| Class | Bio::RestrictionEnzyme::Range::SequenceRange::CalculatedCuts |
| In: |
lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb
|
| Parent: | Object |
cc = CalculatedCuts.new(@size) cc.add_cuts_from_cut_ranges(@cut_ranges) cc.remove_incomplete_cuts
1 2 3 4 5 6 7
G A|T T A C A
+-----+
C T A A T|G T
1 2 3 4 5 6 7
Primary cut = 2 Complement cut = 5 Horizontal cuts = 3, 4, 5
| circular | [RW] | Set to true if the fragment CalculatedCuts is working on is circular |
| hc_between_strands | [R] | Array of horizontal cuts between strands in 0-based index notation |
| size | [R] | Size of the sequence being digested. |
| strands_for_display | [R] | An Array with the primary strand with vertical cuts, the horizontal cuts, and the complementary strand with vertical cuts. |
| strands_for_display_current | [R] | If false the strands_for_display method needs to be called to update the contents of @strands_for_display. Becomes out of date whenever add_cuts_from_cut_ranges is called. |
| vc_complement | [R] | Array of vertical cuts on the complementary strand in 0-based index notation |
| vc_primary | [R] | Array of vertical cuts on the primary strand in 0-based index notation |
# File lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb, line 58
58: def initialize(size=nil, circular=false)
59: @size = size
60: @circular = circular
61: @vc_primary = []
62: @vc_complement = []
63: @hc_between_strands = []
64: end
Accepts an Array of CutRange type objects and applies them to @vc_complement, @vc_primary, and @hc_between_strands.
Arguments
| Returns: | nothing |
# File lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb, line 73
73: def add_cuts_from_cut_ranges(cut_ranges)
74: @strands_for_display_current = false
75:
76: cut_ranges.each do |cut_range|
77: @vc_primary += [cut_range.p_cut_left, cut_range.p_cut_right]
78: @vc_complement += [cut_range.c_cut_left, cut_range.c_cut_right]
79:
80: # Add horizontal cut ranges. This may happen from cuts made inbetween a
81: # VerticalCutRange or may be specifically defined by a HorizontalCutRange.
82: if cut_range.class == VerticalCutRange
83: ( cut_range.min + 1 ).upto( cut_range.max ){|i| @hc_between_strands << i} if cut_range.min < cut_range.max
84: elsif cut_range.class == HorizontalCutRange
85: ( cut_range.hcuts.first ).upto( cut_range.hcuts.last ){|i| @hc_between_strands << i}
86: end
87: end
88: clean_all
89: #return
90: end
There may be incomplete cuts made, this method removes the cuts that don‘t create sub-sequences for easier processing.
For example, stray horizontal cuts that do not end with a left and right separation:
G A T T A C A
+-- ---
C T|A A T G T
Or stray vertical cuts:
G A T T A C A
+-- +
C T|A A T|G T
However note that for non-circular sequences this would be a successful cut which would result in a floating ‘GT’ sub-sequence:
G A T T A C A
+---
C T A A T|G T
Blunt cuts are also complete cuts.
Arguments
| Returns: | nothing |
# File lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb, line 120
120: def remove_incomplete_cuts(size=nil)
121: @strands_for_display_current = false
122: @size = size if size
123: raise IndexError, "Size of the strand must be provided here or during initalization." if !@size.kind_of?(Fixnum) and not @circular
124:
125: vcuts = (@vc_primary + @vc_complement).uniq.sort
126: hcuts = @hc_between_strands
127: last_index = @size - 1
128: good_hcuts = []
129: potential_hcuts = []
130:
131: if @circular
132: # NOTE
133: # if it's circular we should start at the beginning of a cut for orientation,
134: # scan for it, hack off the first set of hcuts and move them to the back
135: else
136: vcuts.unshift(-1) unless vcuts.include?(-1)
137: vcuts.push(last_index) unless vcuts.include?(last_index)
138: end
139:
140: hcuts.each do |hcut|
141: raise IndexError if hcut < -1 or hcut > last_index
142: # skipped a nucleotide
143: potential_hcuts.clear if !potential_hcuts.empty? and (hcut - potential_hcuts.last).abs > 1
144:
145: if potential_hcuts.empty?
146: if vcuts.include?( hcut ) and vcuts.include?( hcut - 1 )
147: good_hcuts += [hcut]
148: elsif vcuts.include?( hcut - 1 )
149: potential_hcuts << hcut
150: end
151: else
152: if vcuts.include?( hcut )
153: good_hcuts += potential_hcuts + [hcut]
154: potential_hcuts.clear
155: else
156: potential_hcuts << hcut
157: end
158: end
159: end
160:
161: check_vc = lambda do |vertical_cuts, opposing_vcuts|
162: # opposing_vcuts is here only to check for blunt cuts, so there shouldn't
163: # be any out-of-order problems with this
164: good_vc = []
165: vertical_cuts.each { |vc| good_vc << vc if good_hcuts.include?( vc ) or good_hcuts.include?( vc + 1 ) or opposing_vcuts.include?( vc ) }
166: good_vc
167: end
168:
169: @vc_primary = check_vc.call(@vc_primary, @vc_complement)
170: @vc_complement = check_vc.call(@vc_complement, @vc_primary)
171: @hc_between_strands = good_hcuts
172:
173: clean_all
174: end
Sets @strands_for_display_current to true and populates @strands_for_display.
Arguments
| Returns: | Array An array with the primary strand with vertical cuts, the horizontal cuts, and the complementary strand with vertical cuts. |
# File lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb, line 187
187: def strands_for_display(str1 = nil, str2 = nil, vcp=nil, vcc=nil, hc=nil)
188: return @strands_for_display if @strands_for_display_current
189: vcs = '|' # Vertical cut symbol
190: hcs = '-' # Horizontal cut symbol
191: vhcs = '+' # Intersection of vertical and horizontal cut symbol
192:
193: num_txt_repeat = lambda { num_txt = '0123456789'; (num_txt * ( @size / num_txt.size.to_f ).ceil)[0..@size-1] }
194: (str1 == nil) ? a = num_txt_repeat.call : a = str1.dup
195: (str2 == nil) ? b = num_txt_repeat.call : b = str2.dup
196:
197: vcp = @vc_primary if vcp==nil
198: vcc = @vc_complement if vcc==nil
199: hc = @hc_between_strands if hc==nil
200:
201: vcuts = (vcp + vcc).uniq.sort
202:
203: vcp.reverse.each { |c| a.insert(c+1, vcs) }
204: vcc.reverse.each { |c| b.insert(c+1, vcs) }
205:
206: between = ' ' * @size
207: hc.each {|hcut| between[hcut,1] = hcs }
208:
209: s_a = add_spacing(a, vcs)
210: s_b = add_spacing(b, vcs)
211: s_bet = add_spacing(between)
212:
213: # NOTE watch this for circular
214: i = 0
215: 0.upto( s_a.size-1 ) do
216: if (s_a[i,1] == vcs) or (s_b[i,1] == vcs)
217: s_bet[i] = vhcs
218: elsif i != 0 and s_bet[i-1,1] == hcs and s_bet[i+1,1] == hcs
219: s_bet[i] = hcs
220: end
221: i+=1
222: end
223:
224: @strands_for_display_current = true
225: @strands_for_display = [s_a, s_bet, s_b]
226: end
remove nil values, remove duplicate values, and sort @vc_primary, @vc_complement, and @hc_between_strands
# File lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb, line 234
234: def clean_all
235: [@vc_primary, @vc_complement, @hc_between_strands].collect { |a| a.delete(nil); a.uniq!; a.sort! }
236: end