basic wrapping of Annotations
authorDiane Trout <diane@caltech.edu>
Wed, 5 Sep 2007 01:41:39 +0000 (01:41 +0000)
committerDiane Trout <diane@caltech.edu>
Wed, 5 Sep 2007 01:41:39 +0000 (01:41 +0000)
this provides at least basic member access for my annotations class,
it unfortunately doesn't properly handle iteratation yet though.

alg/annotations.hpp
py/CMakeLists.txt
py/annotations.cpp [new file with mode: 0644]
py/module.cpp
py/stl_container_adapter.hpp
py/test/TestAnnotations.py [new file with mode: 0644]

index 607d6cb46d9ad81417f350fe9c950f11a21e8c24..132b865346b2862c6d975cc25779a38ac1517a66 100644 (file)
@@ -22,7 +22,11 @@ protected:
   static const std::string name_str;
 
 public:
   static const std::string name_str;
 
 public:
-  typedef std::map<std::string, std::string> metadata_map;
+  typedef std::string key_type;
+  typedef std::string mapped_type;
+  typedef std::map<key_type, mapped_type> metadata_map;
+  typedef metadata_map::iterator iterator;
+  typedef metadata_map::const_iterator const_iterator;
   typedef metadata_map::size_type size_type;
   
   Annotations();
   typedef metadata_map::size_type size_type;
   
   Annotations();
@@ -32,6 +36,8 @@ public:
 
   //! make a shared pointer copy of our object
   AnnotationsRef copy() const;
 
   //! make a shared pointer copy of our object
   AnnotationsRef copy() const;
+
+  mapped_type& operator[](const key_type& k) { return metadata[k]; }
     
   //! provide a special case for accessing a name
   std::string name() const { return metadata.find(name_str)->second; }
     
   //! provide a special case for accessing a name
   std::string name() const { return metadata.find(name_str)->second; }
@@ -40,8 +46,19 @@ public:
   
   //! Generic metadata handling
   //@{
   
   //! Generic metadata handling
   //@{
+  //! begin iterator
+  iterator begin() { return metadata.begin(); }
+  //! const begin iterator
+  const_iterator begin() const { return metadata.begin(); }
+  //! end iterator
+  iterator end() { return metadata.end(); }
+  //! const end iterator
+  const_iterator end() const { return metadata.end(); }
   //! remove some key from our "dictionary"
   void erase(const std::string& key);  
   //! remove some key from our "dictionary"
   void erase(const std::string& key);  
+  //! find an element in the map
+  iterator find( const key_type& key) { return metadata.find(key); }
+  const_iterator find( const key_type& key) const { return metadata.find(key); }
   //! set a metadata element 
   void set(const std::string key, const std::string value );
   //! look for a key, \throws annotation_key_error if it doesn't find it
   //! set a metadata element 
   void set(const std::string key, const std::string value );
   //! look for a key, \throws annotation_key_error if it doesn't find it
@@ -50,8 +67,7 @@ public:
   std::string getdefault(const std::string key, std::string default_value) const;
   //! check for a key
   bool has_key(const std::string key) const;
   std::string getdefault(const std::string key, std::string default_value) const;
   //! check for a key
   bool has_key(const std::string key) const;
-  //! return all the keys of our metadata map
-  //std::list<std::string> keys() const;
+  //! return number of items in the map
   size_type size() const { return metadata.size(); }
   //@}
 protected:
   size_type size() const { return metadata.size(); }
   //@}
 protected:
index c5a30d609aa92b6f1cfb8e8c18452f17ecbc4c80..c47574269e1146e36ec338ca83fb522e9b345526 100644 (file)
@@ -14,6 +14,7 @@ IF(BOOST_PYTHON_LIBRARY)
         alphabet.cpp
         annot.cpp
         annotation_colors.cpp
         alphabet.cpp
         annot.cpp
         annotation_colors.cpp
+       annotations.cpp
         conserved_path.cpp 
         flp.cpp
         glsequence.cpp
         conserved_path.cpp 
         flp.cpp
         glsequence.cpp
@@ -96,6 +97,8 @@ IF(BOOST_PYTHON_LIBRARY)
 
   IF(PYTHON_EXECUTABLE)
     SET(PYTEST_DIR ${CMAKE_SOURCE_DIR}/py/test/)
 
   IF(PYTHON_EXECUTABLE)
     SET(PYTEST_DIR ${CMAKE_SOURCE_DIR}/py/test/)
+    ADD_TEST(TestAnnotations 
+                     ${PYTHON_EXECUTABLE} ${PYTEST_DIR}/TestAnnotations.py)
     ADD_TEST(TestSeqSpan ${PYTHON_EXECUTABLE} ${PYTEST_DIR}/TestSeqSpan.py)
     ADD_TEST(TestSequence ${PYTHON_EXECUTABLE} ${PYTEST_DIR}/TestSequence.py)
     ADD_TEST(TestFlp ${PYTHON_EXECUTABLE} ${PYTEST_DIR}/TestFlp.py)
     ADD_TEST(TestSeqSpan ${PYTHON_EXECUTABLE} ${PYTEST_DIR}/TestSeqSpan.py)
     ADD_TEST(TestSequence ${PYTHON_EXECUTABLE} ${PYTEST_DIR}/TestSequence.py)
     ADD_TEST(TestFlp ${PYTHON_EXECUTABLE} ${PYTEST_DIR}/TestFlp.py)
