# >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
require 'pp'
-require 'open3'
+require 'tempfile'
require 'narray'
require 'maasha/fasta'
ROW_C = 2
ROW_G = 3
-# Adding an initialize method to the existing Fasta class.
-class Fasta
- def initialize(io)
- @io = io
- end
-end
-
# Class for aligning sequences.
class Align
# Class method to align sequences in a list of Seq objects and
# return these as a new list of Seq objects.
- def self.muscle(entries)
- result = []
- index = {}
+ def self.muscle(entries, verbose = false)
+ file_in = Tempfile.new("input")
+ file_out = Tempfile.new("output")
+ result = []
+ index = {}
- Open3.popen3("muscle") do |stdin, stdout, stderr|
+ Fasta.open(file_in, "w") do |ios|
entries.each do |entry|
raise AlignError, "Duplicate sequence name: #{entry.seq_name}" if index.has_key? entry.seq_name
index[entry.seq_name] = entry
- stdin.puts entry.to_fasta
+ ios.puts entry.to_fasta
end
+ end
- stdin.close
+ if verbose
+ cmd = "muscle < #{file_in.path} > #{file_out.path}"
+ else
+ cmd = "muscle -quiet < #{file_in.path} > #{file_out.path}"
+ end
- aligned_entries = Fasta.new(stdout)
+ system(cmd)
+ raise AlignError, "command failed: #{cmd}" unless $?.success?
- aligned_entries.each do |fa_entry|
+ Fasta.open(file_out, "r") do |ios|
+ ios.each do |fa_entry|
fq_entry = index[fa_entry.seq_name]
fa_entry.seq.scan(/-+/) do |m|