add annot and motif classes to python interface
authorDiane Trout <diane@caltech.edu>
Thu, 27 Jul 2006 02:13:31 +0000 (02:13 +0000)
committerDiane Trout <diane@caltech.edu>
Thu, 27 Jul 2006 02:13:31 +0000 (02:13 +0000)
this also involved renaming annot.start to annot.begin to be a bit
more consistent with the begin/end convention used by C++.
I also added some more of the sequence class api to the python layer.
(so there's some hope that one could add annotations)

13 files changed:
alg/glseqbrowser.cpp
alg/glsequence.cpp
alg/glsequence.hpp
alg/sequence.cpp
alg/sequence.hpp
alg/test/test_annotation_color.cpp
alg/test/test_sequence.cpp
py/CMakeLists.txt
py/annot.cpp [new file with mode: 0644]
py/glsequence.cpp
py/module.cpp
py/sequence.cpp
py/test/TestSequence.py

index 919508bcdd8a9cdb3dffe8564bdbae423bd8bdce..d7d60aa2724e43430d2ac4b3d301b675862753ab 100644 (file)
@@ -563,15 +563,15 @@ void GlSeqBrowser::update_layout()
     {
       seq_i->setX(0);
       seq_i->setY(y);
-      if (seq_i->length() > max_base_pairs)
-        max_base_pairs = seq_i->length();
+      if (seq_i->size() > max_base_pairs)
+        max_base_pairs = seq_i->size();
     }
   } else if (track_count == 1) {
     // center the single track
     glseq_itor_type seq_i = track_container.begin();
     seq_i->setX(0);
     seq_i->setY(viewport_size.x /2);
-    max_base_pairs = seq_i->length();
+    max_base_pairs = seq_i->size();
   } else {
     // nothing to do as we're empty
     return;
index 54a13fad5af915e8dd28190ceae135147e43b9ca..de262d461ce9dc283079842c9da879ac55fd0186 100644 (file)
@@ -63,7 +63,7 @@ GLfloat GlSequence::x() const
 
 GLfloat GlSequence::right() const
 {
-  return length()+seq_x;
+  return size()+seq_x;
 }
 
 void GlSequence::setY(GLfloat value)
@@ -81,7 +81,7 @@ GLfloat GlSequence::height() const
   return seq_height;
 }
 
-GLfloat GlSequence::length() const
+GLfloat GlSequence::size() const
 {
   return seq->size();
 }
