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

### Methods

add_cuts_from_cut_ranges clean_all hc_between_strands hc_between_strands_as_original_class new remove_incomplete_cuts strands_for_display vc_complement vc_complement_as_original_class vc_primary vc_primary_as_original_class

### Included Modules

CutSymbol StringFormatting

### Attributes

circular | [RW] | Set to `true` if the fragment CalculatedCuts is working on is circular
size | [R] | Size of the sequence being digested.
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.

### Public Class methods

new(size=nil, circular=false)

[Source]

        # File lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb, line 86
    86:   def initialize(size=nil, circular=false)
    87:     @size = size
    88:     @circular = circular
    89:     @vc_primary = SortedNumArray[]
    90:     @vc_complement = SortedNumArray[]
    91:     @hc_between_strands = SortedNumArray[]
    92:   end

### Public Instance methods

add_cuts_from_cut_ranges(cut_ranges)

Accepts an `Array` of CutRange type objects and applies them to @vc_complement, @vc_primary, and @hc_between_strands.

Arguments

- `cut_ranges`: An `Array` of HorizontalCutRange or VerticalCutRange objects

Returns: | nothing

[Source]

         # File lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb, line 101
    101:   def add_cuts_from_cut_ranges(cut_ranges)
    102:     @strands_for_display_current = false
    103:
    104:     @vc_primary = @vc_primary.dup
    105:     @vc_complement = @vc_complement.dup
    106:
    107:     cut_ranges.each do |cut_range|
    108:       @vc_primary.concat [cut_range.p_cut_left, cut_range.p_cut_right]
    109:       @vc_complement.concat [cut_range.c_cut_left, cut_range.c_cut_right]
    110:
    111:       # Add horizontal cut ranges.  This may happen from cuts made inbetween a
    112:       # VerticalCutRange or may be specifically defined by a HorizontalCutRange.
    113:       if cut_range.class == VerticalCutRange
    114:         ( cut_range.min + 1 ).upto( cut_range.max ){|i| @hc_between_strands << i} if cut_range.min < cut_range.max
    115:       elsif cut_range.class == HorizontalCutRange
    116:         ( cut_range.hcuts.first ).upto( cut_range.hcuts.last ){|i| @hc_between_strands << i}
    117:       end
    118:     end
    119:     clean_all
    120:     #return
    121:   end

hc_between_strands()

`Array` of horizontal cuts between strands in 0-based index notation

[Source]

        # File lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb, line 60
    60:   def hc_between_strands
    61:     #$stderr.puts caller[0].inspect ###DEBUG
    62:     @hc_between_strands.to_a
    63:   end

hc_between_strands_as_original_class()

Returns the same contents as hc_between_strands, but returns original data structure used in the class.

[Source]

        # File lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb, line 67
    67:   def hc_between_strands_as_original_class
    68:     @hc_between_strands
    69:   end

remove_incomplete_cuts(size=nil)

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

- `size`: (optional) Size of the sequence being digested. Defined here or during initalization of CalculatedCuts.

Returns: | nothing

[Source]

         # File lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb, line 151
    151:   def remove_incomplete_cuts(size=nil)
    152:     @strands_for_display_current = false
    153:     @size = size if size
    154:     raise IndexError, "Size of the strand must be provided here or during initalization." if !@size.kind_of?(Fixnum) and not @circular
    155:
    156:     vcuts = @vc_primary + @vc_complement
    157:     hcuts = @hc_between_strands
    158:     last_index = @size - 1
    159:     good_hcuts = SortedNumArray[]
    160:     potential_hcuts = []
    161:
    162:     if @circular
    163:     # NOTE
    164:     # if it's circular we should start at the beginning of a cut for orientation,
    165:     # scan for it, hack off the first set of hcuts and move them to the back
    166:     else
    167:       vcuts.unshift(-1) unless vcuts.include?(-1)
    168:       vcuts.push(last_index) unless vcuts.include?(last_index)
    169:     end
    170:
    171:     hcuts.each do |hcut|
    172:       raise IndexError if hcut < -1 or hcut > last_index
    173:       # skipped a nucleotide
    174:       potential_hcuts.clear if !potential_hcuts.empty? and (hcut - potential_hcuts.last).abs > 1
    175:
    176:       if potential_hcuts.empty?
    177:         if vcuts.include?( hcut ) and vcuts.include?( hcut - 1 )
    178:           good_hcuts << hcut
    179:         elsif vcuts.include?( hcut - 1 )
    180:           potential_hcuts << hcut
    181:         end
    182:       else
    183:         if vcuts.include?( hcut )
    184:           good_hcuts.concat(potential_hcuts)
    185:           good_hcuts << hcut
    186:           potential_hcuts.clear
    187:         else
    188:           potential_hcuts << hcut
    189:         end
    190:       end
    191:     end
    192:
    193:     check_vc = lambda do |vertical_cuts, opposing_vcuts|
    194:       # opposing_vcuts is here only to check for blunt cuts, so there shouldn't
    195:       # be any out-of-order problems with this
    196:       good_vc = SortedNumArray[]
    197:       vertical_cuts.each { |vc| good_vc << vc if good_hcuts.include?( vc ) or good_hcuts.include?( vc + 1 ) or opposing_vcuts.include?( vc ) }
    198:       good_vc
    199:     end
    200:
    201:     @vc_primary = check_vc.call(@vc_primary, @vc_complement)
    202:     @vc_complement = check_vc.call(@vc_complement, @vc_primary)
    203:     @hc_between_strands = good_hcuts
    204:
    205:     clean_all
    206:   end

