]> git.donarmstrong.com Git - biopieces.git/blob - code_ruby/lib/maasha/fastq.rb
4ac44aa70cb84045158fc775f782be7719fdbbbd
[biopieces.git] / code_ruby / lib / maasha / fastq.rb
1 # Copyright (C) 2007-2011 Martin A. Hansen.
2
3 # This program is free software; you can redistribute it and/or
4 # modify it under the terms of the GNU General Public License
5 # as published by the Free Software Foundation; either version 2
6 # of the License, or (at your option) any later version.
7
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 # GNU General Public License for more details.
12
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16
17 # http://www.gnu.org/copyleft/gpl.html
18
19 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
20
21 # This software is part of the Biopieces framework (www.biopieces.org).
22
23 # >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>><<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
24
25 require 'maasha/seq'
26 require 'maasha/filesys'
27
28 # Error class for all exceptions to do with FASTQ.
29 class FastqError < StandardError; end
30
31 # Class for parsing FASTQ entries from an ios and return as Seq objects.
32 class Fastq < Filesys
33   # Method to get the next FASTQ entry from an ios and return this
34   # as a Seq object. If no entry is found or eof then nil is returned.
35   def get_entry
36     begin
37       seq_name       = @io.gets.chomp!
38       seq            = @io.gets.chomp!
39       @io.gets
40       qual           = @io.gets.chomp!
41
42       entry          = Seq.new
43       entry.seq      = seq
44       entry.seq_name = seq_name[1 .. seq_name.length]
45       entry.qual     = qual
46       entry.type     = nil
47
48       entry
49     rescue
50       nil
51     end
52   end
53 end
54
55 # Class for indesing FASTQ entries. The index will be
56 # a hash with the FASTQ sequence name as key and a 
57 # FastqElem as value. The latter contains info on
58 # byte offset and length for each entry.
59 class FastqIndex
60   HEADCHAR = 1
61   NEWLINE  = 1
62
63   attr_accessor :ios
64
65   # Method to initialize a FastqIndex object. For reading
66   # entries from file an _ios_ object must be supplied.
67   def initialize(ios = nil)
68     @ios    = ios
69     @index  = {}
70     @offset = 0
71   end
72
73   # Method to add a Fastq entry to a FastqIndex.
74   def add(entry)
75     offset_seq  = @offset + HEADCHAR + entry.seq_name.length + NEWLINE
76     offset_qual = @offset + HEADCHAR + entry.seq_name.length + NEWLINE + entry.length + NEWLINE + HEADCHAR + NEWLINE
77
78     @index[entry.seq_name] = FastqElem.new(offset_seq, offset_qual, entry.length)
79     
80     @offset += HEADCHAR + entry.seq_name.length + NEWLINE + entry.length + NEWLINE + HEADCHAR + NEWLINE + entry.length + NEWLINE
81   end
82
83   # Method to read from file a Fastq entry from an indexed position,
84   # and return the entry as a Seq object.
85   def get(seq_name)
86     raise FastqError, "Sequence name: #{seq_name} not found in index." unless @index[seq_name]
87
88     elem = @index[seq_name]
89     @ios.sysseek(elem.offset_seq)
90     seq = @ios.sysread(elem.length)
91     @ios.sysseek(elem.offset_qual)
92     qual = @ios.sysread(elem.length)
93
94     Seq.new(seq_name, seq, nil, qual)
95   end
96
97   private
98
99   # Class for storing index information to be used
100   # with disk based index.
101   class FastqElem
102     attr_reader :offset_seq, :offset_qual, :length
103
104     def initialize(offset_seq, offset_qual, length)
105       @offset_seq  = offset_seq
106       @offset_qual = offset_qual
107       @length      = length
108     end
109   end
110 end
111
112
113 __END__