]> git.donarmstrong.com Git - biopieces.git/blob - code_ruby/lib/maasha/cigar.rb
temporary fix of bzip2 read problem
[biopieces.git] / code_ruby / lib / maasha / cigar.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 # Methods to handle extended CIGAR format used in the
26 # SAM format version v1.4-r962 - April 17, 2011
27
28 # http://samtools.sourceforge.net/SAM1.pdf
29
30 # Error class for all exceptions to do with CIGAR.
31 class CigarError < StandardError; end
32
33 # Class to manipulate CIGAR strings.
34 class Cigar
35   attr_accessor :cigar
36
37   # Method to initialize a CIGAR string.
38   def initialize(cigar)
39     @cigar = cigar
40
41     check_cigar
42   end
43
44   # Method to convert the CIGAR string to
45   # a printable string.
46   def to_s
47     @cigar
48   end
49
50   # Method to iterate over the length and operators
51   # in a CIGAR string.
52   def each
53     cigar.scan(/(\d+)([MIDNSHPX=])/).each do |len, op|
54       yield [len.to_i, op]
55     end
56   end
57
58   # Method to return the number length of
59   # the residues described in the CIGAR string.
60   # This length should match the length of the
61   # aligned sequence.
62   def length
63     total = 0
64
65     self.each do |len, op|
66       total += len unless op == 'I'
67     end
68
69     total
70   end
71
72   # Method to return the number of matched
73   # residues in the CIGAR string.
74   def matches
75     total = 0
76
77     self.each do |len, op|
78       total += len if op == 'M'
79     end
80
81     total
82   end
83
84   # Method to return the number of inserted
85   # residues in the CIGAR string.
86   def insertions
87     total = 0
88
89     self.each do |len, op|
90       total += len if op == 'I'
91     end
92
93     total
94   end
95
96   # Method to return the number of deleted
97   # residues in the CIGAR string.
98   def deletions
99     total = 0
100
101     self.each do |len, op|
102       total += len if op == 'D'
103     end
104
105     total
106   end
107
108   # Method to return the number of hard clipped
109   # residues in the CIGAR string.
110   def clip_hard
111     total = 0
112
113     self.each do |len, op|
114       total += len if op == 'H'
115     end
116
117     total
118   end
119
120   # Method to return the number of soft clipped
121   # residues in the CIGAR string.
122   def clip_soft
123     total = 0
124
125     self.each do |len, op|
126       total += len if op == 'S'
127     end
128
129     total
130   end
131
132   private
133
134   # Method to check that the CIGAR string is formatted
135   # correctly, including hard clipping and soft clipping
136   # that cant be located internally.
137   def check_cigar
138     unless  cigar =~ /^(\*|([0-9]+[MIDNSHPX=])+)$/
139       raise CigarError, "Bad cigar format: #{cigar}"
140     end
141
142     if cigar.gsub(/^[0-9]+H|[0-9]+H$/, "").match('H')
143       raise CigarError, "Bad cigar with internal H: #{cigar}"
144     end
145
146     if cigar.gsub(/^[0-9]+H|[0-9]+H$/, "").gsub(/^[0-9]+S|[0-9]+S$/, "").match('S')
147       raise CigarError, "Bad cigar with internal S: #{cigar}"
148     end
149   end
150 end