[BioRuby-cvs] bioruby/lib/bio alignment.rb,1.20,1.21

Naohisa Goto ngoto at dev.open-bio.org
Thu Dec 14 19:52:55 UTC 2006


Update of /home/repository/bioruby/bioruby/lib/bio
In directory dev.open-bio.org:/tmp/cvs-serv15819/lib/bio

Modified Files:
	alignment.rb 
Log Message:
New files/classes: Bio::GCG::Msf in lib/bio/appl/gcg/msf.rb for GCG msf 
multiple sequence alignment format parser, and Bio::GCG::Seq in 
lib/bio/appl/gcg/seq.rb for GCG sequence format parser.

Autoload of the classes (in bio.rb) and file format autodetection
(in flatfile.rb) are also supported.

Bio::Alignment::Output#output_msf, #output(:msf, ...) are added
to generate msf formatted string from multiple alignment object.


Index: alignment.rb
===================================================================
RCS file: /home/repository/bioruby/bioruby/lib/bio/alignment.rb,v
retrieving revision 1.20
retrieving revision 1.21
diff -C2 -d -r1.20 -r1.21
*** alignment.rb	14 Dec 2006 15:08:59 -0000	1.20
--- alignment.rb	14 Dec 2006 19:52:53 -0000	1.21
***************
*** 24,27 ****
--- 24,32 ----
  require 'bio/sequence'
  
+ #---
+ # (depends on autoload)
+ #require 'bio/appl/gcg/seq'
+ #+++
+ 
  module Bio
  
***************
*** 871,874 ****
--- 876,881 ----
          when :phylipnon
            output_phylipnon(*arg)
+         when :msf
+           output_msf(*arg)
          when :molphy
            output_molphy(*arg)
***************
*** 1177,1180 ****
--- 1184,1305 ----
          aseqs.join('')
        end
+ 
+       # Generates msf formatted text as a string
+       def output_msf(options = {})
+         len = self.seq_length
+ 
+         if !options.has_key?(:avoid_same_name) or options[:avoid_same_name]
+           sn = __clustal_avoid_same_name(self.sequence_names)
+         else
+           sn = self.sequence_names.collect do |x|
+             x.to_s.gsub(/[\r\n\x00]/, ' ')
+           end
+         end
+         if !options.has_key?(:replace_space) or options[:replace_space]
+           sn.collect! { |x| x.gsub(/\s/, '_') }
+         end
+         if !options.has_key?(:escape) or options[:escape]
+           sn.collect! { |x| x.gsub(/[\:\;\,\(\)]/, '_') }
+         end
+         if !options.has_key?(:split) or options[:split]
+           sn.collect! { |x| x.split(/\s/)[0].to_s }
+         end
+ 
+         seqwidth = 50
+         namewidth = [31, sn.collect { |x| x.length }.max ].min
+         sep = ' ' * 2
+ 
+         seqregexp = Regexp.new("(.{1,#{seqwidth}})")
+         gchar = (options[:gap_char]  or '.')
+         pchar = (options[:padding_char] or '~')
+ 
+         aseqs = Array.new(self.number_of_sequences).clear
+         self.each_seq do |s|
+           aseqs << s.to_s.gsub(self.gap_regexp, gchar)
+         end
+         aseqs.each do |s|
+           s.sub!(/\A#{Regexp.escape(gchar)}+/) { |x| pchar * x.length }
+           s.sub!(/#{Regexp.escape(gchar)}+\z/, '')
+           s << (pchar * (len - s.length))
+         end
+ 
+         case options[:case].to_s
+         when /lower/i
+           aseqs.each { |s| s.downcase! }
+         when /upper/i
+           aseqs.each { |s| s.upcase! }
+         else #default upcase
+           aseqs.each { |s| s.upcase! }
+         end
+ 
+         case options[:type].to_s
+         when /protein/i, /aa/i
+           amino = true
+         when /na/i
+           amino = false
+         else
+           if seqclass == Bio::Sequence::AA then
+             amino = true
+           elsif seqclass == Bio::Sequence::NA then
+             amino = false
+           else
+             # if we can't determine, we asuume as protein.
+             amino = aseqs.size
+             aseqs.each { |x| amino -= 1 if /\A[acgt]\z/i =~ x }
+             amino = false if amino <= 0
+           end
+         end
+ 
+         seq_type = (amino ? 'P' : 'N')
+ 
+         fn = (options[:entry_id] or self.__id__.abs.to_s + '.msf')
+         dt = (options[:time] or Time.now).strftime('%B %d, %Y %H:%M')
+ 
+         sums = aseqs.collect { |s| GCG::Seq.calc_checksum(s) }
+         #sums = aseqs.collect { |s| 0 }
+         sum = 0; sums.each { |x| sum += x }; sum %= 10000
+         msf =
+           [
+            "#{seq_type == 'N' ? 'N' : 'A' }A_MULTIPLE_ALIGNMENT 1.0\n",
+            "\n",
+            "\n",
+            " #{fn}  MSF: #{len}  Type: #{seq_type}  #{dt}  Check: #{sum} ..\n",
+            "\n"
+           ]
+ 
+         sn.each do |snx|
+           msf << ' Name: ' +
+             sprintf('%*s', -namewidth, snx.to_s)[0, namewidth] +
+             "  Len: #{len}  Check: #{sums.shift}  Weight: 1.00\n"
+         end
+         msf << "\n//\n"
+ 
+         aseqs.collect! do |s|
+           snx = sn.shift
+           head = sprintf("%*s", namewidth, snx.to_s)[0, namewidth] + sep
+           s.gsub!(seqregexp, "\\1\n")
+           a = s.split(/^/)
+           a.collect { |x| head + x }
+         end
+         lines = (len + seqwidth - 1).div(seqwidth)
+         i = 1
+         lines.times do
+           msf << "\n"
+           n_l = i
+           n_r = [ i + seqwidth - 1, len ].min
+           if n_l != n_r then
+             w = [ n_r - n_l + 1 - n_l.to_s.length - n_r.to_s.length, 1 ].max
+             msf << (' ' * namewidth + sep + n_l.to_s + 
+                     ' ' * w + n_r.to_s + "\n")
+           else
+             msf << (' ' * namewidth + sep + n_l.to_s + "\n")
+           end
+           aseqs.each { |a| msf << a.shift }
+           i += seqwidth
+         end
+         msf << "\n"
+         msf.join('')
+       end
+ 
      end #module Output
  




More information about the bioruby-cvs mailing list