From: Diane Trout Date: Wed, 12 Apr 2006 00:45:55 +0000 (+0000) Subject: build the python interface X-Git-Url: http://woldlab.caltech.edu/gitweb/?p=mussa.git;a=commitdiff_plain;h=c8b64e1fb76f78e39dc4db94a8bb7a1d262ec56d build the python interface CMake can build the python version (and on os x/unix test it) CMakes targets aren't quite appropriate for python extensions the ADD_LIBRARY target gets the right build settings but names the file libX.so while python needs X.so. I got around this by adding a custom command which makes a symlink to the right name--of course that depends on shell commands not available on windows. :( Also there's some problems with boost.python not knowing about the string to boost/filesystem converter. I manually wrapped load_mupa_file but it might be more advantagious to write a general wrapper. I also only have the simplest test case included, to test to make sure that the environment can actually run python test cases. --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 0709be1..d9a0563 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,5 +11,6 @@ SET (CXX_FLAGS "-g") INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}) ADD_SUBDIRECTORY( alg ) ADD_SUBDIRECTORY( gui ) +ADD_SUBDIRECTORY( py ) ADD_SUBDIRECTORY( qui ) diff --git a/alg/mussa.hpp b/alg/mussa.hpp index 675658d..0a724e7 100644 --- a/alg/mussa.hpp +++ b/alg/mussa.hpp @@ -47,6 +47,7 @@ class Mussa void clear(); //! set parameters from a file - 'mupa' ~ mussa parameters + void load_mupa_file(std::string para_file_path) { load_mupa_file(boost::filesystem::path(para_file_path));} void load_mupa_file(boost::filesystem::path para_file_path); // set parameters individually (eg from user input into gui classes) diff --git a/alg/nway_paths.hpp b/alg/nway_paths.hpp index 01c4be0..acbef47 100644 --- a/alg/nway_paths.hpp +++ b/alg/nway_paths.hpp @@ -70,16 +70,15 @@ class NwayPaths void save_old(boost::filesystem::path save_file_path); void print(std::list >&); + // The following iterator functions are mostly for the python interface + // they'll have problems when being called from within a const object std::list::iterator pbegin() { return pathz.begin() ; } std::list::iterator pend() { return pathz.end() ; } - std::list::const_iterator pbegin() const { return pathz.begin() ; } - std::list::const_iterator pend() const { return pathz.end() ; } size_t path_size() const { return refined_pathz.size(); } std::list::iterator rpbegin() { return refined_pathz.begin() ; } - std::list::const_iterator rpend() const { return refined_pathz.end() ; } - std::list::const_iterator rpbegin() const { return refined_pathz.begin() ; } std::list::iterator rpend() { return refined_pathz.end() ; } size_t refined_path_size() const { return refined_pathz.size(); } + // these probably shouldn't be public, but lets start // simple std::list pathz; diff --git a/py/CMakeLists.txt b/py/CMakeLists.txt new file mode 100644 index 0000000..6c88db9 --- /dev/null +++ b/py/CMakeLists.txt @@ -0,0 +1,38 @@ +FIND_PACKAGE(Boost) +FIND_PACKAGE(OpenGL) +FIND_PACKAGE(PythonLibs) +FIND_PACKAGE(PythonInterp) + +# IF(BOOST_PYTHON_LIB) + INCLUDE_DIRECTORIES(${PYTHON_INCLUDE_PATH}) + SET(SOURCES + conserved_path.cpp + glsequence.cpp + module.cpp + mussa.cpp + nway_paths.cpp + sequence.cpp + ) + + #SET_SOURCE_FILES_PROPERTIES(${SOURCES} COM + + ADD_LIBRARY(mussa MODULE ${SOURCES}) + ADD_CUSTOM_COMMAND(TARGET mussa + COMMAND rm mussa.so + COMMAND ln -s libmussa.so mussa.so) + LINK_DIRECTORIES(${MUSSA_BINARY_DIR}/alg) + TARGET_LINK_LIBRARIES(mussa + mussa_core + ${BOOST_PYTHON_LIBRARY} + ${BOOST_FILESYSTEM_LIBRARY} + ${OPENGL_gl_LIBRARY} + ${PYTHON_LIBRARIES} + ) + + IF(PYTHON_EXECUTABLE) + SET(PYTHON_TEST_DIR ${CMAKE_SOURCE_DIR}/py/test/) + ADD_TEST(sequence ${PYTHON_EXECUTABLE} ${PYTHON_TEST_DIR}/TestSequence.py) + ENDIF(PYTHON_EXECUTABLE) +#ELSE(BOOST_PYTHON_LIB) +#ENDIF(BOOST_PYTHON_LIB) + diff --git a/py/mussa.cpp b/py/mussa.cpp index 55e5a2f..b82cb43 100644 --- a/py/mussa.cpp +++ b/py/mussa.cpp @@ -9,10 +9,11 @@ void export_mussa() //BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(mussa_analyze_overloads, // &Mussa::analyze, 0, 4); + void (Mussa::*load_mupa_string)(std::string) = &Mussa::load_mupa_file; class_("Mussa") .def("save", &Mussa::save) .def("load", &Mussa::load, "Load previous run analysis") - .def("load_mupa", &Mussa::load_mupa_file, "Load mussa parameter file") + .def("load_mupa", load_mupa_string, "Load mussa parameter file") .def("clear", &Mussa::clear, "Clear the current analysis") .add_property("name", &Mussa::get_name, &Mussa::set_name) .def("size", &Mussa::size, "Number of sequences to be used " diff --git a/py/nway_paths.cpp b/py/nway_paths.cpp index 73a13a9..ee44e88 100644 --- a/py/nway_paths.cpp +++ b/py/nway_paths.cpp @@ -6,10 +6,7 @@ using namespace boost::python; void export_nway_paths() { class_("NwayPaths") - .add_property("pathz", range(&NwayPaths::pbegin, - &NwayPaths::pend)) - .add_property("refinedPathz", range(&NwayPaths::rpbegin, - &NwayPaths::rpend)) - ; + .add_property("pathz", range(&NwayPaths::pbegin, &NwayPaths::pend)) + .add_property("refinedPathz", range(&NwayPaths::rpbegin, &NwayPaths::rpend)) ; } diff --git a/py/sequence.cpp b/py/sequence.cpp index be7a73c..3167d56 100644 --- a/py/sequence.cpp +++ b/py/sequence.cpp @@ -8,7 +8,7 @@ void export_sequence() { class_("Sequence") .def(init()) - .def("__str__", &Sequence::get_seq) + .def("__str__", &Sequence::get_seq, return_value_policy()) .def("size", &Sequence::size) .def("__len__", &Sequence::size) //.add_property("header", &Sequence::get_header) diff --git a/py/test/TestSequence.py b/py/test/TestSequence.py new file mode 100644 index 0000000..23cdc93 --- /dev/null +++ b/py/test/TestSequence.py @@ -0,0 +1,22 @@ +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 TestSequence(unittest.TestCase): + def testSimple(self): + seq_text = "AGCT" + s = mussa.Sequence(seq_text) + self.failUnless(len(seq_text) == len(s)) + self.failUnless(len(s) == s.size()) + self.failUnless(str(s) == seq_text) + +def suite(): + return unittest.makeSuite(TestSequence, 'test') + +if __name__ == "__main__": + sys.exit(unittest.main(defaultTest='suite')) diff --git a/qui/MussaAlignedWindow.cpp b/qui/MussaAlignedWindow.cpp index e4c058e..d72ffad 100644 --- a/qui/MussaAlignedWindow.cpp +++ b/qui/MussaAlignedWindow.cpp @@ -49,8 +49,8 @@ void MussaAlignedWindow::setSelectedPaths(Mussa &m, const set& sel_paths) { // sets are sorted set::iterator sel_i = sel_paths.begin(); - list::const_iterator path_i = m.paths().rpbegin(); - list::const_iterator path_end = m.paths().rpend(); + list::const_iterator path_i = m.paths().refined_pathz.begin(); + list::const_iterator path_end = m.paths().refined_pathz.end(); size_t path_size = m.paths().refined_pathz.size(); size_t pathid=0;