From: martinahansen Date: Wed, 16 Nov 2011 10:18:46 +0000 (+0000) Subject: fixed bug in backtrack.rb X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=1c274f17348ce904feb33a8f084993bdc4659d37;p=biopieces.git fixed bug in backtrack.rb git-svn-id: http://biopieces.googlecode.com/svn/trunk@1651 74ccb610-7750-0410-82ae-013aeee3265d --- diff --git a/code_ruby/lib/maasha/backtrack.rb b/code_ruby/lib/maasha/backtrack.rb index d920d8e..acc5b8c 100644 --- a/code_ruby/lib/maasha/backtrack.rb +++ b/code_ruby/lib/maasha/backtrack.rb @@ -24,10 +24,15 @@ require 'inline' +# Error class for all exceptions to do with BackTrack. +class BackTrackError < StandardError; end + # Module containing code to locate nucleotide patterns in sequences allowing for # ambiguity codes and a given maximum mismatches, insertions, and deletions. The # pattern match engine is based on a backtrack algorithm. module BackTrack + OK_PATTERN = Regexp.new('^[flsycwphqrimtnkvadegu]+$') + # ------------------------------------------------------------------------------ # str.scan(pattern[, max_mismatches [, max_insertions [,max_deletions]]]) # -> Array @@ -42,6 +47,7 @@ module BackTrack # deletions. Matches found in block context return the Match object. Otherwise # matches are returned in an Array of Match objects. def patscan(pattern, offset = 0, max_mismatches = 0, max_insertions = 0, max_deletions = 0) + raise BackTrackError, "Bad pattern: #{pattern}" unless pattern.downcase =~ OK_PATTERN matches = [] if block_given? @@ -113,7 +119,7 @@ module BackTrack # Find all occurrences of p starting at pos in s, with at most # mm mismatches, ins insertions and del deletions. builder.c %{ - static VALUE track(char* p, int pos, int mm, int ins, int del) + static VALUE track(char* p, unsigned int pos, int mm, int ins, int del) { VALUE seq = rb_ivar_get(self, id_seq); char* s = StringValuePtr(seq); @@ -121,22 +127,27 @@ module BackTrack unsigned int e; VALUE tuple; - while (*s && pos) ++s, --pos; // Fast forward until pos - - while (*s) + if (pos < strlen(s)) { - e = backtrack(ss, s, p, mm, ins, del); + s += pos; - if (e) + while (*s) { - tuple = rb_ary_new(); - rb_ary_push(tuple, INT2FIX((int) (s - ss))); - rb_ary_push(tuple, INT2FIX((int) e - (s - ss))); - return tuple; - } + e = backtrack(ss, s, p, mm, ins, del); - s++; + if (e) + { + tuple = rb_ary_new(); + rb_ary_push(tuple, INT2FIX((int) (s - ss))); + rb_ary_push(tuple, INT2FIX((int) e - (s - ss))); + return tuple; + } + + s++; + } } + + return Qnil; } } end diff --git a/code_ruby/test/maasha/test_backtrack.rb b/code_ruby/test/maasha/test_backtrack.rb index 0ffda09..2c271aa 100644 --- a/code_ruby/test/maasha/test_backtrack.rb +++ b/code_ruby/test/maasha/test_backtrack.rb @@ -35,8 +35,44 @@ class BackTrackTest < Test::Unit::TestCase @seq = Seq.new("test", "tacgatgctagcatgcacg") end + def test_BackTrack_patscan_with_bad_pattern_raises + ["", "X", "1"].each { |pattern| + assert_raise(BackTrackError) { @seq.patscan(pattern) } + } + end + + def test_BackTrack_patscan_with_OK_pattern_dont_raise + ["N"].each { |pattern| + assert_nothing_raised { @seq.patscan(pattern) } + } + end + + def test_BackTrack_patscan_with_bad_pos_raises + end + + def test_BackTrack_patscan_with_OK_pos_dont_raise + end + + def test_BackTrack_patscan_with_bad_mis_raises + end + + def test_BackTrack_patscan_with_OK_mis_dont_raise + end + + def test_BackTrack_patscan_with_bad_ins_raises + end + + def test_BackTrack_patscan_with_OK_ins_dont_raise + end + + def test_BackTrack_patscan_with_bad_del_raises + end + + def test_BackTrack_patscan_with_OK_del_dont_raise + end + def test_BackTrack_patscan - assert_equal("0:4:tacg", @seq.patscan("tacg").first.to_s) +# assert_equal("0:4:tacg", @seq.patscan("TACG").first.to_s) end end