IF(BOOST_PYTHON_LIBRARY)
INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH} ${QT_INCLUDES})
SET(SOURCES
+ stl_container_adapter.cpp
+ alphabet.cpp
annot.cpp
annotation_colors.cpp
conserved_path.cpp
module.cpp
mussa.cpp
nway_paths.cpp
+ seq_span.cpp
sequence.cpp
)
SET(QUI_SOURCES
IF(PYTHON_EXECUTABLE)
SET(PYTEST_DIR ${CMAKE_SOURCE_DIR}/py/test/)
+ 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(TestMussa ${PYTHON_EXECUTABLE} ${PYTEST_DIR}/TestMussa.py)
--- /dev/null
+#include <boost/iterator.hpp>
+
+#include <boost/python.hpp>
+
+#include <boost/python/register_ptr_to_python.hpp>
+using namespace boost::python;
+
+#include "alg/alphabet.hpp"
+
+void export_alphabet()
+{
+ enum_<AlphabetRef>("alphabet")
+ .value("reduced_dna_alphabet", reduced_dna_alphabet)
+ .value("dna_alphabet", dna_alphabet)
+ .value("reduced_rna_alphabet", reduced_rna_alphabet)
+ .value("rna_alphabet", rna_alphabet)
+ .value("reduced_nucleic_alphabet", reduced_nucleic_alphabet)
+ .value("nucleic_alphabet", nucleic_alphabet)
+ .value("protein_alphabet", protein_alphabet)
+ ;
+
+}
+
#include <boost/python.hpp>
+#include "stl_container_adapter.hpp"
using namespace boost::python;
+void export_alphabet();
void export_annot();
void export_annotation_colors();
void export_conserved_path();
void export_glsequence();
void export_mussa();
void export_nway_paths();
+void export_seq_span();
void export_sequence();
void export_mussa_window();
BOOST_PYTHON_MODULE(mussa)
{
+ boost::python::register_exception_translator<IndexError>(&translate);
+
+ export_alphabet();
export_annot();
export_annotation_colors();
export_conserved_path();
export_flps();
+ export_seq_span();
export_sequence();
export_glsequence();
export_mussa();
--- /dev/null
+#include <boost/iterator.hpp>
+
+#include <boost/python.hpp>
+#include <boost/python/return_value_policy.hpp>
+
+#include <boost/python/register_ptr_to_python.hpp>
+using namespace boost::python;
+
+#include "alg/seq_span.hpp"
+
+#include "stl_container_adapter.hpp"
+
+void export_seq_span()
+{
+ enum_<SeqSpan::strand_type>("strand_type")
+ .value("unknown", SeqSpan::UnknownStrand)
+ .value("minus", SeqSpan::MinusStrand)
+ .value("plus", SeqSpan::PlusStrand)
+ .value("both", SeqSpan::BothStrand)
+ .value("same", SeqSpan::SameStrand)
+ .value("opposite", SeqSpan::OppositeStrand)
+ .value("single", SeqSpan::SingleStrand)
+ ;
+
+
+ class_<SeqSpan>("SeqSpan",
+ init<std::string, optional<AlphabetRef,
+ SeqSpan::strand_type>
+ >() )
+ .def("__len__", &SeqSpan::size)
+ .def("__getitem__", &std_item<SeqSpan>::get_const,
+ return_value_policy<copy_const_reference>())
+ .def("__str__", &SeqSpan::sequence)
+ .def("empty", &SeqSpan::empty)
+ .add_property("start", &SeqSpan::start, &SeqSpan::setStart,
+ "start position relative to root sequence")
+ .add_property("stop", &SeqSpan::stop, &SeqSpan::setStop,
+ "one past the last position relative to the root sequence.")
+ .add_property("strand", &SeqSpan::strand,
+ "describe which strand the span is on")
+
+ .add_property("parentStart", &SeqSpan::parentStart, &SeqSpan::setParentStart,
+ "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)
+
+ .def("subseq", &SeqSpan::subseq)
+ ;
+
+ register_ptr_to_python< boost::shared_ptr<SeqSpan> >();
+}
--- /dev/null
+#include "stl_container_adapter.hpp"
+
+void translate(IndexError const& e)
+{
+ PyErr_SetString(PyExc_IndexError, "Index out of range");
+}
+
+void translate(KeyError const& e)
+{
+ PyErr_SetString(PyExc_KeyError, "Key not found");
+}
+
#define STL_CONTAINER_ADAPTER_HPP_
#include <algorithm>
+#include <exception>
+
#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"); }
+struct IndexError : std::exception
+{
+public:
+ explicit IndexError(): std::exception() {};
+};
+
+void translate(IndexError const &e);
+
+
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;
- }
+ typedef typename T::value_type V;
+ typedef typename T::reference R;
+ typedef typename T::const_reference CR;
+
+ static R get(T& x, int i)
+ {
+ if( i<0 ) i+=x.size();
+ if( i>=0 && i<x.size() ) return x[i];
+ throw IndexError();
+ }
+ static CR get_const(T& x, int i)
+ {
+ if( i<0 ) i+=x.size();
+ if( i>=0 && i<x.size() ) return x[i];
+ throw 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 throw 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 throw 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;
+ }
+};
+
+struct KeyError : std::exception
+{
+public:
+ explicit KeyError(): std::exception() {};
};
-void KeyError() { PyErr_SetString(PyExc_KeyError, "Key not found"); }
+void translate(KeyError const &e);
+
template<typename T>
struct map_item
{
static V& get(T const& x, K const& i)
{
if( x.find(i) != x.end() ) return x[i];
- KeyError();
+ throw KeyError();
}
static void set(T const& x, K const& i, V const& v)
{
static void del(T const& x, K const& i)
{
if( x.find(i) != x.end() ) x.erase(i);
- else KeyError();
+ else throw KeyError();
}
static bool in(T const& x, K const& i)
{
--- /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 TestSeqSpan(unittest.TestCase):
+ def testSimple(self):
+ seq_text = "AGCT"
+ s = mussa.SeqSpan(seq_text)
+ self.failUnlessEqual(str(s), seq_text)
+
+ def testIter(self):
+ seq_text = "AAAAAAGGGGGGG"
+ s = mussa.SeqSpan(seq_text)
+ new_seq_text = "".join( [ x for x in s ] )
+ print "len", len(s)
+ self.failUnlessEqual(len(seq_text), len(s))
+ self.failUnlessEqual(seq_text, new_seq_text)
+
+
+def suite():
+ return unittest.makeSuite(TestSeqSpan, 'test')
+
+if __name__ == "__main__":
+ sys.exit(unittest.main(defaultTest='suite'))