@@ -236,7 +236,7 @@ void GlSequence::draw_annotations(GLfloat left, GLfloat right) const
        ++annot_itor)
   {
     glColor3f(0.0, 0.8, 0.0);
-    draw_box(left, right, seq_x+annot_itor->start, seq_x+annot_itor->end, 
+    draw_box(left, right, seq_x+annot_itor->begin, seq_x+annot_itor->end, 
              seq_height, annotation_z);
   }
   // if motifs?
@@ -245,7 +245,7 @@ void GlSequence::draw_annotations(GLfloat left, GLfloat right) const
        ++motifs_itor)
   {
     glColor3fv(color_mapper->lookup("motif", motifs_itor->sequence).get());
-    draw_box(left, right, seq_x+motifs_itor->start, seq_x+motifs_itor->end, 
+    draw_box(left, right, seq_x+motifs_itor->begin, seq_x+motifs_itor->end, 
              seq_height, annotation_z+1.0);
   }
 
index 5b08fb31a272eacd48197b7a9bb23089c7ccfd32..31e282e4ef6bad0c096be9bb63e0537edd5f33cc 100644 (file)
@@ -35,7 +35,7 @@ public:
   void setX(GLfloat);
   //! get our starting x (horizontal) coordinate
   GLfloat x() const;
-  //! get our right (horizontal) coordinate (length-x)
+  //! get our right (horizontal) coordinate (size-x)
   GLfloat right() const;
   //! set our current y (vertical) position
   void setY(GLfloat);
@@ -44,7 +44,7 @@ public:
   //! how thick (high) the track we're drawing is
   GLfloat height() const;
   //! how long is our sequence track? (computed from the sequence)
-  GLfloat length() const;
+  GLfloat size() const;
  
   //! return the left (lowest) base index that is fully visible
   Sequence::size_type leftbase(GLfloat left) const;
index 65ff57d2e326c42bea38346fabcdc2966d34e6a3..b2f76c7c4f6d9107c59215e6293dd12ae1a0afae 100644 (file)
@@ -47,15 +47,15 @@ static const char* rna_alphabet = "AaCcGgNnUu\012\015";
 static const char* iupac_alphabet = "AaCcGgTtUuRrYyMmKkSsWwBbDdHhVvNn\012\015";
 
 annot::annot() 
- : start(0),
+ : begin(0),
    end(0),
    type(""),
    name("")
 {
 }
 
-annot::annot(int start, int end, std::string type, std::string name)
- : start(start),
+annot::annot(int begin, int end, std::string type, std::string name)
+ : begin(begin),
    end(end),
    type(type),
    name(name)
@@ -68,14 +68,14 @@ annot::~annot()
 
 bool operator==(const annot& left, const annot& right)
 {
-  return ((left.start == right.start) and
+  return ((left.begin== right.begin) and
           (left.end == right.end) and
           (left.type == right.type) and
           (left.name == right.name));
 }
 
-motif::motif(int start, std::string motif)
- : annot(start, start+motif.size(), "motif", motif),
+motif::motif(int begin, std::string motif)
+ : annot(begin, begin+motif.size(), "motif", motif),
    sequence(motif)
 {
 }
@@ -467,14 +467,14 @@ Sequence::subseq(int start, int count) const
       annot_i != annots.end();
       ++annot_i)
   {
-    int annot_start = annot_i->start;
+    int annot_begin= annot_i->begin;
     int annot_end = annot_i->end;
 
-    if (annot_start < end) {
-      if (annot_start >=start) {
-        annot_start -= start;
+    if (annot_begin < end) {
+      if (annot_begin >= start) {
+        annot_begin -= start;
       } else {
-        annot_start = 0;
+        annot_begin = 0;
       }
 
       if (annot_end < end) {
@@ -483,7 +483,7 @@ Sequence::subseq(int start, int count) const
         annot_end = count;
       }
 
-      annot new_annot(annot_start, annot_end, annot_i->type, annot_i->name);
+      annot new_annot(annot_begin, annot_end, annot_i->type, annot_i->name);
       new_seq.annots.push_back(new_annot);
     }
   }
@@ -593,7 +593,7 @@ Sequence::save(fs::fstream &save_file)
   save_file << species << std::endl;
   for (annots_i = annots.begin(); annots_i != annots.end(); ++annots_i)
   {
-    save_file << annots_i->start << " " << annots_i->end << " " ;
+    save_file << annots_i->begin << " " << annots_i->end << " " ;
     save_file << annots_i->name << " " << annots_i->type << std::endl;
   }
   save_file << "</Annotations>" << std::endl;
@@ -638,7 +638,7 @@ Sequence::load_museq(fs::path load_file_path, int seq_num)
         // get annot start index
         space_split_i = file_data_line.find(" ");
         annot_value = file_data_line.substr(0,space_split_i);
-        an_annot.start = atoi (annot_value.c_str());
+        an_annot.begin = atoi (annot_value.c_str());
         file_data_line = file_data_line.substr(space_split_i+1);
         // get annot end index
         space_split_i = file_data_line.find(" ");
index eceb961c93a5752b5b248fb97d52a704cd3dcd84..c576c3eb45de72f600b2e0d12abaff5361f9f7cf 100644 (file)
 struct annot
 {
   annot();
-  annot(int start, int end, std::string type, std::string name);
+  annot(int begin, int end, std::string type, std::string name);
   ~annot();
   
-  int start;
+  int begin;
   int end;
   std::string type;
   std::string name;
@@ -46,7 +46,7 @@ struct motif : public annot
   std::string sequence;
 
   //! this constructor is for when we're adding motifs to our annotations
-  motif(int start, std::string motif);
+  motif(int begin, std::string motif);
   ~motif();
 };
 
index 4cde0ddf463b400d6e770da969c46fcb06287af6..2e907e9442ed2add2fdefc4a32fddd31fffdeb31 100644 (file)
@@ -26,7 +26,7 @@ BOOST_AUTO_TEST_CASE( simple_annot_colors )
   BOOST_CHECK_EQUAL( ac.lookup("venchent", "a"), white );
 
   annot a;
-  a.start = 30;
+  a.begin = 30;
   a.end = 45;
   a.type = "bleem";
   a.name = "a";
index b331bfaf49462f85e78a63f20a735e9bfcefe919..990e193fda17ac1b7b1a97fb29d16b375f1c7c75 100644 (file)
@@ -128,7 +128,7 @@ BOOST_AUTO_TEST_CASE( annotation_load )
   std::list<annot> annots_list = seq.annotations();
   std::vector<annot> annots(annots_list.begin(), annots_list.end());
   BOOST_REQUIRE_EQUAL( annots.size(), 8);
-  BOOST_CHECK_EQUAL( annots[0].start, 0 );
+  BOOST_CHECK_EQUAL( annots[0].begin, 0 );
   BOOST_CHECK_EQUAL( annots[0].end, 10 );
   BOOST_CHECK_EQUAL( annots[0].type, "type");
   BOOST_CHECK_EQUAL( annots[0].name, "name");
@@ -138,14 +138,14 @@ BOOST_AUTO_TEST_CASE( annotation_load )
   BOOST_CHECK_EQUAL( annots[4].name, "backward");
   BOOST_CHECK_EQUAL( annots[5].name, "name2");
   BOOST_CHECK_EQUAL( annots[5].end, 90);
-  BOOST_CHECK_EQUAL( annots[6].start, 100);
+  BOOST_CHECK_EQUAL( annots[6].begin, 100);
   BOOST_CHECK_EQUAL( annots[6].end, 120);
   BOOST_CHECK_EQUAL( annots[6].name, "name-asdf");
   BOOST_CHECK_EQUAL( annots[6].type, "type!@#$%");
   // sequence defined annotations will always be after the
   // absolute positions
   BOOST_CHECK_EQUAL( annots[7].name, "ident3 asdf");
-  BOOST_CHECK_EQUAL( annots[7].start, 100);
+  BOOST_CHECK_EQUAL( annots[7].begin, 100);
 
   //BOOST_CHECK_EQUAL( annots
 }
@@ -172,7 +172,7 @@ BOOST_AUTO_TEST_CASE( annotation_load_no_species_name )
   std::list<annot> annots_list = seq.annotations();
   std::vector<annot> annots(annots_list.begin(), annots_list.end());
   BOOST_REQUIRE_EQUAL( annots.size(), 8);
-  BOOST_CHECK_EQUAL( annots[0].start, 0 );
+  BOOST_CHECK_EQUAL( annots[0].begin, 0 );
   BOOST_CHECK_EQUAL( annots[0].end, 10 );
   BOOST_CHECK_EQUAL( annots[0].type, "type");
 }
@@ -280,13 +280,13 @@ BOOST_AUTO_TEST_CASE( annot_test )
 {
   annot a(0, 10, "test", "thing");
 
-  BOOST_CHECK_EQUAL( a.start, 0 );
+  BOOST_CHECK_EQUAL( a.begin, 0 );
   BOOST_CHECK_EQUAL( a.end,   10 );
   BOOST_CHECK_EQUAL( a.type,  "test" );
   BOOST_CHECK_EQUAL( a.name,  "thing" );
 
   motif m(10, "AAGGCC");
-  BOOST_CHECK_EQUAL( m.start, 10 );
+  BOOST_CHECK_EQUAL( m.begin, 10 );
   BOOST_CHECK_EQUAL( m.type, "motif" );
   BOOST_CHECK_EQUAL( m.name, "AAGGCC" );
   BOOST_CHECK_EQUAL( m.end,  10+6 );
index 58a3f600d8eaebe934a9f353bcbbc757c13d03c3..7f6577c0bfd1cc868a49b248b665a2f8020f4392 100644 (file)
@@ -12,6 +12,7 @@ INCLUDE( ${QT_USE_FILE} )
 IF(BOOST_PYTHON_LIBRARY)
   INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH} ${QT_INCLUDES})
   SET(SOURCES 
+        annot.cpp
         annotation_colors.cpp
         conserved_path.cpp 
         glsequence.cpp
diff --git a/py/annot.cpp b/py/annot.cpp
new file mode 100644 (file)
index 0000000..7b06fb8
--- /dev/null
@@ -0,0 +1,19 @@
+#include <boost/python.hpp>
+using namespace boost::python;
+
+#include "alg/sequence.hpp"
+
+void export_annot()
+{
+  class_<annot>("annot")
+    .def(init<int, int, std::string, std::string>())
+    .def_readwrite("begin", &annot::begin)
+    .def_readwrite("end", &annot::end)
+    .def_readwrite("type", &annot::type)
+    .def_readwrite("name", &annot::name)
+  ;
+
+  class_<motif, bases<annot> >("motif", init<int, std::string>())
+    .def_readwrite("sequence", &motif::sequence)
+  ;
+}
index f40efa31297564b74363608bf8e63f45c2d07a64..d736920619812b7694e446645fa62291cf670344 100644 (file)
@@ -19,6 +19,6 @@ void export_glsequence()
                   return_internal_reference<>())
     .add_property("x", &GlSequence::x, &GlSequence::setX)
     .add_property("y", &GlSequence::y, &GlSequence::setY)
