From: Diane Trout Date: Wed, 5 Sep 2007 01:41:39 +0000 (+0000) Subject: basic wrapping of Annotations X-Git-Url: http://woldlab.caltech.edu/gitweb/?p=mussa.git;a=commitdiff_plain;h=c417e847eccd0af3bf9dfed0bc252115bbbf3d83 basic wrapping of Annotations this provides at least basic member access for my annotations class, it unfortunately doesn't properly handle iteratation yet though. --- diff --git a/alg/annotations.hpp b/alg/annotations.hpp index 607d6cb..132b865 100644 --- a/alg/annotations.hpp +++ b/alg/annotations.hpp @@ -22,7 +22,11 @@ protected: static const std::string name_str; public: - typedef std::map metadata_map; + typedef std::string key_type; + typedef std::string mapped_type; + typedef std::map metadata_map; + typedef metadata_map::iterator iterator; + typedef metadata_map::const_iterator const_iterator; typedef metadata_map::size_type size_type; Annotations(); @@ -32,6 +36,8 @@ public: //! 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; } @@ -40,8 +46,19 @@ public: //! 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); + //! 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 @@ -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; - //! return all the keys of our metadata map - //std::list keys() const; + //! return number of items in the map size_type size() const { return metadata.size(); } //@} protected: diff --git a/py/CMakeLists.txt b/py/CMakeLists.txt index c5a30d6..c475742 100644 --- a/py/CMakeLists.txt +++ b/py/CMakeLists.txt @@ -14,6 +14,7 @@ IF(BOOST_PYTHON_LIBRARY) alphabet.cpp annot.cpp annotation_colors.cpp + annotations.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/) + 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) diff --git a/py/annotations.cpp b/py/annotations.cpp new file mode 100644 index 0000000..4c0c53c --- /dev/null +++ b/py/annotations.cpp @@ -0,0 +1,31 @@ +#include + +#include +#include +#include + +#include +using namespace boost::python; + +#include "alg/annotations.hpp" + +#include "stl_container_adapter.hpp" + +void export_annotations() +{ + + class_("annotations", init()) + .add_property("name", &Annotations::name, &Annotations::setName) + .def("__contains__", &map_item::in) + .def("__delitem__", &map_item::del) + .def("__getitem__", &map_item::get, + return_value_policy()) + .def("__setitem__", &map_item::set) + .def("__len__", &Annotations::size) + .def("keys", &map_item::keys) + .def("values", &map_item::values) + .def("items", &map_item::items) + ; + + //register_ptr_to_python< AnnotationsRef >(); +} diff --git a/py/module.cpp b/py/module.cpp index f9e6b4f..cd98f04 100644 --- a/py/module.cpp +++ b/py/module.cpp @@ -4,6 +4,7 @@ void export_alphabet(); void export_annot(); void export_annotation_colors(); +void export_annotations(); 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_annotations(); export_conserved_path(); export_flps(); export_seq_span(); diff --git a/py/stl_container_adapter.hpp b/py/stl_container_adapter.hpp index f60c996..37f66fe 100644 --- a/py/stl_container_adapter.hpp +++ b/py/stl_container_adapter.hpp @@ -81,16 +81,16 @@ struct map_item { 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(); } - 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 } - 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(); @@ -102,28 +102,28 @@ struct map_item 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; - 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; - 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; - 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; } diff --git a/py/test/TestAnnotations.py b/py/test/TestAnnotations.py new file mode 100644 index 0000000..32949d4 --- /dev/null +++ b/py/test/TestAnnotations.py @@ -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'))