more work on seq_span
authorDiane Trout <diane@caltech.edu>
Tue, 4 Sep 2007 22:35:50 +0000 (22:35 +0000)
committerDiane Trout <diane@caltech.edu>
Tue, 4 Sep 2007 22:35:50 +0000 (22:35 +0000)
One problem that showed up was that if a SeqSpan is created on the stack,
the parent shared pointer wont work, so any subseqs will crash.

To fix that at the python layer I had to add a factory function that
proprely dynamically created a SeqSpan.

I tried to get the parent call to work but that kept returning a new object
which makes the python is function unhappy.

alg/test/test_seq_span.cpp
py/seq_span.cpp
py/test/TestSeqSpan.py

index 49558677cff21f2270a54e62a1cabe4df565c644..c71382ece05f53f13aa98f76a43f49e9d494780b 100644 (file)
@@ -107,6 +107,25 @@ BOOST_AUTO_TEST_CASE( seqspan_equality )
   BOOST_CHECK_EQUAL(SeqSpan::isFamily(*span2, *span3), false);
 }
 
+BOOST_AUTO_TEST_CASE( seqspan_parents )
+{
+  std::string str1("AAGGCCTT");
+  std::string str2("AACCGGTT");
+  SeqSpanRef s1(new SeqSpan(str1));
+  SeqSpanRef s1_1 = s1->subseq(2,4);
+  SeqSpanRef s2(new SeqSpan(str2));
+  SeqSpanRef s2_1 = s2->subseq(0,2);
+
+  BOOST_CHECK_EQUAL(s1, s1_1->parent());
+  BOOST_CHECK_EQUAL(s2, s2_1->parent());
+  BOOST_CHECK(s1 != s2_1->parent());
+  BOOST_CHECK(s2 != s1_1->parent());
+
+  SeqSpanRef s2_copy = s2;
+
+  BOOST_CHECK_EQUAL(s2_copy, s2_1->parent());
+}
+
 BOOST_AUTO_TEST_CASE( seqspan_find_first_not_of )
 {
   std::string str1("AAAAT");
@@ -417,4 +436,5 @@ BOOST_AUTO_TEST_CASE( seqspan_strand_plusminus )
   BOOST_CHECK_EQUAL(seq2->sequence(), "AAAA");
   SeqSpanRef seq3 = seq1->subseq(0,4,SeqSpan::MinusStrand); 
   BOOST_CHECK_EQUAL(seq3->sequence(), "TTTT");
-}
\ No newline at end of file
+}
+
index aa484c99ddba1a965f16eaa122a08e3974a0544f..d3e0b5b9bcb1563ebb162f08912e910447dfaabd 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <boost/python.hpp>
 #include <boost/python/return_value_policy.hpp>
+#include <boost/python/manage_new_object.hpp>
 
 #include <boost/python/register_ptr_to_python.hpp>
 using namespace boost::python;
@@ -10,9 +11,25 @@ using namespace boost::python;
 
 #include "stl_container_adapter.hpp"
 
+SeqSpanRef seq_span_factory(
+  const std::string& s, 
+  AlphabetRef a = dna_alphabet, 
+  SeqSpan::strand_type strand = SeqSpan::PlusStrand)
+{
+  SeqSpanRef seq(new SeqSpan(s, a, strand));
+  return seq;
+}
+
+BOOST_PYTHON_FUNCTION_OVERLOADS(
+  seq_span_factory_overloads, 
+  seq_span_factory,
+  1, // minimum arguments
+  3 // maximum arguments
+);
+
 void export_seq_span()
 {
-  enum_<SeqSpan::strand_type>("strand_type")
+  enum_<SeqSpan::strand_type>("strand")
     .value("unknown", SeqSpan::UnknownStrand)
     .value("minus", SeqSpan::MinusStrand)
     .value("plus", SeqSpan::PlusStrand)
@@ -22,16 +39,19 @@ void export_seq_span()
     .value("single", SeqSpan::SingleStrand)
     ;
 
+  def("SeqSpan", seq_span_factory, 
+      seq_span_factory_overloads(args("sequence", "alphabet", "strand"))
+      );
 
-  class_<SeqSpan>("SeqSpan", 
-                  init<std::string, optional<AlphabetRef, 
-                                             SeqSpan::strand_type> 
-                      >() )
-    .def("__len__", &SeqSpan::size)
+  class_<SeqSpan>("_SeqSpan", no_init)
     .def("__getitem__", &std_item<SeqSpan>::get_const,
         return_value_policy<copy_const_reference>())
+    .def("__len__", &SeqSpan::size)
     .def("__str__", &SeqSpan::sequence)
     .def("empty", &SeqSpan::empty)
+    //.add_property("alphabet", 
+    //              make_getter(&SeqSpan::get_alphabet,
+    //                          return_value_policy<copy_const_reference>()))
     .add_property("start", &SeqSpan::start, &SeqSpan::setStart,
                   "start position relative to root sequence")
     .add_property("stop", &SeqSpan::stop, &SeqSpan::setStop,
@@ -43,10 +63,11 @@ void export_seq_span()
                   "start position relative to parent sequence")
     .add_property("parentStop", &SeqSpan::parentStop, &SeqSpan::setParentStop,
                   "one past the last position relative to the parent sequence.")
-    .add_property("parent", &SeqSpan::parent)
-
+    // doesn't work because I keep getting new python objects for the same
+    // shared ptr
+    //.def("parent", &SeqSpan::parent)
     .def("subseq", &SeqSpan::subseq)
     ;
  
-  register_ptr_to_python< boost::shared_ptr<SeqSpan> >();
+  register_ptr_to_python< SeqSpanRef >();
 }
index 09747dec3fd3c0bc89041ffac8dee0c112667fa3..de1082402fe655f8624337ce4ae16926f6b67fe4 100644 (file)
@@ -21,6 +21,27 @@ class TestSeqSpan(unittest.TestCase):
     self.failUnlessEqual(len(seq_text), len(s))
     self.failUnlessEqual(seq_text, new_seq_text)
 
+  def testSettingStrand(self):
+    seq_text = "AAAAG"
+    complement_text = "CTTTT"
+    splus = mussa.SeqSpan(seq_text, mussa.alphabet.dna_alphabet, mussa.strand.plus)
+    sminus = splus.subseq(0, len(seq_text), mussa.strand.minus)
+    self.failUnlessEqual(str(sminus), complement_text)
+
+  # Doesn't work because I keep getting new python objects created
+  # for calls to SeqSpan::parent
+  #def testParentEquality(self):
+  #  seq_text = "AAAAAAGGG"
+  #  sparent = mussa.SeqSpan(seq_text)
+  #  s1 = sparent.subseq(4,4, mussa.strand.minus)
+  #y  s2 = s1.subseq(0,2, mussa.strand.opposite)
+  #  print "s2 parent call 1",s2.parent()
+  #  print "s2 parent call 2", s2.parent()
+  #  self.failUnless(s1 is s2.parent())
+  #  self.failUnlessEqual(s1, s2.parent())
+  #  self.failUnless(sparent is s1.parent())
+  #  self.failUnlessEqual(sparent == s1.parent())
+
 
 def suite():
   return unittest.makeSuite(TestSeqSpan, 'test')