Class | Bio::RestrictionEnzyme::Range::SequenceRange
In: | lib/bio/util/restriction_enzyme/range/sequence_range.rb lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb lib/bio/util/restriction_enzyme/range/sequence_range/fragment.rb lib/bio/util/restriction_enzyme/range/sequence_range/fragments.rb
Parent: | Object

A defined range over a nucleotide sequence.

This class accomadates having cuts defined on a sequence and returning the fragments made by those cuts.

### Methods

add_cut_range add_cut_ranges add_horizontal_cut_range create_bins fragments new setup_new_bin

### Classes and Modules

Class Bio::RestrictionEnzyme::Range::SequenceRange::CalculatedCuts
Class Bio::RestrictionEnzyme::Range::SequenceRange::Fragment
Class Bio::RestrictionEnzyme::Range::SequenceRange::Fragments

### Constants

Bin

=

Struct.new(:c, :p)

A Bio::RestrictionEnzyme::Range::SequenceRange::Bin holds an `Array` of indexes for the primary and complement strands (`p` and `c` accessors).

Example hash with Bin values:

      {0=>#<struct Bio::RestrictionEnzyme::Range::SequenceRange::Bin c=[0, 1], p=[0]>,
       2=>#<struct Bio::RestrictionEnzyme::Range::SequenceRange::Bin c=[], p=[1, 2]>,
       3=>#<struct Bio::RestrictionEnzyme::Range::SequenceRange::Bin c=[2, 3], p=[]>,
       4=>#<struct Bio::RestrictionEnzyme::Range::SequenceRange::Bin c=[4, 5], p=[3, 4, 5]>}

Note that the bin cannot be easily stored as a range since there may be nucleotides excised in the middle of a range.

TODO: Perhaps store the bins as one-or-many ranges since missing nucleotides due to enzyme cutting is a special case.

### Attributes

c_left | [R] | Left-most index of complementary strand
c_right | [R] | Right-most index of complementary strand
cut_ranges | [R] | CutRanges in this SequenceRange
left | [R] | Left-most index of DNA sequence
p_left | [R] | Left-most index of primary strand
p_right | [R] | Right-most index of primary strand
right | [R] | Right-most index of DNA sequence
size | [R] | Size of DNA sequence

### Public Class methods

new( p_left = nil, p_right = nil, c_left = nil, c_right = nil )

[Source]

        # File lib/bio/util/restriction_enzyme/range/sequence_range.rb, line 56
    56:   def initialize( p_left = nil, p_right = nil, c_left = nil, c_right = nil )
    57:     raise ArgumentError if p_left == nil and c_left == nil
    58:     raise ArgumentError if p_right == nil and c_right == nil
    59:     (raise ArgumentError unless p_left <= p_right) unless p_left == nil or p_right == nil
    60:     (raise ArgumentError unless c_left <= c_right) unless c_left == nil or c_right == nil
    61:
    62:     @p_left, @p_right, @c_left, @c_right = p_left, p_right, c_left, c_right
    63:     @left = [p_left, c_left].compact.sort.first
    64:     @right = [p_right, c_right].compact.sort.last
    65:     @size = (@right - @left) + 1 unless @left == nil or @right == nil
    66:     @cut_ranges = CutRanges.new
    67:     @__fragments_current = false
    68:   end

### Public Instance methods

add_cut_range( p_cut_left=nil, p_cut_right=nil, c_cut_left=nil, c_cut_right=nil )

If the first object is HorizontalCutRange or VerticalCutRange, that is added to the SequenceRange. Otherwise this method builds a VerticalCutRange object and adds it to the SequenceRange.

Note: Cut occurs immediately after the index supplied. For example, a cut at ‘0’ would mean a cut occurs between bases 0 and 1.

Arguments

- `p_cut_left`: (optional) Left-most cut on the primary strand or a CutRange object. `nil` to skip
- `p_cut_right`: (optional) Right-most cut on the primary strand. `nil` to skip
- `c_cut_left`: (optional) Left-most cut on the complementary strand. `nil` to skip
- `c_cut_right`: (optional) Right-most cut on the complementary strand. `nil` to skip

Returns: | nothing

[Source]

        # File lib/bio/util/restriction_enzyme/range/sequence_range.rb, line 86
    86:   def add_cut_range( p_cut_left=nil, p_cut_right=nil, c_cut_left=nil, c_cut_right=nil )
    87:     @__fragments_current = false
    88:     if p_cut_left.kind_of? CutRange # shortcut
    89:       @cut_ranges << p_cut_left
    90:     else
    91:       [p_cut_left, p_cut_right, c_cut_left, c_cut_right].each { |n| (raise IndexError unless n >= @left and n <= @right) unless n == nil }
    92:       @cut_ranges << VerticalCutRange.new( p_cut_left, p_cut_right, c_cut_left, c_cut_right )
    93:     end
    94:   end

add_cut_ranges(*cut_ranges)

Add a series of CutRange objects (HorizontalCutRange or VerticalCutRange).

Arguments

- `cut_ranges`: A series of CutRange objects

Returns: | nothing

[Source]

         # File lib/bio/util/restriction_enzyme/range/sequence_range.rb, line 102
    102:   def add_cut_ranges(*cut_ranges)
    103:     cut_ranges.flatten.each do |cut_range|
    104:       raise TypeError, "Not of type CutRange" unless cut_range.kind_of? CutRange
    105:       self.add_cut_range( cut_range )
    106:     end
    107:   end

add_horizontal_cut_range( left, right=left )

Builds a HorizontalCutRange object and adds it to the SequenceRange.

Arguments

- `left`: Left-most cut
- `right`: (optional) Right side - by default this equals the left side, default is recommended.

Returns: | nothing

[Source]

         # File lib/bio/util/restriction_enzyme/range/sequence_range.rb, line 116
    116:   def add_horizontal_cut_range( left, right=left )
    117:     @__fragments_current = false
    118:     @cut_ranges << HorizontalCutRange.new( left, right )
    119:   end

fragments()

Calculates the fragments over this sequence range as defined after using the methods add_cut_range, add_cut_ranges, and/or add_horizontal_cut_range

Example return value:

      [#<Bio::RestrictionEnzyme::Range::SequenceRange::Fragment:0x277bdc
        @complement_bin=[0, 1],
        @primary_bin=[0]>,
       #<Bio::RestrictionEnzyme::Range::SequenceRange::Fragment:0x277bc8
        @complement_bin=[],
        @primary_bin=[1, 2]>,
       #<Bio::RestrictionEnzyme::Range::SequenceRange::Fragment:0x277bb4
        @complement_bin=[2, 3],
        @primary_bin=[]>,
       #<Bio::RestrictionEnzyme::Range::SequenceRange::Fragment:0x277ba0
        @complement_bin=[4, 5],
        @primary_bin=[3, 4, 5]>]

Arguments

- none

Returns: | Bio::RestrictionEnzyme::Range::SequenceRange::Fragments

[Source]

         # File lib/bio/util/restriction_enzyme/range/sequence_range.rb, line 158
    158:   def fragments
    159:     return @__fragments if @__fragments_current == true
    160:     @__fragments_current = true
    161:
    162:     num_txt = '0123456789'
    163:     num_txt_repeat = (num_txt * ( @size / num_txt.size.to_f ).ceil)[0..@size-1]
    164:     fragments = Fragments.new(num_txt_repeat, num_txt_repeat)
    165:
    166:     cc = Bio::RestrictionEnzyme::Range::SequenceRange::CalculatedCuts.new(@size)
    167:     cc.add_cuts_from_cut_ranges(@cut_ranges)
    168:     cc.remove_incomplete_cuts
    169:
    170:     create_bins(cc).sort.each { |k, bin| fragments << Fragment.new( bin.p, bin.c ) }
    171:     @__fragments = fragments
    172:     return fragments
    173:   end

### Protected Instance methods

create_bins(cc)

Example:

      cc = Bio::RestrictionEnzyme::Range::SequenceRange::CalculatedCuts.new(@size)
      cc.add_cuts_from_cut_ranges(@cut_ranges)
      cc.remove_incomplete_cuts
      bins = create_bins(cc)

Example return value:

      {0=>#<struct Bio::RestrictionEnzyme::Range::SequenceRange::Bin c=[0, 1], p=[0]>,
       2=>#<struct Bio::RestrictionEnzyme::Range::SequenceRange::Bin c=[], p=[1, 2]>,
       3=>#<struct Bio::RestrictionEnzyme::Range::SequenceRange::Bin c=[2, 3], p=[]>,
       4=>#<struct Bio::RestrictionEnzyme::Range::SequenceRange::Bin c=[4, 5], p=[3, 4, 5]>}

Arguments

- `cc`: Bio::RestrictionEnzyme::Range::SequenceRange::CalculatedCuts

Returns: | `Hash` Keys are unique, values are Bio::RestrictionEnzyme::Range::SequenceRange::Bin objects filled with indexes of the sequence locations they represent.

[Source]

         # File lib/bio/util/restriction_enzyme/range/sequence_range.rb, line 195
    195:   def create_bins(cc)
    196:     p_cut = cc.vc_primary
    197:     c_cut = cc.vc_complement
    198:     h_cut = cc.hc_between_strands
    199:
    200:     if @circular
    201:       # NOTE
    202:       # if it's circular we should start at the beginning of a cut for orientation
    203:       # scan for it, hack off the first set of hcuts and move them to the back
    204:
    205:       unique_id = 0
    206:     else
    207:       p_cut.unshift(-1) unless p_cut.include?(-1)
    208:       c_cut.unshift(-1) unless c_cut.include?(-1)
    209:       unique_id = -1
    210:     end
    211:
    212:     p_bin_id = c_bin_id = unique_id
    213:     bins = {}
    214:     setup_new_bin(bins, unique_id)
    215:
    216:     -1.upto(@size-1) do |idx| # NOTE - circular, for the future - should '-1' be replace with 'unique_id'?
    217:
    218:       # if bin_ids are out of sync but the strands are attached
    219:       if (p_bin_id != c_bin_id) and !h_cut.include?(idx)
    220:         min_id, max_id = [p_bin_id, c_bin_id].sort
    221:         bins.delete(max_id)
    222:         p_bin_id = c_bin_id = min_id
    223:       end
    224:
    225:       bins[ p_bin_id ].p << idx
    226:       bins[ c_bin_id ].c << idx
    227:
    228:       if p_cut.include? idx
    229:         p_bin_id = (unique_id += 1)
    230:         setup_new_bin(bins, p_bin_id)
    231:       end
    232:
    233:       if c_cut.include? idx             # repetition
    234:         c_bin_id = (unique_id += 1)     # repetition
    235:         setup_new_bin(bins, c_bin_id)   # repetition
    236:       end                               # repetition
    237:
    238:     end
    239:
    240:     # Bin "-1" is an easy way to indicate the start of a strand just in case
    241:     # there is a horizontal cut at position 0
    242:     bins.delete(-1) unless @circular
    243:     bins
    244:   end

setup_new_bin(bins, bin_id)

Modifies bins in place by creating a new element with key bin_id and initializing the bin.

[Source]

         # File lib/bio/util/restriction_enzyme/range/sequence_range.rb, line 248
    248:   def setup_new_bin(bins, bin_id)
    249:     bins[ bin_id ] = Bin.new
    250:     bins[ bin_id ].p = []
    251:     bins[ bin_id ].c = []
    252:   end

[Validate]