-    .add_property("length", &GlSequence::length)
+    .add_property("__len__", &GlSequence::size)
   ;
 }
index 632b117fd5f5498f7832dbd14f57942aaf2fb476..91bdd115fbd6d9cfce15108ccdcd133d5a3d1414 100644 (file)
@@ -1,6 +1,7 @@
 #include <boost/python.hpp>
 using namespace boost::python;
 
+void export_annot();
 void export_annotation_colors();
 void export_conserved_path();
 void export_glsequence();
@@ -11,6 +12,7 @@ void export_mussa_window();
 
 BOOST_PYTHON_MODULE(mussa)
 {
+  export_annot();
   export_annotation_colors();
   export_conserved_path();
   export_glsequence();
index 2bb10ab6546a772c2ceb0f179f2c9aaee47a1ced..494690c0d159b9f9269a9a7671c2ac641a13e950 100644 (file)
@@ -19,11 +19,15 @@ void export_sequence()
 {
   class_<Sequence>("Sequence")
     .def(init<std::string>())
-    .def("__str__", &seq_to_string)
-    .def("size", &Sequence::size)
-    .def("__len__", &Sequence::size)
-    .add_property("header", &Sequence::get_fasta_header, &Sequence::set_fasta_header)
+    .def("__str__", &seq_to_string, "cast to string")
+    .def("__repr__", &seq_to_string, "display as string")
+    .def("size", &Sequence::size, "return the length of the sequence")
+    .def("__len__", &Sequence::size, "return the length of the sequence")
+    .def("clear", &Sequence::clear, "clear the sequence and its annotations")
+    .add_property("header", &Sequence::get_fasta_header, &Sequence::set_fasta_header, "the fasta header")
     .add_property("species", &Sequence::get_species, &Sequence::set_species)
+    .def("add_annotation", &Sequence::add_annotation, "append an annotation")
+    //.def("annotations", &Sequence::annotations, "return list of annotations")
     .def("rcseq", &Sequence::rev_comp, return_value_policy<return_by_value>())
   ;
 
index 274fbdba4cd751da41dec9221b9cc79a888eff3a..5fcc36205aa0d1b04614c5ab08c96421ed9fc290 100644 (file)
@@ -27,7 +27,27 @@ class TestSequence(unittest.TestCase):
     s.species = species
     self.failUnless(s.header == header_text)
     self.failUnless(s.species == species)
-     
+
+  def testAnnotations(self):
+    annot = mussa.annot()
+    annot.begin = 0
+    annot.end = 10
+    annot.name = "foo"
+    annot.type = "utr"
+
+    seq = mussa.Sequence("AAGGCCTTAATTGGCCTT")
+    seq.add_annotation(annot)
+
+  def notestFile(self):
+    # remove no prefix once we have sequence loading from a stream
+    seq_text = "AAGGCCTT"
+    from StringIO import StringIO
+    s = StringIO(seq_text)
+
+    seq = mussa.Sequence(s)
+
+    self.failUnless(seq == seq_text)
+
 def suite():
   return unittest.makeSuite(TestSequence, 'test')