From trevor at dev.open-bio.org Mon Jan 1 00:07:06 2007 From: trevor at dev.open-bio.org (Trevor Wennblom) Date: Mon, 01 Jan 2007 05:07:06 +0000 Subject: [BioRuby-cvs] bioruby/lib/bio/util/restriction_enzyme cut_symbol.rb, 1.3, 1.4 double_stranded.rb, 1.2, 1.3 Message-ID: <200701010507.l01576ei000879@dev.open-bio.org> Update of /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme In directory dev.open-bio.org:/tmp/cvs-serv855/lib/bio/util/restriction_enzyme Modified Files: cut_symbol.rb double_stranded.rb Log Message: Index: cut_symbol.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/cut_symbol.rb,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** cut_symbol.rb 1 Jan 2007 02:16:05 -0000 1.3 --- cut_symbol.rb 1 Jan 2007 05:07:04 -0000 1.4 *************** *** 91,95 **** ######### ! protected ######### --- 91,95 ---- ######### ! #protected # NOTE this is a Module, can't hide CutSymbol__ ######### Index: double_stranded.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/double_stranded.rb,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** double_stranded.rb 31 Dec 2006 21:50:31 -0000 1.2 --- double_stranded.rb 1 Jan 2007 05:07:04 -0000 1.3 *************** *** 31,41 **** # License:: Distributes under the same terms as Ruby # ! # A pair of +SingleStrand+ and +SingleStrandComplement+ objects with methods to # add utility to their relation. # # = Notes ! # * This is created by Bio::RestrictionEnzyme.new for convenience. ! # * The two strands accessible are +primary+ and +complement+. ! # * SingleStrand methods may be used on DoubleStranded and they will be passed to +primary+. # class DoubleStranded --- 31,41 ---- # License:: Distributes under the same terms as Ruby # ! # A pair of SingleStrand and SingleStrandComplement objects with methods to # add utility to their relation. # # = Notes ! # * This is created by Bio::RestrictionEnzyme.new for convenience. ! # * The two strands accessible are +primary+ and +complement+. ! # * SingleStrand methods may be used on DoubleStranded and they will be passed to +primary+. # class DoubleStranded From trevor at dev.open-bio.org Mon Jan 1 00:07:06 2007 From: trevor at dev.open-bio.org (Trevor Wennblom) Date: Mon, 01 Jan 2007 05:07:06 +0000 Subject: [BioRuby-cvs] bioruby/lib/bio/util/restriction_enzyme/analysis calculated_cuts.rb, 1.2, 1.3 Message-ID: <200701010507.l01576Wx000883@dev.open-bio.org> Update of /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/analysis In directory dev.open-bio.org:/tmp/cvs-serv855/lib/bio/util/restriction_enzyme/analysis Modified Files: calculated_cuts.rb Log Message: Index: calculated_cuts.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/analysis/calculated_cuts.rb,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** calculated_cuts.rb 31 Dec 2006 21:50:31 -0000 1.2 --- calculated_cuts.rb 1 Jan 2007 05:07:04 -0000 1.3 *************** *** 135,141 **** def strands_for_display(str1 = nil, str2 = nil, vcp=nil, vcc=nil, hc=nil) return @strands_for_display if @strands_for_display_current ! vcs = '|' ! hcs = '-' ! vhcs = '+' num_txt_repeat = lambda { num_txt = '0123456789'; (num_txt * ( @size / num_txt.size.to_f ).ceil)[0.. at size-1] } --- 135,141 ---- def strands_for_display(str1 = nil, str2 = nil, vcp=nil, vcc=nil, hc=nil) return @strands_for_display if @strands_for_display_current ! vcs = '|' # Vertical cut symbol ! hcs = '-' # Horizontal cut symbol ! vhcs = '+' # Intersection of vertical and horizontal cut symbol num_txt_repeat = lambda { num_txt = '0123456789'; (num_txt * ( @size / num_txt.size.to_f ).ceil)[0.. at size-1] } *************** *** 174,193 **** end - =begin - def vc_primary_add(c) - @vc_primary << c - @current = false - end - - def vc_complement_add(c) - @vc_complement << c - @current = false - end - - def hc_between_strands_add(c) - @hc_between_strands << c - @current = false - end - =end ######### protected --- 174,177 ---- From trevor at dev.open-bio.org Mon Jan 1 00:07:06 2007 From: trevor at dev.open-bio.org (Trevor Wennblom) Date: Mon, 01 Jan 2007 05:07:06 +0000 Subject: [BioRuby-cvs] bioruby/lib/bio/util/restriction_enzyme/double_stranded aligned_strands.rb, 1.2, 1.3 cut_location_pair.rb, 1.2, 1.3 cut_location_pair_in_enzyme_notation.rb, 1.2, 1.3 cut_locations.rb, 1.2, 1.3 cut_locations_in_enzyme_notation.rb, 1.2, 1.3 Message-ID: <200701010507.l01576Zk000886@dev.open-bio.org> Update of /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/double_stranded In directory dev.open-bio.org:/tmp/cvs-serv855/lib/bio/util/restriction_enzyme/double_stranded Modified Files: aligned_strands.rb cut_location_pair.rb cut_location_pair_in_enzyme_notation.rb cut_locations.rb cut_locations_in_enzyme_notation.rb Log Message: Index: aligned_strands.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/double_stranded/aligned_strands.rb,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** aligned_strands.rb 31 Dec 2006 21:50:31 -0000 1.2 --- aligned_strands.rb 1 Jan 2007 05:07:04 -0000 1.3 *************** *** 1,4 **** # ! # bio/util/restrction_enzyme/double_stranded/aligned_strands.rb - # # Author:: Trevor Wennblom --- 1,4 ---- # ! # bio/util/restrction_enzyme/double_stranded/aligned_strands.rb - Align two SingleStrand objects # # Author:: Trevor Wennblom *************** *** 21,25 **** # ! # bio/util/restrction_enzyme/double_stranded/aligned_strands.rb - # # Author:: Trevor Wennblom --- 21,25 ---- # ! # bio/util/restrction_enzyme/double_stranded/aligned_strands.rb - Align two SingleStrand objects # # Author:: Trevor Wennblom *************** *** 27,31 **** # License:: Distributes under the same terms as Ruby # ! # Align two SingleStrand::Pattern objects and return a Result # object with +primary+ and +complement+ accessors. # --- 27,31 ---- # License:: Distributes under the same terms as Ruby # ! # Align two SingleStrand objects and return a Result # object with +primary+ and +complement+ accessors. # *************** *** 37,53 **** Result = Struct.new(:primary, :complement) ! # Pad and align two String objects. # ! # +a+:: First String ! # +b+:: Second String # ! # Example invocation: ! # AlignedStrands.align('nngattacannnnn', 'nnnnnctaatgtnn') # ! # Example return value: ! # # # def self.align(a, b) a = a.to_s --- 37,60 ---- Result = Struct.new(:primary, :complement) ! # Pad and align two String objects without cut symbols. # ! # This will look for the sub-sequence without left and right 'n' padding ! # and re-apply 'n' padding to both strings on both sides equal to the ! # maximum previous padding on that side. # ! # The sub-sequences stripped of left and right 'n' padding must be of equal ! # length. # ! # Example: ! # AlignedStrands.align('nngattacannnnn', 'nnnnnctaatgtnn') # => ! # # + # --- + # *Arguments* + # * +a+: Primary strand + # * +b+: Complementary strand + # *Returns*:: +Result+ object with equal padding on both strings def self.align(a, b) a = a.to_s *************** *** 64,79 **** # Pad and align two String objects with cut symbols. # ! # +a+:: First String ! # +b+:: Second String ! # +a_cuts+:: First strand cut locations in 0-based index notation ! # +b_cuts+:: Second strand cut locations in 0-based index notation ! # ! # Example invocation: ! # AlignedStrands.with_cuts('nngattacannnnn', 'nnnnnctaatgtnn', [0, 10, 12], [0, 2, 12]) ! # ! # Example return value: ! # # # # Notes: --- 71,79 ---- # Pad and align two String objects with cut symbols. # ! # Example: ! # AlignedStrands.with_cuts('nngattacannnnn', 'nnnnnctaatgtnn', [0, 10, 12], [0, 2, 12]) # => ! # # # Notes: *************** *** 81,86 **** # * This is meant to be able to handle multiple cuts and completely # unrelated cutsites on the two strands, therefore no biological ! # shortcuts are made. # def self.align_with_cuts(a,b,a_cuts,b_cuts) a = a.to_s --- 81,96 ---- # * This is meant to be able to handle multiple cuts and completely # unrelated cutsites on the two strands, therefore no biological ! # algorithm assumptions (shortcuts) are made. ! # ! # The sequences stripped of left and right 'n' padding must be of equal ! # length. # + # --- + # *Arguments* + # * +a+: Primary sequence + # * +b+: Complementary sequence + # * +a_cuts+: Primary strand cut locations in 0-based index notation + # * +b_cuts+: Complementary strand cut locations in 0-based index notation + # *Returns*:: +Result+ object with equal padding on both strings and spacing between bases def self.align_with_cuts(a,b,a_cuts,b_cuts) a = a.to_s Index: cut_locations.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/double_stranded/cut_locations.rb,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** cut_locations.rb 31 Dec 2006 21:50:31 -0000 1.2 --- cut_locations.rb 1 Jan 2007 05:07:04 -0000 1.3 *************** *** 1,4 **** # ! # bio/util/restrction_enzyme/double_stranded/cut_locations.rb - # # Author:: Trevor Wennblom --- 1,4 ---- # ! # bio/util/restrction_enzyme/double_stranded/cut_locations.rb - Contains an Array of CutLocationPair objects # # Author:: Trevor Wennblom *************** *** 19,23 **** # ! # bio/util/restrction_enzyme/double_stranded/cut_locations.rb - # # Author:: Trevor Wennblom --- 19,23 ---- # ! # bio/util/restrction_enzyme/double_stranded/cut_locations.rb - Contains an Array of CutLocationPair objects # # Author:: Trevor Wennblom *************** *** 25,30 **** --- 25,45 ---- # License:: Distributes under the same terms as Ruby # + # Contains an +Array+ of CutLocationPair objects. + # class CutLocations < Array + # CutLocations constructor. + # + # Contains an +Array+ of CutLocationPair objects. + # + # Example: + # clp1 = CutLocationPair.new(3,2) + # clp2 = CutLocationPair.new(7,9) + # pairs = CutLocations.new(clp1, clp2) + # + # --- + # *Arguments* + # * +args+: Any number of +CutLocationPair+ objects + # *Returns*:: nothing def initialize(*args) validate_args(args) *************** *** 32,39 **** --- 47,66 ---- end + # Returns an +Array+ of locations of cuts on the primary strand + # + # --- + # *Arguments* + # * _none_ + # *Returns*:: +Array+ of locations of cuts on the primary strand def primary self.collect {|a| a[0]} end + # Returns an +Array+ of locations of cuts on the complementary strand + # + # --- + # *Arguments* + # * _none_ + # *Returns*:: +Array+ of locations of cuts on the complementary strand def complement self.collect {|a| a[1]} Index: cut_locations_in_enzyme_notation.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/double_stranded/cut_locations_in_enzyme_notation.rb,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** cut_locations_in_enzyme_notation.rb 31 Dec 2006 21:50:31 -0000 1.2 --- cut_locations_in_enzyme_notation.rb 1 Jan 2007 05:07:04 -0000 1.3 *************** *** 1,4 **** # ! # bio/util/restrction_enzyme/double_stranded/cut_locations_in_enzyme_notation.rb - # # Author:: Trevor Wennblom --- 1,4 ---- # ! # bio/util/restrction_enzyme/double_stranded/cut_locations_in_enzyme_notation.rb - Inherits from DoubleStrand::CutLocations # # Author:: Trevor Wennblom *************** *** 20,24 **** # ! # bio/util/restrction_enzyme/double_stranded/cut_locations_in_enzyme_notation.rb - # # Author:: Trevor Wennblom --- 20,24 ---- # ! # bio/util/restrction_enzyme/double_stranded/cut_locations_in_enzyme_notation.rb - Inherits from DoubleStrand::CutLocations # # Author:: Trevor Wennblom *************** *** 26,39 **** --- 26,64 ---- # License:: Distributes under the same terms as Ruby # + # Inherits from DoubleStranded::CutLocations. Contains CutLocationPairInEnzymeNotation objects. + # Adds helper methods to convert from enzyme index notation to 0-based array index notation. + # class CutLocationsInEnzymeNotation < CutLocations + # Returns +Array+ of locations of cuts on the primary + # strand in 0-based array index notation. + # + # --- + # *Arguments* + # * _none_ + # *Returns*:: +Array+ of locations of cuts on the primary strand in 0-based array index notation. def primary_to_array_index helper_for_to_array_index(self.primary) end + # Returns +Array+ of locations of cuts on the complementary + # strand in 0-based array index notation. + # + # --- + # *Arguments* + # * _none_ + # *Returns*:: +Array+ of locations of cuts on the complementary strand in 0-based array index notation. def complement_to_array_index helper_for_to_array_index(self.complement) end + # Returns the contents of the present CutLocationsInEnzymeNotation object as + # a CutLocations object with the contents converted from enzyme notation + # to 0-based array index notation. + # + # --- + # *Arguments* + # * _none_ + # *Returns*:: +CutLocations+ def to_array_index unless self.primary_to_array_index.size == self.complement_to_array_index.size Index: cut_location_pair_in_enzyme_notation.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/double_stranded/cut_location_pair_in_enzyme_notation.rb,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** cut_location_pair_in_enzyme_notation.rb 31 Dec 2006 21:50:31 -0000 1.2 --- cut_location_pair_in_enzyme_notation.rb 1 Jan 2007 05:07:04 -0000 1.3 *************** *** 1,4 **** # ! # bio/util/restrction_enzyme/double_stranded/cut_location_pair_in_enzyme_notation.rb - # # Author:: Trevor Wennblom --- 1,4 ---- # ! # bio/util/restrction_enzyme/double_stranded/cut_location_pair_in_enzyme_notation.rb - Inherits from DoubleStranded::CutLocationPair # # Author:: Trevor Wennblom *************** *** 20,24 **** # ! # bio/util/restrction_enzyme/double_stranded/cut_location_pair_in_enzyme_notation.rb - # # Author:: Trevor Wennblom --- 20,24 ---- # ! # bio/util/restrction_enzyme/double_stranded/cut_location_pair_in_enzyme_notation.rb - Inherits from DoubleStranded::CutLocationPair # # Author:: Trevor Wennblom *************** *** 26,30 **** # License:: Distributes under the same terms as Ruby # ! # See CutLocationPair # class CutLocationPairInEnzymeNotation < CutLocationPair --- 26,31 ---- # License:: Distributes under the same terms as Ruby # ! # Inherits from DoubleStranded::CutLocationPair , stores the cut location pair in ! # enzyme notation instead of 0-based. # class CutLocationPairInEnzymeNotation < CutLocationPair *************** *** 35,43 **** def validate_2( a, b ) ! if a == 0 ! raise ArgumentError, "Enzyme index notation only. 0 values are illegal." ! end ! ! if b == 0 raise ArgumentError, "Enzyme index notation only. 0 values are illegal." end --- 36,40 ---- def validate_2( a, b ) ! if (a == 0) or (b == 0) raise ArgumentError, "Enzyme index notation only. 0 values are illegal." end Index: cut_location_pair.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/double_stranded/cut_location_pair.rb,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** cut_location_pair.rb 31 Dec 2006 21:50:31 -0000 1.2 --- cut_location_pair.rb 1 Jan 2007 05:07:04 -0000 1.3 *************** *** 1,4 **** # ! # bio/util/restrction_enzyme/double_stranded/cut_location_pair.rb - # # Author:: Trevor Wennblom --- 1,4 ---- # ! # bio/util/restrction_enzyme/double_stranded/cut_location_pair.rb - Stores a cut location pair in 0-based index notation # # Author:: Trevor Wennblom *************** *** 20,24 **** # ! # bio/util/restrction_enzyme/double_stranded/cut_location_pair.rb - # # Author:: Trevor Wennblom --- 20,24 ---- # ! # bio/util/restrction_enzyme/double_stranded/cut_location_pair.rb - Stores a cut location pair in 0-based index notation # # Author:: Trevor Wennblom *************** *** 26,48 **** # License:: Distributes under the same terms as Ruby # ! # Stores a cut location pair in 0-based index notation ! # ! # Input: ! # +pair+:: May be two values represented as an Array, a Range, or a ! # combination of Integer and nil values. The first value ! # represents a cut on the primary strand, the second represents ! # a cut on the complement strand. ! # ! # Example: ! # clp = CutLocationPair.new(3,2) ! # clp.primary # 3 ! # clp.complement # 2 ! # ! # Notes: ! # * a value of +nil+ is an explicit representation of 'no cut' # class CutLocationPair < Array ! attr_reader :primary, :complement def initialize( *pair ) a = b = nil --- 26,60 ---- # License:: Distributes under the same terms as Ruby # ! # Stores a single cut location pair in 0-based index notation for use with ! # DoubleStranded enzyme sequences. # class CutLocationPair < Array ! # Location of the cut on the primary strand. ! # Corresponds - or 'pairs' - to the complement cut. ! # A value of +nil+ is an explicit representation of 'no cut'. ! attr_reader :primary ! ! # Location of the cut on the complementary strand. ! # Corresponds - or 'pairs' - to the primary cut. ! # A value of +nil+ is an explicit representation of 'no cut'. ! attr_reader :complement + # CutLocationPair constructor. + # + # Stores a single cut location pair in 0-based index notation for use with + # DoubleStranded enzyme sequences. + # + # Example: + # clp = CutLocationPair.new(3,2) + # clp.primary # 3 + # clp.complement # 2 + # + # --- + # *Arguments* + # * +pair+: May be two values represented as an Array, a Range, or a + # combination of Integer and nil values. The first value + # represents a cut on the primary strand, the second represents + # a cut on the complement strand. + # *Returns*:: nothing def initialize( *pair ) a = b = nil *************** *** 64,67 **** --- 76,80 ---- @primary = a @complement = b + return end *************** *** 85,93 **** def validate_2( a, b ) ! if a != nil and a.negative? ! raise ArgumentError, "0-based index notation only. Negative values are illegal." ! end ! ! if b != nil and b.negative? raise ArgumentError, "0-based index notation only. Negative values are illegal." end --- 98,102 ---- def validate_2( a, b ) ! if (a != nil and a.negative?) or (b != nil and b.negative?) raise ArgumentError, "0-based index notation only. Negative values are illegal." end From trevor at dev.open-bio.org Mon Jan 1 18:47:30 2007 From: trevor at dev.open-bio.org (Trevor Wennblom) Date: Mon, 01 Jan 2007 23:47:30 +0000 Subject: [BioRuby-cvs] bioruby/lib/bio/util/restriction_enzyme analysis_basic.rb, NONE, 1.1 analysis.rb, 1.7, 1.8 double_stranded.rb, 1.3, 1.4 Message-ID: <200701012347.l01NlUaJ002435@dev.open-bio.org> Update of /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme In directory dev.open-bio.org:/tmp/cvs-serv2413/restriction_enzyme Modified Files: analysis.rb double_stranded.rb Added Files: analysis_basic.rb Log Message: --- NEW FILE: analysis_basic.rb --- # # bio/util/restrction_enzyme/analysis_basic.rb - Does the work of fragmenting the DNA from the enzymes # # Author:: Trevor Wennblom # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com) # License:: Distributes under the same terms as Ruby # # $Id: analysis_basic.rb,v 1.1 2007/01/01 23:47:27 trevor Exp $ # #-- #if RUBY_VERSION[0..2] == '1.9' or RUBY_VERSION == '2.0' # err = "This class makes use of 'include' on ranges quite a bit. Possibly unstable in development Ruby. 2005/12/20." # err += "http://blade.nagaokaut.ac.jp/cgi-bin/vframe.rb/ruby/ruby-talk/167182?167051-169742" # raise err #end #++ require 'pathname' libpath = Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 4, 'lib')).cleanpath.to_s $:.unshift(libpath) unless $:.include?(libpath) require 'bio' class Bio::Sequence::NA # Example: # # seq = Bio::Sequence::NA.new('gaattc') # cuts = seq.cut_with_enzyme('EcoRI') # # _or_ # # seq = Bio::Sequence::NA.new('gaattc') # cuts = seq.cut_with_enzyme('g^aattc') # --- # See Bio::RestrictionEnzyme::Analysis.cut def cut_with_enzyme(*args) Bio::RestrictionEnzyme::Analysis.cut(self, *args) end alias cut_with_enzymes cut_with_enzyme end require 'pp' require 'bio/util/restriction_enzyme' require 'bio/util/restriction_enzyme/analysis/sequence_range' class Bio::RestrictionEnzyme # # bio/util/restrction_enzyme/analysis_basic.rb - Does the work of fragmenting the DNA from the enzymes # # Author:: Trevor Wennblom # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com) # License:: Distributes under the same terms as Ruby # class Analysis def self.cut( sequence, *args ) # self.new.cut( sequence, *args ) end def self.cut_without_permutations( sequence, *args ) self.new.cut_without_permutations( sequence, *args ) end # Example: # # Analysis.cut_without_permutations('gaattc', 'EcoRI') # # _same as:_ # # Analysis.cut_without_permutations('gaattc', 'g^aattc') # --- # *Arguments* # * +sequence+: +String+ kind of object that will be used as a nucleic acid sequence # * +args+: Series of # *Returns*:: +Hash+ ?(array?) of Bio::RestrictionEnzyme::Analysis::UniqueFragment objects def cut_without_permutations( sequence, *args ) return {} if !sequence.kind_of?(String) or sequence.empty? sequence = Bio::Sequence::NA.new( sequence ) tmp = create_enzyme_actions( sequence, *args ) enzyme_actions = tmp[0].merge(tmp[1]) sr_with_cuts = SequenceRange.new( 0, 0, sequence.size-1, sequence.size-1 ) enzyme_actions.each do |id, enzyme_action| enzyme_action.cut_ranges.each do |cut_range| sr_with_cuts.add_cut_range(cut_range) end end sr_with_cuts.fragments.primary = sequence sr_with_cuts.fragments.complement = sequence.forward_complement unique_fragments_for_display( {0 => sr_with_cuts} ) end ######### protected ######### UniqueFragment = Struct.new(:primary, :complement) class UniqueFragments < Array def primary tmp = [] self.each { |uf| tmp << uf.primary } tmp.sort.map { |e| e.tr(' ', '') } end def complement tmp = [] self.each { |uf| tmp << uf.complement } tmp.sort.map { |e| e.tr(' ', '') } end end def unique_fragments_for_display( hash_of_sequence_ranges_with_cuts ) uf_ary = UniqueFragments.new return uf_ary if hash_of_sequence_ranges_with_cuts == nil or hash_of_sequence_ranges_with_cuts.empty? hash_of_sequence_ranges_with_cuts.each do |permutation, sr_with_cuts| sr_with_cuts.fragments.for_display.each do |fragment| uf = UniqueFragment.new uf.primary = fragment.primary uf.complement = fragment.complement duplicate = false uf_ary.each do |element| if (uf.primary == element.primary) and (uf.complement == element.complement) duplicate = true break end end uf_ary << uf unless duplicate end end uf_ary end # Creates an array of EnzymeActions based on the DNA sequence and supplied enzymes. # # +sequence+:: The string of DNA to match the enzyme recognition sites against # +args+:: The enzymes to use. def create_enzyme_actions( sequence, *args ) id = 0 enzyme_actions_that_sometimes_cut = {} enzyme_actions_that_always_cut = {} indicies_of_sometimes_cut = [] args.each do |enzyme| enzyme = Bio::RestrictionEnzyme.new(enzyme) unless enzyme.class == Bio::RestrictionEnzyme::DoubleStranded find_match_locations( sequence, enzyme.primary.to_re ).each do |offset| #enzyme_actions_that_always_cut[id] = enzyme_to_enzyme_action( enzyme, offset ) enzyme_actions_that_always_cut[id] = enzyme.create_action_at( offset ) id += 1 end end # enzyme_actions_that_always_cut may lose members, the members to be lost are recorded in indicies_of_sometimes_cut max = enzyme_actions_that_always_cut.size - 1 0.upto(max) do |i| enzyme_action = enzyme_actions_that_always_cut[i] conflict = false other_cut_ranges = {} enzyme_actions_that_always_cut.each { |key,i_ea| next if i == key; other_cut_ranges[key] = i_ea.cut_ranges } other_cut_ranges.each do |key, cut_ranges| cut_ranges.each do |cut_range| next unless cut_range.class == VerticalCutRange # we aren't concerned with horizontal cuts previous_cut_left = cut_range.range.first previous_cut_right = cut_range.range.last if (enzyme_action.right <= previous_cut_left) or (enzyme_action.left > previous_cut_right) or (enzyme_action.left > previous_cut_left and enzyme_action.right <= previous_cut_right) # in between cuts # no conflict else conflict = true end indicies_of_sometimes_cut += [i, key] if conflict == true end end end indicies_of_sometimes_cut.uniq.each do |i| enzyme_actions_that_sometimes_cut[i] = enzyme_actions_that_always_cut[i] enzyme_actions_that_always_cut.delete(i) end [enzyme_actions_that_sometimes_cut, enzyme_actions_that_always_cut] end # Returns an +Array+ of the match indicies of a RegExp to a string. # # --- # *Arguments* # * +string+: The string to scan # * +re+: A RegExp to use # *Returns*:: +Array+ with indicies of match locations def find_match_locations( string, re ) md = string.match( re ) locations = [] counter = 0 while md # save the match index relative to the original string locations << (counter += md.begin(0)) # find the next match md = string[ (counter += 1)..-1 ].match( re ) end locations end end # Analysis end # Bio::RestrictionEnzyme Index: analysis.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/analysis.rb,v retrieving revision 1.7 retrieving revision 1.8 diff -C2 -d -r1.7 -r1.8 *** analysis.rb 1 Jan 2007 02:16:05 -0000 1.7 --- analysis.rb 1 Jan 2007 23:47:27 -0000 1.8 *************** *** 21,37 **** $:.unshift(libpath) unless $:.include?(libpath) ! require 'bio' ! class Bio::Sequence::NA ! # See Bio::RestrictionEnzyme::Analysis.cut ! def cut_with_enzyme(*args) ! Bio::RestrictionEnzyme::Analysis.cut(self, *args) ! end ! alias cut_with_enzymes cut_with_enzyme ! end ! ! require 'pp' ! ! require 'bio/util/restriction_enzyme' ! require 'bio/util/restriction_enzyme/analysis/sequence_range' class Bio::RestrictionEnzyme --- 21,25 ---- $:.unshift(libpath) unless $:.include?(libpath) ! require 'bio/util/restriction_enzyme/analysis_basic' class Bio::RestrictionEnzyme *************** *** 50,84 **** end ! def self.cut_without_permutations( sequence, *args ) ! self.new.cut_without_permutations( sequence, *args ) ! end ! ! def self.cut_and_return_by_permutations( sequence, *args ) ! self.new.cut_and_return_by_permutations( sequence, *args ) ! end ! ! def cut_without_permutations( sequence, *args ) ! return {} if !sequence.kind_of?(String) or sequence.empty? ! sequence = Bio::Sequence::NA.new( sequence ) ! ! #enzyme_actions = create_enzyme_actions( sequence, *args ) ! tmp = create_enzyme_actions( sequence, *args ) ! enzyme_actions = tmp[0].merge(tmp[1]) ! ! sr_with_cuts = SequenceRange.new( 0, 0, sequence.size-1, sequence.size-1 ) ! enzyme_actions.each do |id, enzyme_action| ! enzyme_action.cut_ranges.each do |cut_range| ! sr_with_cuts.add_cut_range(cut_range) ! end ! end ! ! sr_with_cuts.fragments.primary = sequence ! sr_with_cuts.fragments.complement = sequence.forward_complement ! ! tmp = {} ! tmp[0] = sr_with_cuts ! unique_fragments_for_display( tmp ) end def cut_and_return_by_permutations( sequence, *args ) return {} if !sequence.kind_of?(String) or sequence.empty? --- 38,51 ---- end ! def cut( sequence, *args ) ! return nil if !sequence.kind_of?(String) or sequence.empty? ! hash_of_sequence_ranges_with_cuts = cut_and_return_by_permutations( sequence, *args ) ! unique_fragments_for_display( hash_of_sequence_ranges_with_cuts ) end + ######### + protected + ######### + def cut_and_return_by_permutations( sequence, *args ) return {} if !sequence.kind_of?(String) or sequence.empty? *************** *** 123,134 **** previous_cut_right = cut_range.range.last - =begin - puts "--- #{permutation.inspect} ---" - puts "Previous cut left: #{previous_cut_left}" - puts "EA.left #{enzyme_action.left}" - puts "Previous cut right: #{previous_cut_right}" - puts "EA.right: #{enzyme_action.right}" - =end - # Keep in mind: # * The cut location is to the immediate right of the base located at the index. --- 90,93 ---- *************** *** 140,148 **** (enzyme_action.left > previous_cut_left and enzyme_action.right <= previous_cut_right) # in between cuts # no conflict - #puts "no conflict" - else conflict = true - #puts "conflict" end end --- 99,104 ---- *************** *** 161,178 **** end - #pp hash_of_sequence_ranges_with_cuts hash_of_sequence_ranges_with_cuts end - def cut( sequence, *args ) - return nil if !sequence.kind_of?(String) or sequence.empty? - hash_of_sequence_ranges_with_cuts = cut_and_return_by_permutations( sequence, *args ) - unique_fragments_for_display( hash_of_sequence_ranges_with_cuts ) - end - - ######### - protected - ######### - def permute(count, permutations = [[0]]) return permutations if count <= 1 --- 117,123 ---- *************** *** 190,366 **** end - UniqueFragment = Struct.new(:primary, :complement) - class UniqueFragments < Array - def primary - tmp = [] - self.each { |uf| tmp << uf.primary } - tmp.sort.map { |e| e.tr(' ', '') } - end - def complement - tmp = [] - self.each { |uf| tmp << uf.complement } - tmp.sort.map { |e| e.tr(' ', '') } - end - end - - def unique_fragments_for_display( hash_of_sequence_ranges_with_cuts ) - uf_ary = UniqueFragments.new - return uf_ary if hash_of_sequence_ranges_with_cuts == nil or hash_of_sequence_ranges_with_cuts.empty? - - hash_of_sequence_ranges_with_cuts.each do |permutation, sr_with_cuts| - sr_with_cuts.fragments.for_display.each do |fragment| - uf = UniqueFragment.new - uf.primary = fragment.primary - uf.complement = fragment.complement - - duplicate = false - uf_ary.each do |element| - if (uf.primary == element.primary) and (uf.complement == element.complement) - duplicate = true - break - end - end - - uf_ary << uf unless duplicate - end - end - uf_ary - end - - - =begin - Strand = Struct.new(:primary, :complement, :p_left, :p_right, :c_left, :c_right) - - def ts_fragments_to_strands( sequence, fragments ) - sequence = Bio::Sequence::NA.new( sequence ) - strands = [] - fragments.each do |f| - p = sequence[f.p_left..f.p_right] - c = sequence[f.c_left..f.c_right] - strands << Strand.new(p, c, f.p_left, f.p_right, f.c_left, f.c_right) - end - strands - end - =end - - # Defines a single enzyme action, in this case being a range that correlates - # to the DNA sequence that may contain it's own internal cuts. - class EnzymeAction < SequenceRange - end - - # Creates an array of EnzymeActions based on the DNA sequence and supplied enzymes. - # - # +sequence+:: The string of DNA to match the enzyme recognition sites against - # +args+:: The enzymes to use. - def create_enzyme_actions( sequence, *args ) - id = 0 - enzyme_actions_that_sometimes_cut = {} - enzyme_actions_that_always_cut = {} - indicies_of_sometimes_cut = [] - - args.each do |enzyme| - enzyme = Bio::RestrictionEnzyme.new(enzyme) unless enzyme.class == Bio::RestrictionEnzyme::DoubleStranded - find_match_locations( sequence, enzyme.primary.to_re ).each do |offset| - enzyme_actions_that_always_cut[id] = enzyme_to_enzyme_action( enzyme, offset ) - id += 1 - end - end - - # enzyme_actions_that_always_cut may lose members, the members to be lost are recorded in indicies_of_sometimes_cut - - max = enzyme_actions_that_always_cut.size - 1 - 0.upto(max) do |i| - enzyme_action = enzyme_actions_that_always_cut[i] - conflict = false - other_cut_ranges = {} - #enzyme_actions.each { |key,enzyme_action| next if i == key; puts "i: #{i}, key: #{key}"; previous_cut_ranges += enzyme_action.cut_ranges } - # enzyme_actions_that_always_cut.each { |key,i_ea| next if i == key; puts "i: #{i}, key: #{key}"; other_cut_ranges[key] = i_ea.cut_ranges } - enzyme_actions_that_always_cut.each { |key,i_ea| next if i == key; other_cut_ranges[key] = i_ea.cut_ranges } - # puts "Enzyme action #{i}:" - # pp enzyme_actions[i] - # pp enzyme_action - # puts "Previous cut ranges:" - # pp previous_cut_ranges - - other_cut_ranges.each do |key, cut_ranges| - cut_ranges.each do |cut_range| - next unless cut_range.class == VerticalCutRange # we aren't concerned with horizontal cuts - previous_cut_left = cut_range.range.first - previous_cut_right = cut_range.range.last - - if (enzyme_action.right <= previous_cut_left) or - (enzyme_action.left > previous_cut_right) or - (enzyme_action.left > previous_cut_left and enzyme_action.right <= previous_cut_right) # in between cuts - # no conflict - # puts "no conflict" - - else - conflict = true - # puts "conflict" - #puts "cut range:" - #pp cut_range - #puts "enzyme action:" - #pp enzyme_action - end - - indicies_of_sometimes_cut += [i, key] if conflict == true - end - end - - # We don't need to make permutations with this enzyme action if it always cuts - # indicies << i if conflict == false - end - # pp indicies_of_sometimes_cut - - indicies_of_sometimes_cut.uniq.each do |i| - enzyme_actions_that_sometimes_cut[i] = enzyme_actions_that_always_cut[i] - enzyme_actions_that_always_cut.delete(i) - end - #puts 'Always cut:' - #pp enzyme_actions_that_always_cut - #puts 'Permute:' - #pp enzyme_actions_that_sometimes_cut - - [enzyme_actions_that_sometimes_cut, enzyme_actions_that_always_cut] - end - - # Returns the offsets of the match of a RegExp to a string. - # - # +string+:: The string to scan. - # +re+:: A regexp to use. - def find_match_locations( string, re ) - md = string.match( re ) - locations = [] - location = -1 - while md - location += md.pre_match.size + 1 - locations << location - # md[0] is the same as $&, or "the match" itself - md = (md[0][1..-1] + md.post_match).match( re ) - end - locations - end - - # Takes a RestrictionEnzyme and a numerical offset to the sequence and - # returns an EnzymeAction - # - # +enzyme+:: RestrictionEnzyme - # +offset+:: Numerical offset of where the enzyme action occurs on the seqeunce - def enzyme_to_enzyme_action( enzyme, offset ) - enzyme_action = EnzymeAction.new(offset, offset + enzyme.primary.size-1, offset, offset + enzyme.complement.size-1) - - enzyme.cut_locations.each do |cut_pair| - p = cut_pair[0] - c = cut_pair[1] - if c >= p - enzyme_action.add_cut_range(offset+p, nil, nil, offset+c) - else - enzyme_action.add_cut_range(nil, offset+p, offset+c, nil) - end - end - - enzyme_action - end - end # Analysis end # Bio::RestrictionEnzyme --- 135,138 ---- Index: double_stranded.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/double_stranded.rb,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** double_stranded.rb 1 Jan 2007 05:07:04 -0000 1.3 --- double_stranded.rb 1 Jan 2007 23:47:27 -0000 1.4 *************** *** 14,17 **** --- 14,19 ---- require 'bio/db/rebase' require 'bio/util/restriction_enzyme' + require 'bio/util/restriction_enzyme/analysis/sequence_range' + require 'bio/util/restriction_enzyme/cut_symbol' require 'bio/util/restriction_enzyme/single_strand' *************** *** 96,99 **** --- 98,102 ---- # Decide if this String is an enzyme name or a pattern if Bio::RestrictionEnzyme.enzyme_name?( erp ) + # FIXME we added this to rebase... # Check if it's a known name known_enzyme = false *************** *** 157,160 **** --- 160,252 ---- !blunt? end + + # Takes a RestrictionEnzyme object and a numerical offset to the sequence and + # returns an EnzymeAction + # + # +restriction_enzyme+:: RestrictionEnzyme + # +offset+:: Numerical offset of where the enzyme action occurs on the seqeunce + def create_action_at( offset ) + #def enzyme_to_enzyme_action( restriction_enzyme, offset ) + enzyme_action = EnzymeAction.new( offset, + offset + @primary.size-1, + offset, + offset + @complement.size-1) + + @cut_locations.each do |cut_location_pair| + # cut_pair is a DoubleStranded::CutLocationPair + p, c = cut_location_pair.primary, cut_location_pair.complement + if c >= p + enzyme_action.add_cut_range(offset+p, nil, nil, offset+c) + else + enzyme_action.add_cut_range(nil, offset+p, offset+c, nil) + end + end + + enzyme_action + end + + # An EnzymeAction is a way of representing a potential effect that a + # RestrictionEnzyme may have on a nucleotide sequence, an 'action'. + # + # Multiple cuts in multiple locations on a sequence may occur in one + # 'action' if it is done by a single enzyme. + # + # An EnzymeAction is a series of locations that represents where the restriction + # enzyme will bind on the sequence, as well as what ranges are cut on the + # sequence itself. The complexity is due to the fact that our virtual + # restriction enzyme may create multiple segments from its cutting action, + # on which another restriction enzyme may operate upon. + # + # For example, the DNA sequence: + # + # 5' - G A A T A A A C G A - 3' + # 3' - C T T A T T T G C T - 5' + # + # When mixed with the restriction enzyme with the following cut pattern: + # + # 5' - A|A T A A A C|G - 3' + # +-+ + + # 3' - T T|A T T T G|C - 5' + # + # And also mixed with the restriction enzyme of the following cut pattern: + # + # 5' - A A|A C - 3' + # +-+ + # 3' - T|T T G - 5' + # + # Would result in a DNA sequence with these cuts: + # + # 5' - G A|A T A A|A C|G A - 3' + # +-+ +-+ + + # 3' - C T T|A T|T T G|C T - 5' + # + # Or these separate "free-floating" sequences: + # + # 5' - G A - 3' + # 3' - C T T - 5' + # + # 5' - A T A A - 3' + # 3' - A T - 5' + # + # 5' - A C - 3' + # 3' - T T G - 5' + # + # 5' - G A - 3' + # 3' - C T - 5' + # + # This would be represented by two EnzymeActions - one for each + # RestrictionEnzyme. + # + # To initialize an EnzymeAction you must first instantiate it with the + # beginning and ending locations of where it will operate on a nucleotide + # sequence. + # + # Next the ranges of cu + # + # An EnzymeAction is + # Defines a single enzyme action, in this case being a range that correlates + # to the DNA sequence that may contain it's own internal cuts. + class EnzymeAction < Bio::RestrictionEnzyme::Analysis::SequenceRange + end ######### From trevor at dev.open-bio.org Mon Jan 1 18:47:30 2007 From: trevor at dev.open-bio.org (Trevor Wennblom) Date: Mon, 01 Jan 2007 23:47:30 +0000 Subject: [BioRuby-cvs] bioruby/lib/bio/util/restriction_enzyme/analysis calculated_cuts.rb, 1.3, 1.4 cut_range.rb, 1.2, 1.3 cut_ranges.rb, 1.3, 1.4 horizontal_cut_range.rb, 1.2, 1.3 sequence_range.rb, 1.4, 1.5 vertical_cut_range.rb, 1.2, 1.3 Message-ID: <200701012347.l01NlU6G002440@dev.open-bio.org> Update of /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/analysis In directory dev.open-bio.org:/tmp/cvs-serv2413/restriction_enzyme/analysis Modified Files: calculated_cuts.rb cut_range.rb cut_ranges.rb horizontal_cut_range.rb sequence_range.rb vertical_cut_range.rb Log Message: Index: vertical_cut_range.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/analysis/vertical_cut_range.rb,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** vertical_cut_range.rb 31 Dec 2006 21:50:31 -0000 1.2 --- vertical_cut_range.rb 1 Jan 2007 23:47:28 -0000 1.3 *************** *** 31,34 **** --- 31,56 ---- attr_reader :range + # VerticalCutRange provides an extremely raw, yet precise, method of + # defining the location of cuts on primary and complementary sequences. + # + # Many VerticalCutRange objects are used with HorizontalCutRange objects + # to be contained in CutRanges to define the cut pattern that a + # specific enzyme may make. + # + # VerticalCutRange takes up to four possible cuts, two on the primary + # strand and two on the complementary strand. In typical usage + # you will want to make a single cut on the primary strand and a single + # cut on the complementary strand. + # + # However, you can construct it with whatever cuts you desire to accomadate + # the most eccentric of imaginary restriction enzymes. + # + # --- + # *Arguments* + # * +p_cut_left+: (_optional_) Left-most cut on the primary strand. +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 def initialize( p_cut_left=nil, p_cut_right=nil, c_cut_left=nil, c_cut_right=nil ) @p_cut_left = p_cut_left *************** *** 45,50 **** --- 67,80 ---- @range = nil @range = (@min.. at max) unless @min == nil or @max == nil + return end + # Check if a location falls within the minimum or maximum values of this + # range. + # + # --- + # *Arguments* + # * +i+: Location to check if it is included in the range + # *Returns*:: +true+ _or_ +false+ def include?(i) return false if @range == nil Index: horizontal_cut_range.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/analysis/horizontal_cut_range.rb,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** horizontal_cut_range.rb 31 Dec 2006 21:50:31 -0000 1.2 --- horizontal_cut_range.rb 1 Jan 2007 23:47:28 -0000 1.3 *************** *** 36,41 **** # The 'range' here is actually off by one on the left # side in relation to a normal CutRange, so using the normal ! # variables from CutRange would result in unpredictable ! # behavior. @p_cut_left = nil --- 36,52 ---- # The 'range' here is actually off by one on the left # side in relation to a normal CutRange, so using the normal ! # variables from CutRange would result in bad behavior. ! # ! # See below - the first horizontal cut is the primary cut plus one. ! # ! # 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 @p_cut_left = nil *************** *** 50,53 **** --- 61,71 ---- end + # Check if a location falls within the minimum or maximum values of this + # range. + # + # --- + # *Arguments* + # * +i+: Location to check if it is included in the range + # *Returns*:: +true+ _or_ +false+ def include?(i) @range.include?(i) Index: calculated_cuts.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/analysis/calculated_cuts.rb,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** calculated_cuts.rb 1 Jan 2007 05:07:04 -0000 1.3 --- calculated_cuts.rb 1 Jan 2007 23:47:28 -0000 1.4 *************** *** 27,30 **** --- 27,34 ---- # License:: Distributes under the same terms as Ruby # + # 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 *************** *** 41,55 **** include StringFormatting ! # Vertical cuts on the primary strand attr_reader :vc_primary ! # Vertical cuts on the complement strand attr_reader :vc_complement ! # Horizontal cuts attr_reader :hc_between_strands # Set to +true+ if the fragment CalculatedCuts is working on is circular attr_accessor :circular def initialize(size=nil, circular=false) --- 45,69 ---- include StringFormatting ! # +Array+ of vertical cuts on the primary strand in 0-based index notation attr_reader :vc_primary ! # +Array+ of vertical cuts on the complementary strand in 0-based index notation attr_reader :vc_complement ! # +Array+ of horizontal cuts between strands in 0-based index notation attr_reader :hc_between_strands # Set to +true+ if the fragment CalculatedCuts is working on is circular attr_accessor :circular + + # An +Array+ with the primary strand with vertical cuts, the horizontal cuts, and the complementary strand with vertical cuts. + attr_reader :strands_for_display + + # 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. + attr_reader :strands_for_display_current + + # Size of the sequence being digested. + attr_reader :size def initialize(size=nil, circular=false) *************** *** 61,64 **** --- 75,82 ---- end + # --- + # *Arguments* + # * +cut_ranges+: An +Array+ of HorizontalCutRange or VerticalCutRange objects + # *Returns*:: nothing def add_cuts_from_cut_ranges(cut_ranges) @strands_for_display_current = false *************** *** 68,71 **** --- 86,91 ---- @vc_complement += [cut_range.c_cut_left, cut_range.c_cut_right] + # Add horizontal cut ranges. This may happen from cuts made inbetween a + # VerticalCutRange or may be specifically defined by a HorizontalCutRange. if cut_range.class == VerticalCutRange ( cut_range.min + 1 ).upto( cut_range.max ){|i| @hc_between_strands << i} if cut_range.min < cut_range.max *************** *** 75,80 **** --- 95,129 ---- end clean_all + #return 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* + # * +size+: (_optional_) Size of the sequence being digested. Defined here or during initalization of CalculatedCuts. + # *Returns*:: nothing def remove_incomplete_cuts(size=nil) @strands_for_display_current = false *************** *** 90,94 **** if @circular # NOTE ! # if it's circular we should start at the beginning of a cut for orientation # scan for it, hack off the first set of hcuts and move them to the back else --- 139,143 ---- if @circular # NOTE ! # if it's circular we should start at the beginning of a cut for orientation, # scan for it, hack off the first set of hcuts and move them to the back else *************** *** 133,136 **** --- 182,196 ---- end + # 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. + # def strands_for_display(str1 = nil, str2 = nil, vcp=nil, vcc=nil, hc=nil) return @strands_for_display if @strands_for_display_current *************** *** 178,181 **** --- 238,243 ---- ######### + # remove nil values, remove duplicate values, and + # sort @vc_primary, @vc_complement, and @hc_between_strands def clean_all [@vc_primary, @vc_complement, @hc_between_strands].collect { |a| a.delete(nil); a.uniq!; a.sort! } Index: cut_range.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/analysis/cut_range.rb,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** cut_range.rb 31 Dec 2006 21:50:31 -0000 1.2 --- cut_range.rb 1 Jan 2007 23:47:28 -0000 1.3 *************** *** 1,4 **** # ! # bio/util/restrction_enzyme/analysis/cut_range.rb - # # Author:: Trevor Wennblom --- 1,4 ---- # ! # bio/util/restrction_enzyme/analysis/cut_range.rb - Abstract base class for HorizontalCutRange and VerticalCutRange # # Author:: Trevor Wennblom *************** *** 20,24 **** # ! # bio/util/restrction_enzyme/analysis/cut_range.rb - # # Author:: Trevor Wennblom --- 20,24 ---- # ! # bio/util/restrction_enzyme/analysis/cut_range.rb - Abstract base class for HorizontalCutRange and VerticalCutRange # # Author:: Trevor Wennblom *************** *** 26,29 **** --- 26,31 ---- # License:: Distributes under the same terms as Ruby # + # Abstract base class for HorizontalCutRange and VerticalCutRange + # class CutRange end # CutRange Index: cut_ranges.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/analysis/cut_ranges.rb,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** cut_ranges.rb 1 Jan 2007 02:16:05 -0000 1.3 --- cut_ranges.rb 1 Jan 2007 23:47:28 -0000 1.4 *************** *** 1,4 **** # ! # bio/util/restrction_enzyme/analysis/cut_ranges.rb - # # Author:: Trevor Wennblom --- 1,4 ---- # ! # bio/util/restrction_enzyme/analysis/cut_ranges.rb - Container for many CutRange objects or CutRange child objects. # # Author:: Trevor Wennblom *************** *** 12,24 **** $:.unshift(libpath) unless $:.include?(libpath) - #require 'bio' - module Bio; end class Bio::RestrictionEnzyme class Analysis ! #class Analysis ! # ! # bio/util/restrction_enzyme/analysis/cut_ranges.rb - # # Author:: Trevor Wennblom --- 12,21 ---- $:.unshift(libpath) unless $:.include?(libpath) module Bio; end class Bio::RestrictionEnzyme class Analysis ! # ! # bio/util/restrction_enzyme/analysis/cut_ranges.rb - Container for many CutRange objects or CutRange child objects. # # Author:: Trevor Wennblom *************** *** 26,29 **** --- 23,28 ---- # License:: Distributes under the same terms as Ruby # + # Container for many CutRange objects or CutRange child objects. Inherits from array. + # class CutRanges < Array def min; self.collect{|a| a.min}.flatten.sort.first; end Index: sequence_range.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/analysis/sequence_range.rb,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** sequence_range.rb 1 Jan 2007 02:31:22 -0000 1.4 --- sequence_range.rb 1 Jan 2007 23:47:28 -0000 1.5 *************** *** 87,98 **** # scan for it, hack off the first set of hcuts and move them to the back else - # last_index = @size - 1 p_cut.unshift(-1) unless p_cut.include?(-1) - # p_cut.push(last_index) unless p_cut.include?(last_index) c_cut.unshift(-1) unless c_cut.include?(-1) - # c_cut.push(last_index) unless c_cut.include?(last_index) end - if @circular largest_bin = 0 --- 87,94 ---- *************** *** 114,118 **** -1.upto(@size-1) do |idx| - # if bins are out of sync but the strands are attached if p_bin != c_bin and h.include?(idx) == false --- 110,113 ---- *************** *** 134,138 **** x.call(c_bin) end - end --- 129,132 ---- *************** *** 141,148 **** bins.delete(-1) unless @circular - # require 'pp' - # pp bins - - #NOTE str1 = nil str2 = nil --- 135,138 ---- *************** *** 159,166 **** end - #pp fragments.for_display - # pp fragments - # exit - @__fragments = fragments return fragments --- 149,152 ---- From trevor at dev.open-bio.org Mon Jan 1 18:54:35 2007 From: trevor at dev.open-bio.org (Trevor Wennblom) Date: Mon, 01 Jan 2007 23:54:35 +0000 Subject: [BioRuby-cvs] bioruby/lib/bio/util/restriction_enzyme/range - New directory Message-ID: <200701012354.l01NsZPO002475@dev.open-bio.org> Update of /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/range In directory dev.open-bio.org:/tmp/cvs-serv2455/range Log Message: Directory /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/range added to the repository From trevor at dev.open-bio.org Mon Jan 1 19:12:30 2007 From: trevor at dev.open-bio.org (Trevor Wennblom) Date: Tue, 02 Jan 2007 00:12:30 +0000 Subject: [BioRuby-cvs] bioruby/lib/bio/util/restriction_enzyme/range/sequence_range - New directory Message-ID: <200701020012.l020CUSi002607@dev.open-bio.org> Update of /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/range/sequence_range In directory dev.open-bio.org:/tmp/cvs-serv2587/sequence_range Log Message: Directory /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/range/sequence_range added to the repository From trevor at dev.open-bio.org Mon Jan 1 19:13:09 2007 From: trevor at dev.open-bio.org (Trevor Wennblom) Date: Tue, 02 Jan 2007 00:13:09 +0000 Subject: [BioRuby-cvs] bioruby/lib/bio/util/restriction_enzyme analysis.rb, 1.8, 1.9 analysis_basic.rb, 1.1, 1.2 double_stranded.rb, 1.4, 1.5 Message-ID: <200701020013.l020D9ZK002682@dev.open-bio.org> Update of /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme In directory dev.open-bio.org:/tmp/cvs-serv2656/restriction_enzyme Modified Files: analysis.rb analysis_basic.rb double_stranded.rb Log Message: Index: analysis_basic.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/analysis_basic.rb,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** analysis_basic.rb 1 Jan 2007 23:47:27 -0000 1.1 --- analysis_basic.rb 2 Jan 2007 00:13:07 -0000 1.2 *************** *** 43,47 **** require 'bio/util/restriction_enzyme' ! require 'bio/util/restriction_enzyme/analysis/sequence_range' class Bio::RestrictionEnzyme --- 43,47 ---- require 'bio/util/restriction_enzyme' ! require 'bio/util/restriction_enzyme/range/sequence_range' class Bio::RestrictionEnzyme *************** *** 83,87 **** enzyme_actions = tmp[0].merge(tmp[1]) ! sr_with_cuts = SequenceRange.new( 0, 0, sequence.size-1, sequence.size-1 ) enzyme_actions.each do |id, enzyme_action| enzyme_action.cut_ranges.each do |cut_range| --- 83,87 ---- enzyme_actions = tmp[0].merge(tmp[1]) ! sr_with_cuts = Bio::RestrictionEnzyme::Range::SequenceRange.new( 0, 0, sequence.size-1, sequence.size-1 ) enzyme_actions.each do |id, enzyme_action| enzyme_action.cut_ranges.each do |cut_range| *************** *** 167,171 **** other_cut_ranges.each do |key, cut_ranges| cut_ranges.each do |cut_range| ! next unless cut_range.class == VerticalCutRange # we aren't concerned with horizontal cuts previous_cut_left = cut_range.range.first previous_cut_right = cut_range.range.last --- 167,171 ---- other_cut_ranges.each do |key, cut_ranges| cut_ranges.each do |cut_range| ! next unless cut_range.class == Bio::RestrictionEnzyme::Range::VerticalCutRange # we aren't concerned with horizontal cuts previous_cut_left = cut_range.range.first previous_cut_right = cut_range.range.last Index: analysis.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/analysis.rb,v retrieving revision 1.8 retrieving revision 1.9 diff -C2 -d -r1.8 -r1.9 *** analysis.rb 1 Jan 2007 23:47:27 -0000 1.8 --- analysis.rb 2 Jan 2007 00:13:07 -0000 1.9 *************** *** 64,68 **** if permutations.empty? ! sr_with_cuts = SequenceRange.new( 0, 0, sequence.size-1, sequence.size-1 ) initial_cuts.each { |key, enzyme_action| enzyme_action.cut_ranges.each { |cut_range| sr_with_cuts.add_cut_range(cut_range) } } hash_of_sequence_ranges_with_cuts[0] = sr_with_cuts --- 64,68 ---- if permutations.empty? ! sr_with_cuts = Bio::RestrictionEnzyme::Range::SequenceRange.new( 0, 0, sequence.size-1, sequence.size-1 ) initial_cuts.each { |key, enzyme_action| enzyme_action.cut_ranges.each { |cut_range| sr_with_cuts.add_cut_range(cut_range) } } hash_of_sequence_ranges_with_cuts[0] = sr_with_cuts *************** *** 71,75 **** permutations.each do |permutation| previous_cut_ranges = [] ! sr_with_cuts = SequenceRange.new( 0, 0, sequence.size-1, sequence.size-1 ) initial_cuts.each { |enzyme_action| enzyme_action.cut_ranges.each { |cut_range| sr_with_cuts.add_cut_range(cut_range) } } --- 71,75 ---- permutations.each do |permutation| previous_cut_ranges = [] ! sr_with_cuts = Bio::RestrictionEnzyme::Range::SequenceRange.new( 0, 0, sequence.size-1, sequence.size-1 ) initial_cuts.each { |enzyme_action| enzyme_action.cut_ranges.each { |cut_range| sr_with_cuts.add_cut_range(cut_range) } } *************** *** 86,90 **** # so all cut locations must be checked that would fall underneath. previous_cut_ranges.each do |cut_range| ! next unless cut_range.class == VerticalCutRange # we aren't concerned with horizontal cuts previous_cut_left = cut_range.range.first previous_cut_right = cut_range.range.last --- 86,90 ---- # so all cut locations must be checked that would fall underneath. previous_cut_ranges.each do |cut_range| ! next unless cut_range.class == Bio::RestrictionEnzyme::Range::VerticalCutRange # we aren't concerned with horizontal cuts previous_cut_left = cut_range.range.first previous_cut_right = cut_range.range.last Index: double_stranded.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/double_stranded.rb,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** double_stranded.rb 1 Jan 2007 23:47:27 -0000 1.4 --- double_stranded.rb 2 Jan 2007 00:13:07 -0000 1.5 *************** *** 14,18 **** require 'bio/db/rebase' require 'bio/util/restriction_enzyme' ! require 'bio/util/restriction_enzyme/analysis/sequence_range' require 'bio/util/restriction_enzyme/cut_symbol' --- 14,18 ---- require 'bio/db/rebase' require 'bio/util/restriction_enzyme' ! require 'bio/util/restriction_enzyme/range/sequence_range' require 'bio/util/restriction_enzyme/cut_symbol' *************** *** 247,251 **** # Defines a single enzyme action, in this case being a range that correlates # to the DNA sequence that may contain it's own internal cuts. ! class EnzymeAction < Bio::RestrictionEnzyme::Analysis::SequenceRange end --- 247,251 ---- # Defines a single enzyme action, in this case being a range that correlates # to the DNA sequence that may contain it's own internal cuts. ! class EnzymeAction < Bio::RestrictionEnzyme::Range::SequenceRange end From trevor at dev.open-bio.org Mon Jan 1 19:13:09 2007 From: trevor at dev.open-bio.org (Trevor Wennblom) Date: Tue, 02 Jan 2007 00:13:09 +0000 Subject: [BioRuby-cvs] bioruby/lib/bio/util/restriction_enzyme/range cut_range.rb, NONE, 1.1 cut_ranges.rb, NONE, 1.1 horizontal_cut_range.rb, NONE, 1.1 sequence_range.rb, NONE, 1.1 vertical_cut_range.rb, NONE, 1.1 Message-ID: <200701020013.l020D99D002693@dev.open-bio.org> Update of /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/range In directory dev.open-bio.org:/tmp/cvs-serv2656/restriction_enzyme/range Added Files: cut_range.rb cut_ranges.rb horizontal_cut_range.rb sequence_range.rb vertical_cut_range.rb Log Message: --- NEW FILE: vertical_cut_range.rb --- # # bio/util/restrction_enzyme/range/vertical_cut_range.rb - # # Author:: Trevor Wennblom # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com) # License:: Distributes under the same terms as Ruby # # $Id: vertical_cut_range.rb,v 1.1 2007/01/02 00:13:07 trevor Exp $ # require 'pathname' libpath = Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 5, 'lib')).cleanpath.to_s $:.unshift(libpath) unless $:.include?(libpath) require 'bio/util/restriction_enzyme/range/cut_range' module Bio; end class Bio::RestrictionEnzyme class Range # # bio/util/restrction_enzyme/range/vertical_cut_range.rb - # # Author:: Trevor Wennblom # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com) # License:: Distributes under the same terms as Ruby # class VerticalCutRange < CutRange attr_reader :p_cut_left, :p_cut_right attr_reader :c_cut_left, :c_cut_right attr_reader :min, :max attr_reader :range # VerticalCutRange provides an extremely raw, yet precise, method of # defining the location of cuts on primary and complementary sequences. # # Many VerticalCutRange objects are used with HorizontalCutRange objects # to be contained in CutRanges to define the cut pattern that a # specific enzyme may make. # # VerticalCutRange takes up to four possible cuts, two on the primary # strand and two on the complementary strand. In typical usage # you will want to make a single cut on the primary strand and a single # cut on the complementary strand. # # However, you can construct it with whatever cuts you desire to accomadate # the most eccentric of imaginary restriction enzymes. # # --- # *Arguments* # * +p_cut_left+: (_optional_) Left-most cut on the primary strand. +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 def initialize( p_cut_left=nil, p_cut_right=nil, c_cut_left=nil, c_cut_right=nil ) @p_cut_left = p_cut_left @p_cut_right = p_cut_right @c_cut_left = c_cut_left @c_cut_right = c_cut_right a = [@p_cut_left, @c_cut_left, @p_cut_right, @c_cut_right] a.delete(nil) a.sort! @min = a.first @max = a.last @range = nil @range = (@min.. at max) unless @min == nil or @max == nil return end # Check if a location falls within the minimum or maximum values of this # range. # # --- # *Arguments* # * +i+: Location to check if it is included in the range # *Returns*:: +true+ _or_ +false+ def include?(i) return false if @range == nil @range.include?(i) end end # VerticalCutRange end # Range end # Bio::RestrictionEnzyme --- NEW FILE: horizontal_cut_range.rb --- # # bio/util/restrction_enzyme/range/horizontal_cut_range.rb - # # Author:: Trevor Wennblom # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com) # License:: Distributes under the same terms as Ruby # # $Id: horizontal_cut_range.rb,v 1.1 2007/01/02 00:13:07 trevor Exp $ # require 'pathname' libpath = Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 5, 'lib')).cleanpath.to_s $:.unshift(libpath) unless $:.include?(libpath) require 'bio/util/restriction_enzyme/range/cut_range' module Bio; end class Bio::RestrictionEnzyme class Range # # bio/util/restrction_enzyme/range/horizontal_cut_range.rb - # # Author:: Trevor Wennblom # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com) # License:: Distributes under the same terms as Ruby # class HorizontalCutRange < CutRange attr_reader :p_cut_left, :p_cut_right attr_reader :c_cut_left, :c_cut_right attr_reader :min, :max attr_reader :hcuts def initialize( left, right=left ) raise "left > right" if left > right # The 'range' here is actually off by one on the left # side in relation to a normal CutRange, so using the normal # variables from CutRange would result in bad behavior. # # See below - the first horizontal cut is the primary cut plus one. # # 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 @p_cut_left = nil @p_cut_right = nil @c_cut_left = nil @c_cut_right = nil @min = nil @max = nil @range = nil @hcuts = (left..right) end # Check if a location falls within the minimum or maximum values of this # range. # # --- # *Arguments* # * +i+: Location to check if it is included in the range # *Returns*:: +true+ _or_ +false+ def include?(i) @range.include?(i) end end # HorizontalCutRange end # Range end # Bio::RestrictionEnzyme --- NEW FILE: sequence_range.rb --- # # bio/util/restrction_enzyme/range/sequence_range.rb - # # Author:: Trevor Wennblom # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com) # License:: Distributes under the same terms as Ruby # # $Id: sequence_range.rb,v 1.1 2007/01/02 00:13:07 trevor Exp $ # require 'pathname' libpath = Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 5, 'lib')).cleanpath.to_s $:.unshift(libpath) unless $:.include?(libpath) require 'bio/util/restriction_enzyme/range/cut_ranges' require 'bio/util/restriction_enzyme/range/horizontal_cut_range' require 'bio/util/restriction_enzyme/range/vertical_cut_range' require 'bio/util/restriction_enzyme/range/sequence_range/calculated_cuts' require 'bio/util/restriction_enzyme/range/sequence_range/fragments' require 'bio/util/restriction_enzyme/range/sequence_range/fragment' require 'bio' module Bio; end class Bio::RestrictionEnzyme class Range # # bio/util/restrction_enzyme/range/sequence_range.rb - # # Author:: Trevor Wennblom # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com) # License:: Distributes under the same terms as Ruby # class SequenceRange attr_reader :p_left, :p_right attr_reader :c_left, :c_right attr_reader :left, :right attr_reader :size attr_reader :cut_ranges def initialize( p_left = nil, p_right = nil, c_left = nil, c_right = nil ) @__fragments_current = false raise ArgumentError if p_left == nil and c_left == nil raise ArgumentError if p_right == nil and c_right == nil (raise ArgumentError unless p_left <= p_right) unless p_left == nil or p_right == nil (raise ArgumentError unless c_left <= c_right) unless c_left == nil or c_right == nil @p_left = p_left @p_right = p_right @c_left = c_left @c_right = c_right tmp = [p_left, c_left] tmp.delete(nil) @left = tmp.sort.first tmp = [p_right, c_right] tmp.delete(nil) @right = tmp.sort.last @size = (@right - @left) + 1 unless @left == nil or @right == nil @cut_ranges = CutRanges.new end =begin Special Case: Horizontal cuts at beginning or end of strand =end Bin = Struct.new(:c, :p) def fragments return @__fragments if @__fragments_current == true @__fragments_current = true cc = Bio::RestrictionEnzyme::Range::SequenceRange::CalculatedCuts.new(@size) cc.add_cuts_from_cut_ranges(@cut_ranges) cc.remove_incomplete_cuts p_cut = cc.vc_primary c_cut = cc.vc_complement h = cc.hc_between_strands if @circular # NOTE # if it's circular we should start at the beginning of a cut for orientation # scan for it, hack off the first set of hcuts and move them to the back else p_cut.unshift(-1) unless p_cut.include?(-1) c_cut.unshift(-1) unless c_cut.include?(-1) end if @circular largest_bin = 0 else largest_bin = -1 end p_bin = largest_bin c_bin = largest_bin bins = { largest_bin => Bin.new } # bin_id, bin bins[ largest_bin ].p = [] bins[ largest_bin ].c = [] x = lambda do |bin_id| largest_bin += 1 bins[ bin_id ] = Bin.new bins[ bin_id ].p = [] bins[ bin_id ].c = [] end -1.upto(@size-1) do |idx| # if bins are out of sync but the strands are attached if p_bin != c_bin and h.include?(idx) == false bins.delete( [p_bin, c_bin].sort.last ) p_bin = c_bin = [p_bin, c_bin].sort.first largest_bin -= 1 end bins[ p_bin ].p << idx bins[ c_bin ].c << idx if p_cut.include? idx p_bin = largest_bin + 1 x.call(p_bin) end if c_cut.include? idx c_bin = largest_bin + 1 x.call(c_bin) end end # Easy way to indicate the start of a strand just in case # there is a horizontal cut at position 0 bins.delete(-1) unless @circular str1 = nil str2 = nil num_txt_repeat = lambda { num_txt = '0123456789'; (num_txt * ( @size / num_txt.size.to_f ).ceil)[0.. at size-1] } (str1 == nil) ? a = num_txt_repeat.call : a = str1.dup (str2 == nil) ? b = num_txt_repeat.call : b = str2.dup fragments = Fragments.new(a,b) bins.sort.each do |k, bin| fragment = Fragment.new( bin.p, bin.c ) fragments << fragment end @__fragments = fragments return fragments end # Cut occurs immediately after the index supplied. # For example, a cut at '0' would mean a cut occurs between 0 and 1. def add_cut_range( p_cut_left=nil, p_cut_right=nil, c_cut_left=nil, c_cut_right=nil ) @__fragments_current = false if p_cut_left.kind_of? CutRange @cut_ranges << p_cut_left else (raise IndexError unless p_cut_left >= @left and p_cut_left <= @right) unless p_cut_left == nil (raise IndexError unless p_cut_right >= @left and p_cut_right <= @right) unless p_cut_right == nil (raise IndexError unless c_cut_left >= @left and c_cut_left <= @right) unless c_cut_left == nil (raise IndexError unless c_cut_right >= @left and c_cut_right <= @right) unless c_cut_right == nil @cut_ranges << VerticalCutRange.new( p_cut_left, p_cut_right, c_cut_left, c_cut_right ) end end def add_cut_ranges(*cut_ranges) cut_ranges.flatten! cut_ranges.each do |cut_range| raise TypeError, "Not of type CutRange" unless cut_range.kind_of? CutRange self.add_cut_range( cut_range ) end end def add_horizontal_cut_range( left, right=left ) @__fragments_current = false @cut_ranges << HorizontalCutRange.new( left, right ) end end # SequenceRange end # Range end # Bio::RestrictionEnzyme --- NEW FILE: cut_ranges.rb --- # # bio/util/restrction_enzyme/range/cut_ranges.rb - Container for many CutRange objects or CutRange child objects. # # Author:: Trevor Wennblom # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com) # License:: Distributes under the same terms as Ruby # # $Id: cut_ranges.rb,v 1.1 2007/01/02 00:13:07 trevor Exp $ # require 'pathname' libpath = Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 5, 'lib')).cleanpath.to_s $:.unshift(libpath) unless $:.include?(libpath) module Bio; end class Bio::RestrictionEnzyme class Range # # bio/util/restrction_enzyme/range/cut_ranges.rb - Container for many CutRange objects or CutRange child objects. # # Author:: Trevor Wennblom # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com) # License:: Distributes under the same terms as Ruby # # Container for many CutRange objects or CutRange child objects. Inherits from array. # class CutRanges < Array def min; self.collect{|a| a.min}.flatten.sort.first; end def max; self.collect{|a| a.max}.flatten.sort.last; end def include?(i); self.collect{|a| a.include?(i)}.include?(true); end end # CutRanges end # Range end # Bio::RestrictionEnzyme --- NEW FILE: cut_range.rb --- # # bio/util/restrction_enzyme/range/cut_range.rb - Abstract base class for HorizontalCutRange and VerticalCutRange # # Author:: Trevor Wennblom # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com) # License:: Distributes under the same terms as Ruby # # $Id: cut_range.rb,v 1.1 2007/01/02 00:13:07 trevor Exp $ # require 'pathname' libpath = Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 5, 'lib')).cleanpath.to_s $:.unshift(libpath) unless $:.include?(libpath) require 'bio' module Bio; end class Bio::RestrictionEnzyme class Range # # bio/util/restrction_enzyme/range/cut_range.rb - Abstract base class for HorizontalCutRange and VerticalCutRange # # Author:: Trevor Wennblom # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com) # License:: Distributes under the same terms as Ruby # # Abstract base class for HorizontalCutRange and VerticalCutRange # class CutRange end # CutRange end # Range end # Bio::RestrictionEnzyme From trevor at dev.open-bio.org Mon Jan 1 19:13:09 2007 From: trevor at dev.open-bio.org (Trevor Wennblom) Date: Tue, 02 Jan 2007 00:13:09 +0000 Subject: [BioRuby-cvs] bioruby/lib/bio/util/restriction_enzyme/analysis calculated_cuts.rb, 1.4, NONE cut_range.rb, 1.3, NONE cut_ranges.rb, 1.4, NONE fragment.rb, 1.3, NONE fragments.rb, 1.2, NONE horizontal_cut_range.rb, 1.3, NONE sequence_range.rb, 1.5, NONE vertical_cut_range.rb, 1.3, NONE Message-ID: <200701020013.l020D9Xl002689@dev.open-bio.org> Update of /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/analysis In directory dev.open-bio.org:/tmp/cvs-serv2656/restriction_enzyme/analysis Removed Files: calculated_cuts.rb cut_range.rb cut_ranges.rb fragment.rb fragments.rb horizontal_cut_range.rb sequence_range.rb vertical_cut_range.rb Log Message: --- vertical_cut_range.rb DELETED --- --- fragment.rb DELETED --- --- horizontal_cut_range.rb DELETED --- --- fragments.rb DELETED --- --- calculated_cuts.rb DELETED --- --- cut_range.rb DELETED --- --- cut_ranges.rb DELETED --- --- sequence_range.rb DELETED --- From trevor at dev.open-bio.org Mon Jan 1 19:13:09 2007 From: trevor at dev.open-bio.org (Trevor Wennblom) Date: Tue, 02 Jan 2007 00:13:09 +0000 Subject: [BioRuby-cvs] bioruby/lib/bio/util/restriction_enzyme/range/sequence_range calculated_cuts.rb, NONE, 1.1 fragment.rb, NONE, 1.1 fragments.rb, NONE, 1.1 Message-ID: <200701020013.l020D9Ea002702@dev.open-bio.org> Update of /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/range/sequence_range In directory dev.open-bio.org:/tmp/cvs-serv2656/restriction_enzyme/range/sequence_range Added Files: calculated_cuts.rb fragment.rb fragments.rb Log Message: --- NEW FILE: calculated_cuts.rb --- # # bio/util/restrction_enzyme/analysis/calculated_cuts.rb - # # Author:: Trevor Wennblom # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com) # License:: Distributes under the same terms as Ruby # # $Id: calculated_cuts.rb,v 1.1 2007/01/02 00:13:07 trevor Exp $ # require 'pathname' libpath = Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 6, 'lib')).cleanpath.to_s $:.unshift(libpath) unless $:.include?(libpath) require 'bio/util/restriction_enzyme/cut_symbol' require 'bio/util/restriction_enzyme/string_formatting' module Bio; end class Bio::RestrictionEnzyme class Range class SequenceRange # # bio/util/restrction_enzyme/analysis/calculated_cuts.rb - # # Author:: Trevor Wennblom # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com) # License:: Distributes under the same terms as Ruby # # 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 # class CalculatedCuts include CutSymbol include StringFormatting # +Array+ of vertical cuts on the primary strand in 0-based index notation attr_reader :vc_primary # +Array+ of vertical cuts on the complementary strand in 0-based index notation attr_reader :vc_complement # +Array+ of horizontal cuts between strands in 0-based index notation attr_reader :hc_between_strands # Set to +true+ if the fragment CalculatedCuts is working on is circular attr_accessor :circular # An +Array+ with the primary strand with vertical cuts, the horizontal cuts, and the complementary strand with vertical cuts. attr_reader :strands_for_display # 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. attr_reader :strands_for_display_current # Size of the sequence being digested. attr_reader :size def initialize(size=nil, circular=false) @size = size @circular = circular @vc_primary = [] @vc_complement = [] @hc_between_strands = [] end # --- # *Arguments* # * +cut_ranges+: An +Array+ of HorizontalCutRange or VerticalCutRange objects # *Returns*:: nothing def add_cuts_from_cut_ranges(cut_ranges) @strands_for_display_current = false cut_ranges.each do |cut_range| @vc_primary += [cut_range.p_cut_left, cut_range.p_cut_right] @vc_complement += [cut_range.c_cut_left, cut_range.c_cut_right] # Add horizontal cut ranges. This may happen from cuts made inbetween a # VerticalCutRange or may be specifically defined by a HorizontalCutRange. if cut_range.class == VerticalCutRange ( cut_range.min + 1 ).upto( cut_range.max ){|i| @hc_between_strands << i} if cut_range.min < cut_range.max elsif cut_range.class == HorizontalCutRange ( cut_range.hcuts.first ).upto( cut_range.hcuts.last ){|i| @hc_between_strands << i} end end clean_all #return 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* # * +size+: (_optional_) Size of the sequence being digested. Defined here or during initalization of CalculatedCuts. # *Returns*:: nothing def remove_incomplete_cuts(size=nil) @strands_for_display_current = false @size = size if size raise IndexError, "Size of the strand must be provided here or during initalization." if !@size.kind_of?(Fixnum) and not @circular vcuts = (@vc_primary + @vc_complement).uniq.sort hcuts = @hc_between_strands last_index = @size - 1 good_hcuts = [] potential_hcuts = [] if @circular # NOTE # if it's circular we should start at the beginning of a cut for orientation, # scan for it, hack off the first set of hcuts and move them to the back else vcuts.unshift(-1) unless vcuts.include?(-1) vcuts.push(last_index) unless vcuts.include?(last_index) end hcuts.each do |hcut| raise IndexError if hcut < -1 or hcut > last_index # skipped a nucleotide potential_hcuts.clear if !potential_hcuts.empty? and (hcut - potential_hcuts.last).abs > 1 if potential_hcuts.empty? if vcuts.include?( hcut ) and vcuts.include?( hcut - 1 ) good_hcuts += [hcut] elsif vcuts.include?( hcut - 1 ) potential_hcuts << hcut end else if vcuts.include?( hcut ) good_hcuts += potential_hcuts + [hcut] potential_hcuts.clear else potential_hcuts << hcut end end end check_vc = lambda do |vertical_cuts, opposing_vcuts| # opposing_vcuts is here only to check for blunt cuts, so there shouldn't # be any out-of-order problems with this good_vc = [] vertical_cuts.each { |vc| good_vc << vc if good_hcuts.include?( vc ) or good_hcuts.include?( vc + 1 ) or opposing_vcuts.include?( vc ) } good_vc end @vc_primary = check_vc.call(@vc_primary, @vc_complement) @vc_complement = check_vc.call(@vc_complement, @vc_primary) @hc_between_strands = good_hcuts clean_all end # 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. # def strands_for_display(str1 = nil, str2 = nil, vcp=nil, vcc=nil, hc=nil) return @strands_for_display if @strands_for_display_current vcs = '|' # Vertical cut symbol hcs = '-' # Horizontal cut symbol vhcs = '+' # Intersection of vertical and horizontal cut symbol num_txt_repeat = lambda { num_txt = '0123456789'; (num_txt * ( @size / num_txt.size.to_f ).ceil)[0.. at size-1] } (str1 == nil) ? a = num_txt_repeat.call : a = str1.dup (str2 == nil) ? b = num_txt_repeat.call : b = str2.dup vcp = @vc_primary if vcp==nil vcc = @vc_complement if vcc==nil hc = @hc_between_strands if hc==nil vcuts = (vcp + vcc).uniq.sort vcp.reverse.each { |c| a.insert(c+1, vcs) } vcc.reverse.each { |c| b.insert(c+1, vcs) } between = ' ' * @size hc.each {|hcut| between[hcut,1] = hcs } s_a = add_spacing(a, vcs) s_b = add_spacing(b, vcs) s_bet = add_spacing(between) # NOTE watch this for circular i = 0 0.upto( s_a.size-1 ) do if (s_a[i,1] == vcs) or (s_b[i,1] == vcs) s_bet[i] = vhcs elsif i != 0 and s_bet[i-1,1] == hcs and s_bet[i+1,1] == hcs s_bet[i] = hcs end i+=1 end @strands_for_display_current = true @strands_for_display = [s_a, s_bet, s_b] end ######### protected ######### # remove nil values, remove duplicate values, and # sort @vc_primary, @vc_complement, and @hc_between_strands def clean_all [@vc_primary, @vc_complement, @hc_between_strands].collect { |a| a.delete(nil); a.uniq!; a.sort! } end end # CalculatedCuts end # SequenceRange end # Range end # Bio::RestrictionEnzyme --- NEW FILE: fragment.rb --- # # bio/util/restrction_enzyme/analysis/fragment.rb - # # Author:: Trevor Wennblom # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com) # License:: Distributes under the same terms as Ruby # # $Id: fragment.rb,v 1.1 2007/01/02 00:13:07 trevor Exp $ # require 'pathname' libpath = Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 6, 'lib')).cleanpath.to_s $:.unshift(libpath) unless $:.include?(libpath) require 'bio/util/restriction_enzyme/range/cut_ranges' require 'bio/util/restriction_enzyme/range/horizontal_cut_range' require 'bio' module Bio; end class Bio::RestrictionEnzyme class Range class SequenceRange # # bio/util/restrction_enzyme/analysis/fragment.rb - # # Author:: Trevor Wennblom # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com) # License:: Distributes under the same terms as Ruby # class Fragment attr_reader :size def initialize( primary_bin, complement_bin ) @primary_bin = primary_bin @complement_bin = complement_bin end DisplayFragment = Struct.new(:primary, :complement) def for_display(p_str=nil, c_str=nil) df = DisplayFragment.new df.primary = '' df.complement = '' both_bins = (@primary_bin + @complement_bin).sort.uniq both_bins.each do |item| @primary_bin.include?(item) ? df.primary << p_str[item] : df.primary << ' ' @complement_bin.include?(item) ? df.complement << c_str[item] : df.complement << ' ' end df end end # Fragment end # SequenceRange end # Range end # Bio::RestrictionEnzyme --- NEW FILE: fragments.rb --- # # bio/util/restrction_enzyme/analysis/fragments.rb - # # Author:: Trevor Wennblom # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com) # License:: Distributes under the same terms as Ruby # # $Id: fragments.rb,v 1.1 2007/01/02 00:13:07 trevor Exp $ # require 'pathname' libpath = Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 6, 'lib')).cleanpath.to_s $:.unshift(libpath) unless $:.include?(libpath) module Bio; end class Bio::RestrictionEnzyme class Range class SequenceRange # # bio/util/restrction_enzyme/analysis/fragments.rb - # # Author:: Trevor Wennblom # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com) # License:: Distributes under the same terms as Ruby # class Fragments < Array attr_accessor :primary attr_accessor :complement def initialize(primary, complement) @primary = primary @complement = complement end DisplayFragment = Struct.new(:primary, :complement) def for_display(p_str=nil, c_str=nil) p_str ||= @primary c_str ||= @complement pretty_fragments = [] self.each { |fragment| pretty_fragments << fragment.for_display(p_str, c_str) } pretty_fragments end end # Fragments end # SequenceRange end # Range end # Bio::RestrictionEnzyme From trevor at dev.open-bio.org Mon Jan 1 19:19:08 2007 From: trevor at dev.open-bio.org (Trevor Wennblom) Date: Tue, 02 Jan 2007 00:19:08 +0000 Subject: [BioRuby-cvs] bioruby/lib/bio/util/restriction_enzyme/range/sequence_range calculated_cuts.rb, 1.1, 1.2 fragment.rb, 1.1, 1.2 fragments.rb, 1.1, 1.2 Message-ID: <200701020019.l020J8r2002755@dev.open-bio.org> Update of /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/range/sequence_range In directory dev.open-bio.org:/tmp/cvs-serv2735/range/sequence_range Modified Files: calculated_cuts.rb fragment.rb fragments.rb Log Message: Index: calculated_cuts.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** calculated_cuts.rb 2 Jan 2007 00:13:07 -0000 1.1 --- calculated_cuts.rb 2 Jan 2007 00:19:06 -0000 1.2 *************** *** 1,4 **** # ! # bio/util/restrction_enzyme/analysis/calculated_cuts.rb - # # Author:: Trevor Wennblom --- 1,4 ---- # ! # bio/util/restrction_enzyme/range/sequence_range/calculated_cuts.rb - # # Author:: Trevor Wennblom *************** *** 22,26 **** # ! # bio/util/restrction_enzyme/analysis/calculated_cuts.rb - # # Author:: Trevor Wennblom --- 22,26 ---- # ! # bio/util/restrction_enzyme/range/sequence_range/calculated_cuts.rb - # # Author:: Trevor Wennblom Index: fragment.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/range/sequence_range/fragment.rb,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** fragment.rb 2 Jan 2007 00:13:07 -0000 1.1 --- fragment.rb 2 Jan 2007 00:19:06 -0000 1.2 *************** *** 1,4 **** # ! # bio/util/restrction_enzyme/analysis/fragment.rb - # # Author:: Trevor Wennblom --- 1,4 ---- # ! # bio/util/restrction_enzyme/range/sequence_range/fragment.rb - # # Author:: Trevor Wennblom *************** *** 22,26 **** # ! # bio/util/restrction_enzyme/analysis/fragment.rb - # # Author:: Trevor Wennblom --- 22,26 ---- # ! # bio/util/restrction_enzyme/range/sequence_range/fragment.rb - # # Author:: Trevor Wennblom Index: fragments.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/range/sequence_range/fragments.rb,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** fragments.rb 2 Jan 2007 00:13:07 -0000 1.1 --- fragments.rb 2 Jan 2007 00:19:06 -0000 1.2 *************** *** 18,22 **** # ! # bio/util/restrction_enzyme/analysis/fragments.rb - # # Author:: Trevor Wennblom --- 18,22 ---- # ! # bio/util/restrction_enzyme/range/sequence_range/fragments.rb - # # Author:: Trevor Wennblom From trevor at dev.open-bio.org Mon Jan 1 19:22:29 2007 From: trevor at dev.open-bio.org (Trevor Wennblom) Date: Tue, 02 Jan 2007 00:22:29 +0000 Subject: [BioRuby-cvs] bioruby/test/unit/bio/util/restriction_enzyme/analysis test_calculated_cuts.rb, 1.2, 1.3 test_sequence_range.rb, 1.2, 1.3 Message-ID: <200701020022.l020MT3s002785@dev.open-bio.org> Update of /home/repository/bioruby/bioruby/test/unit/bio/util/restriction_enzyme/analysis In directory dev.open-bio.org:/tmp/cvs-serv2765 Modified Files: test_calculated_cuts.rb test_sequence_range.rb Log Message: Index: test_sequence_range.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/test/unit/bio/util/restriction_enzyme/analysis/test_sequence_range.rb,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_sequence_range.rb 31 Dec 2006 18:46:15 -0000 1.2 --- test_sequence_range.rb 2 Jan 2007 00:22:27 -0000 1.3 *************** *** 14,24 **** require 'test/unit' ! require 'bio/util/restriction_enzyme/analysis/sequence_range' ! require 'bio/util/restriction_enzyme/analysis/fragments' ! require 'bio/util/restriction_enzyme/analysis/cut_range' ! require 'bio/util/restriction_enzyme/analysis/horizontal_cut_range' ! require 'bio/util/restriction_enzyme/analysis/vertical_cut_range' ! require 'bio/util/restriction_enzyme/analysis/cut_ranges' module Bio #:nodoc: --- 14,24 ---- require 'test/unit' ! require 'bio/util/restriction_enzyme/range/sequence_range' ! require 'bio/util/restriction_enzyme/range/sequence_range/fragments' ! require 'bio/util/restriction_enzyme/range/cut_range' ! require 'bio/util/restriction_enzyme/range/horizontal_cut_range' ! require 'bio/util/restriction_enzyme/range/vertical_cut_range' ! require 'bio/util/restriction_enzyme/range/cut_ranges' module Bio #:nodoc: *************** *** 27,37 **** def setup ! @t = Bio::RestrictionEnzyme::Analysis::SequenceRange ! @fs = Bio::RestrictionEnzyme::Analysis::Fragments #a.add_cut_range(p_cut_left, p_cut_right, c_cut_left, c_cut_right ) ! @vcr = Bio::RestrictionEnzyme::Analysis::VerticalCutRange ! @crs = Bio::RestrictionEnzyme::Analysis::CutRanges ! @hcr = Bio::RestrictionEnzyme::Analysis::HorizontalCutRange @obj_1 = @t.new(0,5) --- 27,37 ---- def setup ! @t = Bio::RestrictionEnzyme::Range::SequenceRange ! @fs = Bio::RestrictionEnzyme::Range::SequenceRange::Fragments #a.add_cut_range(p_cut_left, p_cut_right, c_cut_left, c_cut_right ) ! @vcr = Bio::RestrictionEnzyme::Range::VerticalCutRange ! @crs = Bio::RestrictionEnzyme::Range::CutRanges ! @hcr = Bio::RestrictionEnzyme::Range::HorizontalCutRange @obj_1 = @t.new(0,5) Index: test_calculated_cuts.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/test/unit/bio/util/restriction_enzyme/analysis/test_calculated_cuts.rb,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** test_calculated_cuts.rb 31 Dec 2006 18:46:15 -0000 1.2 --- test_calculated_cuts.rb 2 Jan 2007 00:22:27 -0000 1.3 *************** *** 14,22 **** require 'test/unit' ! require 'bio/util/restriction_enzyme/analysis/calculated_cuts' ! require 'bio/util/restriction_enzyme/analysis/cut_range' ! require 'bio/util/restriction_enzyme/analysis/horizontal_cut_range' ! require 'bio/util/restriction_enzyme/analysis/vertical_cut_range' ! require 'bio/util/restriction_enzyme/analysis/cut_ranges' module Bio #:nodoc: --- 14,22 ---- require 'test/unit' ! require 'bio/util/restriction_enzyme/range/sequence_range/calculated_cuts' ! require 'bio/util/restriction_enzyme/range/cut_range' ! require 'bio/util/restriction_enzyme/range/cut_ranges' ! require 'bio/util/restriction_enzyme/range/horizontal_cut_range' ! require 'bio/util/restriction_enzyme/range/vertical_cut_range' module Bio #:nodoc: *************** *** 25,32 **** def setup ! @t = Bio::RestrictionEnzyme::Analysis::CalculatedCuts ! @vcr = Bio::RestrictionEnzyme::Analysis::VerticalCutRange ! @crs = Bio::RestrictionEnzyme::Analysis::CutRanges ! @hcr = Bio::RestrictionEnzyme::Analysis::HorizontalCutRange #a.add_cut_range(p_cut_left, p_cut_right, c_cut_left, c_cut_right ) --- 25,32 ---- def setup ! @t = Bio::RestrictionEnzyme::Range::SequenceRange::CalculatedCuts ! @vcr = Bio::RestrictionEnzyme::Range::VerticalCutRange ! @crs = Bio::RestrictionEnzyme::Range::CutRanges ! @hcr = Bio::RestrictionEnzyme::Range::HorizontalCutRange #a.add_cut_range(p_cut_left, p_cut_right, c_cut_left, c_cut_right ) From trevor at dev.open-bio.org Tue Jan 2 01:18:09 2007 From: trevor at dev.open-bio.org (Trevor Wennblom) Date: Tue, 02 Jan 2007 06:18:09 +0000 Subject: [BioRuby-cvs] bioruby/test/unit/bio/util/restriction_enzyme/analysis test_cut_ranges.rb, NONE, 1.1 Message-ID: <200701020618.l026I9Lc003133@dev.open-bio.org> Update of /home/repository/bioruby/bioruby/test/unit/bio/util/restriction_enzyme/analysis In directory dev.open-bio.org:/tmp/cvs-serv3107/restriction_enzyme/analysis Added Files: test_cut_ranges.rb Log Message: --- NEW FILE: test_cut_ranges.rb --- # # test/unit/bio/util/restriction_enzyme/analysis/test_cut_ranges.rb - Unit test for Bio::RestrictionEnzyme::Analysis::SequenceRange # # Author:: Trevor Wennblom # Copyright:: Copyright (c) 2005-2007 Midwinter Laboratories, LLC (http://midwinterlabs.com) # License:: Distributes under the same terms as Ruby # # $Id: test_cut_ranges.rb,v 1.1 2007/01/02 06:18:07 trevor Exp $ # require 'pathname' libpath = Pathname.new(File.join(File.dirname(__FILE__), ['..'] * 6, 'lib')).cleanpath.to_s $:.unshift(libpath) unless $:.include?(libpath) require 'test/unit' require 'bio/util/restriction_enzyme/range/sequence_range' require 'bio/util/restriction_enzyme/range/sequence_range/fragments' require 'bio/util/restriction_enzyme/range/cut_range' require 'bio/util/restriction_enzyme/range/horizontal_cut_range' require 'bio/util/restriction_enzyme/range/vertical_cut_range' require 'bio/util/restriction_enzyme/range/cut_ranges' module Bio #:nodoc: class TestCutRanges < Test::Unit::TestCase #:nodoc: def setup @t = Bio::RestrictionEnzyme::Range::SequenceRange @fs = Bio::RestrictionEnzyme::Range::SequenceRange::Fragments #a.add_cut_range(p_cut_left, p_cut_right, c_cut_left, c_cut_right ) @vcr = Bio::RestrictionEnzyme::Range::VerticalCutRange @crs = Bio::RestrictionEnzyme::Range::CutRanges @hcr = Bio::RestrictionEnzyme::Range::HorizontalCutRange @obj_2 = @crs.new( [@vcr.new(0,2,nil,nil), @vcr.new(3,nil,4,nil)] ) @obj_3 = @crs.new( [@vcr.new(0,2,nil,nil), @vcr.new(3,nil,4,nil), @hcr.new(0), @hcr.new(5)] ) @obj_7 = @crs.new( [@vcr.new(nil,2,nil,nil), @hcr.new(0,2)] ) @obj_z = @crs.new( [@vcr.new(nil,2,nil,5), @hcr.new(1,6)] ) end def test_obj_z assert_equal(6, @obj_z.max) assert_equal(1, @obj_z.min) assert_equal(2, @obj_z.min_vertical) assert_equal(5, @obj_z.max_vertical) assert_equal(true, @obj_z.include?(6)) assert_equal(true, @obj_z.include?(4)) assert_equal(true, @obj_z.include?(2)) assert_equal(false, @obj_z.include?(-1)) assert_equal(false, @obj_z.include?(0)) assert_equal(false, @obj_z.include?(7)) end def test_obj_7 assert_equal(2, @obj_7.max) assert_equal(0, @obj_7.min) assert_equal(2, @obj_7.min_vertical) assert_equal(2, @obj_7.max_vertical) assert_equal(true, @obj_7.include?(0)) assert_equal(true, @obj_7.include?(1)) assert_equal(true, @obj_7.include?(2)) assert_equal(false, @obj_7.include?(-1)) assert_equal(false, @obj_7.include?(3)) end def test_obj_2 assert_equal(4, @obj_2.max) assert_equal(0, @obj_2.min) assert_equal(0, @obj_2.min_vertical) assert_equal(4, @obj_2.max_vertical) assert_equal(true, @obj_2.include?(0)) assert_equal(true, @obj_2.include?(1)) assert_equal(true, @obj_2.include?(3)) assert_equal(true, @obj_2.include?(4)) assert_equal(false, @obj_2.include?(-1)) assert_equal(false, @obj_2.include?(5)) end def test_obj_3 assert_equal(5, @obj_3.max) assert_equal(0, @obj_3.min) assert_equal(0, @obj_3.min_vertical) assert_equal(4, @obj_3.max_vertical) assert_equal(true, @obj_3.include?(0)) assert_equal(true, @obj_3.include?(1)) assert_equal(true, @obj_3.include?(3)) assert_equal(true, @obj_3.include?(4)) assert_equal(true, @obj_3.include?(5)) assert_equal(false, @obj_3.include?(-1)) assert_equal(false, @obj_3.include?(6)) end end end From trevor at dev.open-bio.org Tue Jan 2 01:18:09 2007 From: trevor at dev.open-bio.org (Trevor Wennblom) Date: Tue, 02 Jan 2007 06:18:09 +0000 Subject: [BioRuby-cvs] bioruby/test/unit/bio/util/restriction_enzyme test_analysis.rb, 1.4, 1.5 test_double_stranded.rb, 1.3, 1.4 Message-ID: <200701020618.l026I96E003129@dev.open-bio.org> Update of /home/repository/bioruby/bioruby/test/unit/bio/util/restriction_enzyme In directory dev.open-bio.org:/tmp/cvs-serv3107/restriction_enzyme Modified Files: test_analysis.rb test_double_stranded.rb Log Message: Index: test_double_stranded.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/test/unit/bio/util/restriction_enzyme/test_double_stranded.rb,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** test_double_stranded.rb 1 Jan 2007 02:16:05 -0000 1.3 --- test_double_stranded.rb 2 Jan 2007 06:18:07 -0000 1.4 *************** *** 35,39 **** @obj_7 = @t.new('garraxt', @cl.new(3,2), @cl.new(9,11)) ! @obj_8 = @t.new('garraxt', 3..2, 9..11) @obj_9 = @t.new('garraxt', [3,2], [9,11]) --- 35,39 ---- @obj_7 = @t.new('garraxt', @cl.new(3,2), @cl.new(9,11)) ! # @obj_8 = @t.new('garraxt', 3..2, 9..11) @obj_9 = @t.new('garraxt', [3,2], [9,11]) *************** *** 57,61 **** assert_equal('gar^raxtnn^n', @obj_7.primary.with_cut_symbols) ! assert_equal('gar^raxtnn^n', @obj_8.primary.with_cut_symbols) assert_equal('gar^raxtnn^n', @obj_9.primary.with_cut_symbols) --- 57,61 ---- assert_equal('gar^raxtnn^n', @obj_7.primary.with_cut_symbols) ! # assert_equal('gar^raxtnn^n', @obj_8.primary.with_cut_symbols) assert_equal('gar^raxtnn^n', @obj_9.primary.with_cut_symbols) *************** *** 75,79 **** assert_equal('ct^yytxannnn^n', @obj_7.complement.with_cut_symbols) ! assert_equal('ct^yytxannnn^n', @obj_8.complement.with_cut_symbols) assert_equal('ct^yytxannnn^n', @obj_9.complement.with_cut_symbols) --- 75,79 ---- assert_equal('ct^yytxannnn^n', @obj_7.complement.with_cut_symbols) ! # assert_equal('ct^yytxannnn^n', @obj_8.complement.with_cut_symbols) assert_equal('ct^yytxannnn^n', @obj_9.complement.with_cut_symbols) Index: test_analysis.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/test/unit/bio/util/restriction_enzyme/test_analysis.rb,v retrieving revision 1.4 retrieving revision 1.5 diff -C2 -d -r1.4 -r1.5 *** test_analysis.rb 31 Dec 2006 18:46:14 -0000 1.4 --- test_analysis.rb 2 Jan 2007 06:18:07 -0000 1.5 *************** *** 31,34 **** --- 31,36 ---- @obj_4 = @t.cut('atgcatgcatgc', e1) + @obj_4bd = @t.cut('atgcatgcatgccccc', e1, 'cc^c') + e2 = @enz.new('atgcatgc', [3,5]) @obj_5 = @t.cut('atgcatgcatgc', e2) *************** *** 39,42 **** --- 41,47 ---- @obj_7 = @t.cut('gaccaggaaaaagaccaggaaagcctggaaaagttaac', 'EcoRII') + @obj_7b = @t.cut('gaccaggaaaaagaccaggaaagcctggaaaagttaaccc', 'EcoRII', 'HincII', 'cc^c') + @obj_7bd = @t.cut_without_permutations('gaccaggaaaaagaccaggaaagcctggaaaagttaaccc', 'EcoRII', 'HincII', 'cc^c') + @obj_8 = @t.cut('gaccaggaaaaagaccaggaaagcctggaaaagttaac', 'EcoRII', 'HincII') *************** *** 76,83 **** --- 81,105 ---- assert_equal(["ag", "agt", "cag"], @obj_3.primary) assert_equal(["atg", "atgcatg", "catg", "catgc"], @obj_4.primary) + =begin + A T G^C A T G C + + A T G C A T G C A T G C + + A T G^C A T G^C A T G C + + A T G C A T G^C A T G C + =end + + + e1 = @enz.new('atgcatgc', [3,3]) + @obj_4 = @t.cut('atgcatgcatgc', e1) + assert_equal(["atg", "atgcatg", "catgc", "catgcatgc"], @obj_5.primary) assert_equal(["a", "ag", "g", "ga"], @obj_6.primary) assert_equal(["ccaggaaaaaga", "ccaggaaag", "cctggaaaagttaac", "ga"], @obj_7.primary) assert_equal(["aac", "ccaggaaaaaga", "ccaggaaag", "cctggaaaagtt", "ga"], @obj_8.primary) + + assert_equal(["atg", "atgcatg", "c", "catg", "catgcc", "catgccc", "cc", "cc"], @obj_4bd.primary) + assert_equal(["gg", "gg", "ggg", "gtac", "gtacg", "gtacgg", "tac", "tacgtac"], @obj_4bd.complement) end From trevor at dev.open-bio.org Tue Jan 2 01:18:40 2007 From: trevor at dev.open-bio.org (Trevor Wennblom) Date: Tue, 02 Jan 2007 06:18:40 +0000 Subject: [BioRuby-cvs] bioruby/lib/bio/util/restriction_enzyme/range cut_ranges.rb, 1.1, 1.2 horizontal_cut_range.rb, 1.1, 1.2 Message-ID: <200701020618.l026IeZg003178@dev.open-bio.org> Update of /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/range In directory dev.open-bio.org:/tmp/cvs-serv3143/restriction_enzyme/range Modified Files: cut_ranges.rb horizontal_cut_range.rb Log Message: Index: horizontal_cut_range.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/range/horizontal_cut_range.rb,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** horizontal_cut_range.rb 2 Jan 2007 00:13:07 -0000 1.1 --- horizontal_cut_range.rb 2 Jan 2007 06:18:38 -0000 1.2 *************** *** 54,60 **** @c_cut_left = nil @c_cut_right = nil ! @min = nil ! @max = nil ! @range = nil @hcuts = (left..right) --- 54,61 ---- @c_cut_left = nil @c_cut_right = nil ! @min = left # NOTE this used to be 'nil', make sure all tests work ! @max = right # NOTE this used to be 'nil', make sure all tests work ! @range = (@min.. at max) unless @min == nil or @max == nil # NOTE this used to be 'nil', make sure all tests work ! @hcuts = (left..right) Index: cut_ranges.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/range/cut_ranges.rb,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** cut_ranges.rb 2 Jan 2007 00:13:07 -0000 1.1 --- cut_ranges.rb 2 Jan 2007 06:18:38 -0000 1.2 *************** *** 29,32 **** --- 29,53 ---- def max; self.collect{|a| a.max}.flatten.sort.last; end def include?(i); self.collect{|a| a.include?(i)}.include?(true); end + + def min_vertical + vertical_min_max_helper( :min ) + end + + def max_vertical + vertical_min_max_helper( :max ) + end + + protected + + def vertical_min_max_helper( sym_which ) + tmp = [] + self.each do |a| + next unless a.class == Bio::RestrictionEnzyme::Range::VerticalCutRange + tmp << a.send( sym_which ) + end + z = (sym_which == :max) ? :last : :first + tmp.flatten.sort.send(z) + end + end # CutRanges end # Range From trevor at dev.open-bio.org Tue Jan 2 01:18:40 2007 From: trevor at dev.open-bio.org (Trevor Wennblom) Date: Tue, 02 Jan 2007 06:18:40 +0000 Subject: [BioRuby-cvs] bioruby/lib/bio/util/restriction_enzyme analysis.rb, 1.9, 1.10 analysis_basic.rb, 1.2, 1.3 Message-ID: <200701020618.l026IeDC003167@dev.open-bio.org> Update of /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme In directory dev.open-bio.org:/tmp/cvs-serv3143/restriction_enzyme Modified Files: analysis.rb analysis_basic.rb Log Message: Index: analysis_basic.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/analysis_basic.rb,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** analysis_basic.rb 2 Jan 2007 00:13:07 -0000 1.2 --- analysis_basic.rb 2 Jan 2007 06:18:38 -0000 1.3 *************** *** 81,137 **** tmp = create_enzyme_actions( sequence, *args ) ! enzyme_actions = tmp[0].merge(tmp[1]) ! sr_with_cuts = Bio::RestrictionEnzyme::Range::SequenceRange.new( 0, 0, sequence.size-1, sequence.size-1 ) ! enzyme_actions.each do |id, enzyme_action| enzyme_action.cut_ranges.each do |cut_range| ! sr_with_cuts.add_cut_range(cut_range) end end ! sr_with_cuts.fragments.primary = sequence ! sr_with_cuts.fragments.complement = sequence.forward_complement ! unique_fragments_for_display( {0 => sr_with_cuts} ) end - ######### - protected - ######### - UniqueFragment = Struct.new(:primary, :complement) class UniqueFragments < Array ! def primary ! tmp = [] ! self.each { |uf| tmp << uf.primary } ! tmp.sort.map { |e| e.tr(' ', '') } ! end ! def complement ! tmp = [] ! self.each { |uf| tmp << uf.complement } ! tmp.sort.map { |e| e.tr(' ', '') } end end - def unique_fragments_for_display( hash_of_sequence_ranges_with_cuts ) - uf_ary = UniqueFragments.new - return uf_ary if hash_of_sequence_ranges_with_cuts == nil or hash_of_sequence_ranges_with_cuts.empty? - - hash_of_sequence_ranges_with_cuts.each do |permutation, sr_with_cuts| - sr_with_cuts.fragments.for_display.each do |fragment| - uf = UniqueFragment.new - uf.primary = fragment.primary - uf.complement = fragment.complement ! duplicate = false ! uf_ary.each do |element| ! if (uf.primary == element.primary) and (uf.complement == element.complement) ! duplicate = true ! break ! end ! end ! uf_ary << uf unless duplicate end end uf_ary end --- 81,130 ---- tmp = create_enzyme_actions( sequence, *args ) ! #enzyme_actions = tmp[0].merge(tmp[1]) ! enzyme_actions = tmp[0] + tmp[1] ! sequence_range = Bio::RestrictionEnzyme::Range::SequenceRange.new( 0, 0, sequence.size-1, sequence.size-1 ) ! enzyme_actions.each do |enzyme_action| enzyme_action.cut_ranges.each do |cut_range| ! sequence_range.add_cut_range(cut_range) end end ! sequence_range.fragments.primary = sequence ! sequence_range.fragments.complement = sequence.forward_complement ! unique_fragments_for_display( {0 => sequence_range} ) end UniqueFragment = Struct.new(:primary, :complement) + class UniqueFragments < Array ! def primary; strip_and_sort(:primary); end ! def complement; strip_and_sort(:complement); end ! ! protected ! ! def strip_and_sort( sym_strand ) ! self.map {|uf| uf.send( sym_strand ).tr(' ', '') }.sort end end + + ######### + protected + ######### ! # * +hsh+: +Hash+ Key is a permutation ID, if any. Value is SequenceRange object that has cuts. ! # ! def unique_fragments_for_display( hsh ) ! uf_ary = UniqueFragments.new ! return uf_ary if hsh == nil ! hsh.each do |permutation_id, sequence_range| ! sequence_range.fragments.for_display.each do |fragment| ! # NOTE might not need tr here ! uf_ary << UniqueFragment.new(fragment.primary.tr(' ', ''), fragment.complement.tr(' ', '')) end end + uf_ary.uniq! uf_ary end *************** *** 142,193 **** # +args+:: The enzymes to use. def create_enzyme_actions( sequence, *args ) ! id = 0 ! enzyme_actions_that_sometimes_cut = {} ! enzyme_actions_that_always_cut = {} ! indicies_of_sometimes_cut = [] ! args.each do |enzyme| enzyme = Bio::RestrictionEnzyme.new(enzyme) unless enzyme.class == Bio::RestrictionEnzyme::DoubleStranded find_match_locations( sequence, enzyme.primary.to_re ).each do |offset| ! #enzyme_actions_that_always_cut[id] = enzyme_to_enzyme_action( enzyme, offset ) ! enzyme_actions_that_always_cut[id] = enzyme.create_action_at( offset ) ! id += 1 end end # enzyme_actions_that_always_cut may lose members, the members to be lost are recorded in indicies_of_sometimes_cut ! max = enzyme_actions_that_always_cut.size - 1 ! 0.upto(max) do |i| ! enzyme_action = enzyme_actions_that_always_cut[i] conflict = false other_cut_ranges = {} - enzyme_actions_that_always_cut.each { |key,i_ea| next if i == key; other_cut_ranges[key] = i_ea.cut_ranges } other_cut_ranges.each do |key, cut_ranges| cut_ranges.each do |cut_range| next unless cut_range.class == Bio::RestrictionEnzyme::Range::VerticalCutRange # we aren't concerned with horizontal cuts ! previous_cut_left = cut_range.range.first ! previous_cut_right = cut_range.range.last ! if (enzyme_action.right <= previous_cut_left) or ! (enzyme_action.left > previous_cut_right) or ! (enzyme_action.left > previous_cut_left and enzyme_action.right <= previous_cut_right) # in between cuts # no conflict else conflict = true end ! ! indicies_of_sometimes_cut += [i, key] if conflict == true end end end ! indicies_of_sometimes_cut.uniq.each do |i| ! enzyme_actions_that_sometimes_cut[i] = enzyme_actions_that_always_cut[i] ! enzyme_actions_that_always_cut.delete(i) ! end ! ! [enzyme_actions_that_sometimes_cut, enzyme_actions_that_always_cut] end --- 135,209 ---- # +args+:: The enzymes to use. def create_enzyme_actions( sequence, *args ) ! require 'set' ! always_cut = [] ! indicies_of_sometimes_cut = Set.new ! args.each do |enzyme| enzyme = Bio::RestrictionEnzyme.new(enzyme) unless enzyme.class == Bio::RestrictionEnzyme::DoubleStranded + find_match_locations( sequence, enzyme.primary.to_re ).each do |offset| ! always_cut << enzyme.create_action_at( offset ) end end + + # VerticalCutRange should really be called VerticalAndHorizontalCutRange + + # * always_cut is now full of EnzymeActions at specific locations across + # the sequence. + # * always_cut will now be examined to see if any EnzymeActions may + # conflict with one another, and if they do they'll be made note of in + # indicies_of_sometimes_cut. They will then be remove FIXME + # * a conflict occurs if another enzyme's bind site is compromised do due + # to another enzyme's cut. Enzyme's bind sites may overlap and not be + # competitive, however neither bind site may be part of the other + # enzyme's cut or else they do become competitive. + # * note that a small enzyme may possibly cut inbetween two cuts far apart + # made by a larger enzyme, this would be a "sometimes" cut since it's + # not guaranteed that the larger enzyme will cut first, therefore there + # is competition. + + dirty = Set.new + =begin + always_cut.each_with_index do |ea, index| + + end + =end # enzyme_actions_that_always_cut may lose members, the members to be lost are recorded in indicies_of_sometimes_cut ! always_cut.each_with_index do |ea, index1| conflict = false other_cut_ranges = {} + always_cut.each_with_index do |i_ea, index2| + next if index1 == index2 + other_cut_ranges[index2] = i_ea.cut_ranges + end + other_cut_ranges.each do |key, cut_ranges| + cut_ranges.each do |cut_range| next unless cut_range.class == Bio::RestrictionEnzyme::Range::VerticalCutRange # we aren't concerned with horizontal cuts ! previous_cut_left, previous_cut_right = cut_range.min, cut_range.max ! if (ea.right <= previous_cut_left) or ! (ea.left > previous_cut_right) or ! (ea.left > previous_cut_left and ea.right <= previous_cut_right) # in-between cuts # no conflict else conflict = true end ! indicies_of_sometimes_cut += [index1, key] if conflict == true end end end + + sometimes_cut = always_cut.values_at( *indicies_of_sometimes_cut ) + always_cut.delete_if {|x| sometimes_cut.include? x } ! #puts "Sometimes cut: #{sometimes_cut.size}" ! #puts "Always cut: #{always_cut.size}" ! #puts ! [sometimes_cut, always_cut] end Index: analysis.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/analysis.rb,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** analysis.rb 2 Jan 2007 00:13:07 -0000 1.9 --- analysis.rb 2 Jan 2007 06:18:38 -0000 1.10 *************** *** 40,45 **** def cut( sequence, *args ) return nil if !sequence.kind_of?(String) or sequence.empty? ! hash_of_sequence_ranges_with_cuts = cut_and_return_by_permutations( sequence, *args ) ! unique_fragments_for_display( hash_of_sequence_ranges_with_cuts ) end --- 40,44 ---- def cut( sequence, *args ) return nil if !sequence.kind_of?(String) or sequence.empty? ! unique_fragments_for_display( cut_and_return_by_permutations( sequence, *args ) ) end *************** *** 51,121 **** return {} if !sequence.kind_of?(String) or sequence.empty? sequence = Bio::Sequence::NA.new( sequence ) enzyme_actions, initial_cuts = create_enzyme_actions( sequence, *args ) ! return {} if enzyme_actions.empty? and initial_cuts.empty? if enzyme_actions.size > 1 permutations = permute(enzyme_actions.size) ! else ! permutations = [] ! end ! ! # Indexed by permutation. ! hash_of_sequence_ranges_with_cuts = {} ! ! if permutations.empty? ! sr_with_cuts = Bio::RestrictionEnzyme::Range::SequenceRange.new( 0, 0, sequence.size-1, sequence.size-1 ) ! initial_cuts.each { |key, enzyme_action| enzyme_action.cut_ranges.each { |cut_range| sr_with_cuts.add_cut_range(cut_range) } } ! hash_of_sequence_ranges_with_cuts[0] = sr_with_cuts ! end ! ! permutations.each do |permutation| ! previous_cut_ranges = [] ! sr_with_cuts = Bio::RestrictionEnzyme::Range::SequenceRange.new( 0, 0, sequence.size-1, sequence.size-1 ) ! initial_cuts.each { |enzyme_action| enzyme_action.cut_ranges.each { |cut_range| sr_with_cuts.add_cut_range(cut_range) } } ! permutation.each do |id| ! enzyme_action = enzyme_actions[id] ! # conflict is false if the current enzyme action may cut in it's range. ! # conflict is true if it cannot do to a previous enzyme action making ! # a cut where this enzyme action needs a whole recognition site. ! conflict = false ! # If current size of enzyme_action overlaps with previous cut_range, don't cut ! # note that the enzyme action may fall in the middle of a previous enzyme action ! # so all cut locations must be checked that would fall underneath. ! previous_cut_ranges.each do |cut_range| ! next unless cut_range.class == Bio::RestrictionEnzyme::Range::VerticalCutRange # we aren't concerned with horizontal cuts ! previous_cut_left = cut_range.range.first ! previous_cut_right = cut_range.range.last ! # Keep in mind: ! # * The cut location is to the immediate right of the base located at the index. ! # ex: at^gc -- the cut location is at index 1 ! # * The enzyme action location is located at the base of the index. ! # ex: atgc -- 0 => 'a', 1 => 't', 2 => 'g', 3 => 'c' ! if (enzyme_action.right <= previous_cut_left) or ! (enzyme_action.left > previous_cut_right) or ! (enzyme_action.left > previous_cut_left and enzyme_action.right <= previous_cut_right) # in between cuts ! # no conflict ! else ! conflict = true end end ! next if conflict == true ! enzyme_action.cut_ranges.each { |cut_range| sr_with_cuts.add_cut_range(cut_range) } ! previous_cut_ranges += enzyme_action.cut_ranges end ! hash_of_sequence_ranges_with_cuts[permutation] = sr_with_cuts ! end ! hash_of_sequence_ranges_with_cuts.each do |permutation, sr_with_cuts| ! sr_with_cuts.fragments.primary = sequence ! sr_with_cuts.fragments.complement = sequence.forward_complement end ! hash_of_sequence_ranges_with_cuts end --- 50,129 ---- return {} if !sequence.kind_of?(String) or sequence.empty? sequence = Bio::Sequence::NA.new( sequence ) + sequence.freeze + + # +Hash+ Key is permutation ID, value is SequenceRange + my_hash = {} + enzyme_actions, initial_cuts = create_enzyme_actions( sequence, *args ) ! return my_hash if enzyme_actions.empty? and initial_cuts.empty? if enzyme_actions.size > 1 permutations = permute(enzyme_actions.size) ! ! permutations.each do |permutation| ! previous_cut_ranges = [] ! sequence_range = Bio::RestrictionEnzyme::Range::SequenceRange.new( 0, ! 0, ! sequence.size-1, ! sequence.size-1 ) ! ! initial_cuts.each { |enzyme_action| ! raise initial_cuts.inspect ! ! enzyme_action.cut_ranges.each { |cut_range| ! sequence_range.add_cut_range(cut_range) } } ! permutation.each do |id| ! enzyme_action = enzyme_actions[id] ! # conflict is false if the current enzyme action may cut in it's range. ! # conflict is true if it cannot due to a previous enzyme action making ! # a cut where this enzyme action needs a whole recognition site. ! conflict = false ! # If current size of enzyme_action overlaps with previous cut_range, don't cut ! # note that the enzyme action may fall in the middle of a previous enzyme action ! # so all cut locations must be checked that would fall underneath. ! previous_cut_ranges.each do |cut_range| ! next unless cut_range.class == Bio::RestrictionEnzyme::Range::VerticalCutRange # we aren't concerned with horizontal cuts ! previous_cut_left = cut_range.range.first ! previous_cut_right = cut_range.range.last ! # Keep in mind: ! # * The cut location is to the immediate right of the base located at the index. ! # ex: at^gc -- the cut location is at index 1 ! # * The enzyme action location is located at the base of the index. ! # ex: atgc -- 0 => 'a', 1 => 't', 2 => 'g', 3 => 'c' ! if (enzyme_action.right <= previous_cut_left) or ! (enzyme_action.left > previous_cut_right) or ! (enzyme_action.left > previous_cut_left and enzyme_action.right <= previous_cut_right) # in between cuts ! # no conflict ! else ! conflict = true ! end end + + next if conflict == true + enzyme_action.cut_ranges.each { |cut_range| sequence_range.add_cut_range(cut_range) } + previous_cut_ranges += enzyme_action.cut_ranges end ! sequence_range.fragments.primary = sequence ! sequence_range.fragments.complement = sequence.forward_complement ! my_hash[permutation] = sequence_range end + + else # !if enzyme_actions.size > 1 + sequence_range = Bio::RestrictionEnzyme::Range::SequenceRange.new( 0, 0, sequence.size-1, sequence.size-1 ) ! #initial_cuts.each { |key, enzyme_action| enzyme_action.cut_ranges.each { |cut_range| sequence_range.add_cut_range(cut_range) } } ! initial_cuts.each { |enzyme_action| enzyme_action.cut_ranges.each { |cut_range| sequence_range.add_cut_range(cut_range) } } ! sequence_range.fragments.primary = sequence ! sequence_range.fragments.complement = sequence.forward_complement ! my_hash[0] = sequence_range end ! my_hash end From trevor at dev.open-bio.org Tue Jan 2 01:18:40 2007 From: trevor at dev.open-bio.org (Trevor Wennblom) Date: Tue, 02 Jan 2007 06:18:40 +0000 Subject: [BioRuby-cvs] bioruby/lib/bio/util/restriction_enzyme/double_stranded cut_location_pair.rb, 1.3, 1.4 Message-ID: <200701020618.l026IeVN003173@dev.open-bio.org> Update of /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/double_stranded In directory dev.open-bio.org:/tmp/cvs-serv3143/restriction_enzyme/double_stranded Modified Files: cut_location_pair.rb Log Message: Index: cut_location_pair.rb =================================================================== RCS file: /home/repository/bioruby/bioruby/lib/bio/util/restriction_enzyme/double_stranded/cut_location_pair.rb,v retrieving revision 1.3 retrieving revision 1.4 diff -C2 -d -r1.3 -r1.4 *** cut_location_pair.rb 1 Jan 2007 05:07:04 -0000 1.3 --- cut_location_pair.rb 2 Jan 2007 06:18:38 -0000 1.4 *************** *** 63,67 **** a,b = init_with_array( pair[0] ) ! elsif pair[0].kind_of? Range a,b = init_with_array( [pair[0].first, pair[0].last] ) --- 63,67 ---- a,b = init_with_array( pair[0] ) ! elsif pair[0].kind_of? Range # FIXME This seems to be broken? Check tests a,b = init_with_array( [pair[0].first, pair[0].last] ) *************** *** 70,74