]> git.donarmstrong.com Git - biopieces.git/blob - code_ruby/lib/maasha/fastq.rb
polish of fastq
[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     seq_name       = @io.gets.chomp!
37     seq            = @io.gets.chomp!
38     @io.gets
39     qual           = @io.gets.chomp!
40
41     entry          = Seq.new
42     entry.seq      = seq
43     entry.seq_name = seq_name[1 .. seq_name.length]
44     entry.qual     = qual
45     entry.type     = nil
46
47     entry
48   rescue
49     nil
50   end
51 end
52
53 # Class for indesing FASTQ entries. The index will be
54 # a hash with the FASTQ sequence name as key and a 
55 # FastqElem as value. The latter contains info on
56 # byte offset and length for each entry.
57 class FastqIndex
58   HEADCHAR = 1
59   NEWLINE  = 1
60
61   attr_accessor :ios
62
63   # Method to initialize a FastqIndex object. For reading
64   # entries from file an _ios_ object must be supplied.
65   def initialize(ios = nil)
66     @ios    = ios
67     @index  = {}
68     @offset = 0
69   end
70
71   # Method to add a Fastq entry to a FastqIndex.
72   def add(entry)
73     offset_seq  = @offset + HEADCHAR + entry.seq_name.length + NEWLINE
74     offset_qual = @offset + HEADCHAR + entry.seq_name.length + NEWLINE + entry.length + NEWLINE + HEADCHAR + NEWLINE
75
76     @index[entry.seq_name] = FastqElem.new(offset_seq, offset_qual, entry.length)
77     
78     @offset += HEADCHAR + entry.seq_name.length + NEWLINE + entry.length + NEWLINE + HEADCHAR + NEWLINE + entry.length + NEWLINE
79   end
80
81   # Method to read from file a Fastq entry from an indexed position,
82   # and return the entry as a Seq object.
83   def get(seq_name)
84     raise FastqError, "Sequence name: #{seq_name} not found in index." unless @index[seq_name]
85
86     elem = @index[seq_name]
87     @ios.sysseek(elem.offset_seq)
88     seq = @ios.sysread(elem.length)
89     @ios.sysseek(elem.offset_qual)
90     qual = @ios.sysread(elem.length)
91
92     Seq.new(seq_name, seq, nil, qual)
93   end
94
95   private
96
97   # Class for storing index information to be used
98   # with disk based index.
99   class FastqElem
100     attr_reader :offset_seq, :offset_qual, :length
101
102     def initialize(offset_seq, offset_qual, length)
103       @offset_seq  = offset_seq
104       @offset_qual = offset_qual
105       @length      = length
106     end
107   end
108 end
109
110
111 __END__