]> git.donarmstrong.com Git - biopieces.git/blob - code_ruby/Maasha/lib/fasta.rb
added progress_meter biopiece
[biopieces.git] / code_ruby / Maasha / lib / fasta.rb
1 # This program is free software; you can redistribute it and/or
2 # modify it under the terms of the GNU General Public License
3 # as published by the Free Software Foundation; either version 2
4 # of the License, or (at your option) any later version.
5
6 # This program is distributed in the hope that it will be useful,
7 # but WITHOUT ANY WARRANTY; without even the implied warranty of
8 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9 # GNU General Public License for more details.
10
11 # You should have received a copy of the GNU General Public License
12 # along with this program; if not, write to the Free Software
13 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
14
15 # http://www.gnu.org/copyleft/gpl.html
16
17 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
18
19 # This software is part of the Biopieces framework (www.biopieces.org).
20
21 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
22
23 require 'seq'
24 require 'zlib'
25
26 # Error class for all exceptions to do with FASTA.
27 class FastaError < StandardError; end
28
29 class Fasta
30   include Enumerable
31
32   # Class method allowing open to be used on (zipped) files.
33   # See File.open.
34   def self.open(*args)
35     ios = self.zopen(*args)
36
37     if block_given?
38       begin
39         yield ios
40       ensure
41         ios.close
42       end
43     else
44       return ios
45     end
46   end
47
48   def initialize(io, type=nil)
49     @io   = io
50     @type = type
51   end
52
53   # Method to close ios.
54   def close
55     @io.close
56   end
57
58   # Iterator method for parsing FASTA enries.
59   def each
60     while entry = get_entry do
61       yield entry
62     end
63   end
64
65   # Method to get the next FASTA entry form an ios and return this
66   # as a Seq object. If no entry is found or eof then nil is returned.
67   def get_entry
68     block = @io.gets($/ + '>')
69     return nil if block.nil?
70
71     block.chomp!($/ + '>')
72
73     (seq_name, seq) = block.split($/, 2)
74
75     raise FastaError, "Bad FASTA format" if seq_name.nil? or seq.nil?
76
77     entry          = Seq.new
78     entry.type     = @type.nil? ? nil : @type.downcase
79     entry.seq      = seq.gsub(/\s/, '')
80     entry.seq_name = seq_name.sub(/^>/, '').rstrip
81
82     raise FastaError, "Bad FASTA format" if entry.seq_name.empty?
83     raise FastaError, "Bad FASTA format" if entry.seq.empty?
84
85     entry
86   end
87
88   # TODO - this should be some custom to_s method instead.
89   def puts(record)
90     if record.has_key? :SEQ_NAME and record.has_key? :SEQ
91       @io.print ">#{record[:SEQ_NAME]}\n"
92       @io.print "#{record[:SEQ]}\n"
93     end
94   end
95
96   private
97
98   # Helper method to return an ios to a file that may be zipped in which case
99   # the ios is unzipped on the fly. See File.open.
100   def self.zopen(*args)
101     ios = File.open(*args)
102
103     begin
104       ios = Zlib::GzipReader.new(ios)
105     rescue
106       ios.rewind
107     end
108
109     self.new(ios)
110   end
111 end
112
113
114 __END__