From 7a55c95eeeb792f89df39dc9375040dcbd415dfd Mon Sep 17 00:00:00 2001 From: Diane Trout Date: Tue, 4 Sep 2007 22:35:50 +0000 Subject: [PATCH] more work on seq_span 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 | 22 ++++++++++++++++++++- py/seq_span.cpp | 39 +++++++++++++++++++++++++++++--------- py/test/TestSeqSpan.py | 21 ++++++++++++++++++++ 3 files changed, 72 insertions(+), 10 deletions(-) diff --git a/alg/test/test_seq_span.cpp b/alg/test/test_seq_span.cpp index 4955867..c71382e 100644 --- a/alg/test/test_seq_span.cpp +++ b/alg/test/test_seq_span.cpp @@ -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 +} + diff --git a/py/seq_span.cpp b/py/seq_span.cpp index aa484c9..d3e0b5b 100644 --- a/py/seq_span.cpp +++ b/py/seq_span.cpp @@ -2,6 +2,7 @@ #include #include +#include #include 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_("strand_type") + enum_("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", - init - >() ) - .def("__len__", &SeqSpan::size) + class_("_SeqSpan", no_init) .def("__getitem__", &std_item::get_const, return_value_policy()) + .def("__len__", &SeqSpan::size) .def("__str__", &SeqSpan::sequence) .def("empty", &SeqSpan::empty) + //.add_property("alphabet", + // make_getter(&SeqSpan::get_alphabet, + // return_value_policy())) .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 >(); + register_ptr_to_python< SeqSpanRef >(); } diff --git a/py/test/TestSeqSpan.py b/py/test/TestSeqSpan.py index 09747de..de10824 100644 --- a/py/test/TestSeqSpan.py +++ b/py/test/TestSeqSpan.py @@ -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') -- 2.30.2