COMMAND cp libmussa.so mussa.so
DEPENDS mussa)
ENDIF(WIN32)
- LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/alg)
TARGET_LINK_LIBRARIES(mussa
mussa_core
${BOOST_PYTHON_LIBRARY}
optimized ${QT_QTCORE_LIBRARY}
debug ${QT_QTCORE_LIBRARY_DEBUG}
)
-
GET_MUSSA_COMPILE_FLAGS(PY_CFLAGS)
GET_MUSSA_LINK_FLAGS(PY_LDFLAGS)
SET_SOURCE_FILES_PROPERTIES(
SET(PYTEST_DIR ${CMAKE_SOURCE_DIR}/py/test/)
ADD_TEST(TestSequence ${PYTHON_EXECUTABLE} ${PYTEST_DIR}/TestSequence.py)
ADD_TEST(TestFlp ${PYTHON_EXECUTABLE} ${PYTEST_DIR}/TestFlp.py)
+ ADD_TEST(TestMussa ${PYTHON_EXECUTABLE} ${PYTEST_DIR}/TestMussa.py)
ENDIF(PYTHON_EXECUTABLE)
ELSE(BOOST_PYTHON_LIBRARY)
ENDIF(BOOST_PYTHON_LIBRARY)
namespace py = boost::python;
#include "alg/mussa.hpp"
+#include "alg/sequence.hpp"
+#include "stl_container_adapter.hpp"
void export_mussa()
{
void (Mussa::*load_mupa_string)(std::string) = &Mussa::load_mupa_file;
+ void (Mussa::*append_sequence_ref)(const Sequence&) = &Mussa::append_sequence;
+ void (Mussa::*append_sequence_ptr)(const boost::shared_ptr<Sequence>) = &Mussa::append_sequence;
+ py::class_<Mussa::vector_sequence_type>("Sequences")
+ .def("__len__", &Mussa::vector_sequence_type::size, "return length of sequences")
+ .def("__contains__", &std_item<Mussa::vector_sequence_type>::in)
+ .def("__iter__", py::iterator<Mussa::vector_sequence_type>())
+ .def("clear", &Mussa::vector_sequence_type::clear, "remove all the sequences")
+ .def("append", &std_item<Mussa::vector_sequence_type>::add,
+ py::with_custodian_and_ward<1,2>()) // to let container keep value
+ .def("__getitem__", &std_item<Mussa::vector_sequence_type>::get,
+ py::return_value_policy<py::copy_non_const_reference>())
+ .def("__setitem__", &std_item<Mussa::vector_sequence_type>::set,
+ py::with_custodian_and_ward<1,2>()) // to let container keep value
+ .def("__delitem__", &std_item<Mussa::vector_sequence_type>::del)
+ ;
+
py::class_<Mussa>("Mussa")
.def("save", &Mussa::save)
.def("load", &Mussa::load, "Load previous run analysis")
.add_property("analysisModeName", &Mussa::get_analysis_mode_name)
.def("analyze", &Mussa::analyze, "Run the analysis")
.def("paths", &Mussa::paths, py::return_internal_reference<>())
- //.def("sequences", &Mussa::sequences)
- //.def("addSequence", &Mussa::append_sequence)
+ .def("sequences", &Mussa::sequences, py::return_internal_reference<>())
+ .def("add_sequence", append_sequence_ref)
;
py::enum_<Mussa::analysis_modes>("analysis_modes")
--- /dev/null
+#ifndef STL_CONTAINER_ADAPTER_HPP_
+#define STL_CONTAINER_ADAPTER_HPP_
+
+#include <algorithm>
+#include <boost/python.hpp>
+
+// This template started off life at
+// http://wiki.python.org/moin/boost.python/StlContainers
+
+void IndexError() { PyErr_SetString(PyExc_IndexError, "Index out of range"); }
+template<typename T>
+struct std_item
+{
+ typedef typename T::value_type V;
+ static V& get(T& x, int i)
+ {
+ if( i<0 ) i+=x.size();
+ if( i>=0 && i<x.size() ) return x[i];
+ IndexError();
+ }
+ static void set(T& x, int i, V const& v)
+ {
+ if( i<0 ) i+=x.size();
+ if( i>=0 && i<x.size() ) x[i]=v;
+ else IndexError();
+ }
+ static void del(T& x, int i)
+ {
+ if( i<0 ) i+=x.size();
+ if( i>=0 && i<x.size() ) {
+ typename T::iterator itor = x.begin();
+ itor += i;
+ x.erase(itor);
+ } else IndexError();
+ }
+ static void add(T& x, V& v)
+ {
+ x.push_back(v);
+ }
+ static bool in(T const& x, V const& v)
+ {
+ return std::find(x.begin(), x.end(), v) != x.end();
+ }
+ static int index(T const& x, V const& v)
+ {
+ int i=0;
+ for(typename T::const_iterator it=x.begin; it!=x.end(); ++it,++i)
+ if( *it == v ) return i;
+ return -1;
+ }
+};
+
+void KeyError() { PyErr_SetString(PyExc_KeyError, "Key not found"); }
+template<typename T>
+struct map_item
+{
+ typedef typename T::key_type K;
+ typedef typename T::mapped_type V;
+ static V& get(T const& x, K const& i)
+ {
+ if( x.find(i) != x.end() ) return x[i];
+ KeyError();
+ }
+ static void set(T const& x, K const& i, V const& v)
+ {
+ x[i]=v; // use map autocreation feature
+ }
+ static void del(T const& x, K const& i)
+ {
+ if( x.find(i) != x.end() ) x.erase(i);
+ else KeyError();
+ }
+ static bool in(T const& x, K const& i)
+ {
+ return x.find(i) != x.end();
+ }
+ static boost::python::list keys(T const& x)
+ {
+ boost::python::list t;
+ 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)
+ 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)
+ 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)
+ if( it->first == k ) return i;
+ return -1;
+ }
+};
+
+
+#endif /*STL_CONTAINER_ADAPTER_HPP_*/
--- /dev/null
+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 TestMussa(unittest.TestCase):
+ def testSimple(self):
+ s1 = mussa.Sequence("A"*10)
+ s2 = mussa.Sequence("GG"+"A"*8+"GG")
+ s3 = mussa.Sequence("T"*10)
+ m = mussa.Mussa()
+ m.window = 10
+ m.threshold = 8
+ m.add_sequence(s1)
+ m.add_sequence(s2)
+ m.add_sequence(s3)
+ m.analyze()
+ print m.paths()
+
+def suite():
+ return unittest.makeSuite(TestMussa, 'test')
+
+if __name__ == "__main__":
+ sys.exit(unittest.main(defaultTest='suite'))
\ No newline at end of file