diff --git a/py/annotations.cpp b/py/annotations.cpp
new file mode 100644 (file)
index 0000000..4c0c53c
--- /dev/null
@@ -0,0 +1,31 @@
+#include <boost/iterator.hpp>
+
+#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;
+
+#include "alg/annotations.hpp"
+
+#include "stl_container_adapter.hpp"
+
+void export_annotations()
+{
+
+  class_<Annotations>("annotations", init<std::string>())
+    .add_property("name", &Annotations::name, &Annotations::setName)
+    .def("__contains__", &map_item<Annotations>::in)
+    .def("__delitem__", &map_item<Annotations>::del)
+    .def("__getitem__", &map_item<Annotations>::get,
+        return_value_policy<copy_non_const_reference>())
+    .def("__setitem__", &map_item<Annotations>::set)
+    .def("__len__", &Annotations::size)
+    .def("keys", &map_item<Annotations>::keys)
+    .def("values", &map_item<Annotations>::values)
+    .def("items", &map_item<Annotations>::items)
+    ;
+
+  //register_ptr_to_python< AnnotationsRef >();
+}
index f9e6b4fdc339b1d2c5ca0916f234055ba77bc397..cd98f04fc602770c0849bcd65e2e6d6615b56626 100644 (file)
@@ -4,6 +4,7 @@
 void export_alphabet();
 void export_annot();
 void export_annotation_colors();
 void export_alphabet();
 void export_annot();
 void export_annotation_colors();
+void export_annotations();
 void export_container_exceptions();
 void export_conserved_path();
 void export_flps();
 void export_container_exceptions();
 void export_conserved_path();
 void export_flps();
@@ -20,6 +21,7 @@ BOOST_PYTHON_MODULE(mussa)
   export_alphabet();
   export_annot();
   export_annotation_colors();
   export_alphabet();
   export_annot();
   export_annotation_colors();
+  export_annotations();
   export_conserved_path();
   export_flps();
   export_seq_span();
   export_conserved_path();
   export_flps();
   export_seq_span();
index f60c9960583d51a39d453f67f22e33a078666ad6..37f66fe64d56b7daabd11d7e12ccc1512f78dcfe 100644 (file)
@@ -81,16 +81,16 @@ struct map_item
 {
     typedef typename T::key_type K;
     typedef typename T::mapped_type V;
 {
     typedef typename T::key_type K;
     typedef typename T::mapped_type V;
-    static V& get(T const& x, K const& i)
+    static V& get(T & x, K const& i)
     {
         if( x.find(i) != x.end() ) return x[i];
         throw KeyError();
     }
     {
         if( x.find(i) != x.end() ) return x[i];
         throw KeyError();
     }
-    static void set(T const& x, K const& i, V const& v)
+    static void set(T & x, K const& i, V const& v)
     {
         x[i]=v; // use map autocreation feature
     }
     {
         x[i]=v; // use map autocreation feature
     }
-    static void del(T const& x, K const& i)
+    static void del(T & x, K const& i)
     {
         if( x.find(i) != x.end() ) x.erase(i);
         else throw KeyError();
     {
         if( x.find(i) != x.end() ) x.erase(i);
         else throw KeyError();
@@ -102,28 +102,28 @@ struct map_item
     static boost::python::list keys(T const& x)
     {
         boost::python::list t;
     static boost::python::list keys(T const& x)
     {
         boost::python::list t;
-        for(typename T::const_iterator it=x.begin; it!=x.end(); ++it)
+        for(typename T::const_iterator it=x.begin(); it!=x.end(); ++it)
           t.append(it->first);
         return t;
     }
     static boost::python::list values(T const& x)
     {
         boost::python::list t;
           t.append(it->first);
         return t;
     }
     static boost::python::list values(T const& x)
     {
         boost::python::list t;
-        for(typename T::const_iterator it=x.begin; it!=x.end(); ++it)
+        for(typename T::const_iterator it=x.begin(); it!=x.end(); ++it)
           t.append(it->second);
         return t;
     }
     static boost::python::list items(T const& x)
     {
         boost::python::list t;
           t.append(it->second);
         return t;
     }
     static boost::python::list items(T const& x)
     {
         boost::python::list t;
-        for(typename T::const_iterator it=x.begin; it!=x.end(); ++it)
+        for(typename T::const_iterator it=x.begin(); it!=x.end(); ++it)
           t.append(boost::python::make_tuple(it->first,it->second));
         return t;
     }
     static int index(T const& x,  K const& k)
     {
         int i=0;
           t.append(boost::python::make_tuple(it->first,it->second));
         return t;
     }
     static int index(T const& x,  K const& k)
     {
         int i=0;
-        for(typename T::const_iterator it=x.begin; it!=x.end(); ++it,++i)
+        for(typename T::const_iterator it=x.begin(); it!=x.end(); ++it,++i)
           if( it->first == k ) return i;
         return -1;
     }
           if( it->first == k ) return i;
         return -1;
     }
diff --git a/py/test/TestAnnotations.py b/py/test/TestAnnotations.py
new file mode 100644 (file)
index 0000000..32949d4
--- /dev/null
@@ -0,0 +1,29 @@
+import os
+import sys
+import unittest
+
+# kinda hackish but it makes it possible to runi under ctest 
+sys.path.append(os.getcwd())
+
+import mussa
+
+class TestAnnotations(unittest.TestCase):
+  def testSimple(self):
+    name_value = 'name_value'
+    a = mussa.annotations(name_value)
+    self.failUnlessEqual( a['name'], name_value)
+    self.failUnlessEqual( len(a), 1)
+    self.failUnlessEqual( a.keys(), ['name'])
+    self.failUnlessEqual( a.values(), ['name_value'])
+
+  def testIter(self):
+    name_value = 'name_value'
+    a = mussa.annotations(name_value)
+    # It'd be nice if this worked.
+    # l = [ x for x in a ]
+
+def suite():
+  return unittest.makeSuite(TestAnnotations, 'test')
+
+if __name__ == "__main__":
+  sys.exit(unittest.main(defaultTest='suite'))