strands_for_display(str1 = nil, str2 = nil, vcp=nil, vcc=nil, hc=nil)

Sets @strands_for_display_current to `true` and populates @strands_for_display.

Arguments

- +str1+: (optional) For displaying a primary strand. If `nil` a numbered sequence will be used in place.
- +str2+: (optional) For displaying a complementary strand. If `nil` a numbered sequence will be used in place.
- `vcp`: (optional) An array of vertical cut locations on the primary strand. If `nil` the contents of @vc_primary is used.
- `vcc`: (optional) An array of vertical cut locations on the complementary strand. If `nil` the contents of @vc_complementary is used.
- `hc`: (optional) An array of horizontal cut locations between strands. If `nil` the contents of @hc_between_strands is used.

Returns: | `Array` An array with the primary strand with vertical cuts, the horizontal cuts, and the complementary strand with vertical cuts.

[Source]

         # File lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb, line 219
    219:   def strands_for_display(str1 = nil, str2 = nil, vcp=nil, vcc=nil, hc=nil)
    220:     return @strands_for_display if @strands_for_display_current
    221:     vcs = '|'   # Vertical cut symbol
    222:     hcs = '-'   # Horizontal cut symbol
    223:     vhcs = '+'  # Intersection of vertical and horizontal cut symbol
    224:
    225:     num_txt_repeat = lambda { num_txt = '0123456789'; (num_txt * (@size.div(num_txt.size) + 1))[0..@size-1] }
    226:     (str1 == nil) ? a = num_txt_repeat.call : a = str1.dup
    227:     (str2 == nil) ? b = num_txt_repeat.call : b = str2.dup
    228:
    229:     if vcp and !vcp.is_a?(SortedNumArray) then
    230:       vcp = SortedNumArray.new.concat(vcp)
    231:     end
    232:     if vcc and !vcc.is_a?(SortedNumArray) then
    233:       vcc = SortedNumArray.new.concat(vcc)
    234:     end
    235:     if hc and !hc.is_a?(SortedNumArray) then
    236:       hc = SortedNumArray.new.concat(hc)
    237:     end
    238:
    239:     vcp = @vc_primary if vcp==nil
    240:     vcc = @vc_complement if vcc==nil
    241:     hc = @hc_between_strands if hc==nil
    242:
    243:     vcp.reverse_each { |c| a.insert(c+1, vcs) }
    244:     vcc.reverse_each { |c| b.insert(c+1, vcs) }
    245:
    246:     between = ' ' * @size
    247:     hc.each {|hcut| between[hcut,1] = hcs }
    248:
    249:     s_a = add_spacing(a, vcs)
    250:     s_b = add_spacing(b, vcs)
    251:     s_bet = add_spacing(between)
    252:
    253:     # NOTE watch this for circular
    254:     i = 0
    255:     0.upto( s_a.size-1 ) do
    256:       if (s_a[i,1] == vcs) or (s_b[i,1] == vcs)
    257:         s_bet[i] = vhcs
    258:       elsif i != 0 and s_bet[i-1,1] == hcs and s_bet[i+1,1] == hcs
    259:         s_bet[i] = hcs
    260:       end
    261:       i+=1
    262:     end
    263:
    264:     @strands_for_display_current = true
    265:     @strands_for_display = [s_a, s_bet, s_b]
    266:   end

vc_complement()

`Array` of vertical cuts on the complementary strand in 0-based index notation

[Source]

        # File lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb, line 48
    48:   def vc_complement
    49:     #$stderr.puts caller[0].inspect ###DEBUG
    50:     @vc_complement.to_a
    51:   end

vc_complement_as_original_class()

Returns the same contents as vc_complement, but returns original data structure used in the class.

[Source]

        # File lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb, line 55
    55:   def vc_complement_as_original_class
    56:     @vc_complement
    57:   end

vc_primary()

`Array` of vertical cuts on the primary strand in 0-based index notation

[Source]

        # File lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb, line 36
    36:   def vc_primary
    37:     #$stderr.puts caller[0].inspect ###DEBUG
    38:     @vc_primary.to_a
    39:   end

vc_primary_as_original_class()

Returns the same contents as vc_primary, but returns original data structure used in the class.

[Source]

        # File lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb, line 43
    43:   def vc_primary_as_original_class
    44:     @vc_primary
    45:   end

### Protected Instance methods

clean_all()

remove nil values, remove duplicate values, and sort @vc_primary, @vc_complement, and @hc_between_strands

[Source]

         # File lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb, line 274
    274:   def clean_all
    275:     [@vc_primary, @vc_complement, @hc_between_strands].collect { |a| a.delete(nil); a.uniq!; a.sort! }
    276:   end

[Validate]