build the python interface
authorDiane Trout <diane@caltech.edu>
Wed, 12 Apr 2006 00:45:55 +0000 (00:45 +0000)
committerDiane Trout <diane@caltech.edu>
Wed, 12 Apr 2006 00:45:55 +0000 (00:45 +0000)
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.

CMakeLists.txt
alg/mussa.hpp
alg/nway_paths.hpp
py/CMakeLists.txt [new file with mode: 0644]
py/mussa.cpp
py/nway_paths.cpp
py/sequence.cpp
py/test/TestSequence.py [new file with mode: 0644]
qui/MussaAlignedWindow.cpp

index 0709be1e83c15f27147c9aa17c305757849e4f48..d9a0563c61bd24934d33ac28de775e1b6a18ee99 100644 (file)
@@ -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 )
 
index 675658d4a65ad55a2b2f71076a48f363afe87cdb..0a724e7904450899175eeec336dfe9e154e4bec2 100644 (file)
@@ -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)
index 01c4be0f09a57ce3bd2d28a2bfb7facd71ba8c0d..acbef47475a70a62b36e3879946b3bf284fef690 100644 (file)
@@ -70,16 +70,15 @@ class NwayPaths
     void save_old(boost::filesystem::path save_file_path);
     void print(std::list<std::vector<int> >&);
 
+    // The following iterator functions are mostly for the python interface
+    // they'll have problems when being called from within a const object
     std::list<ConservedPath>::iterator pbegin() { return pathz.begin() ; }
     std::list<ConservedPath>::iterator pend() { return pathz.end() ; }
-    std::list<ConservedPath>::const_iterator pbegin() const { return pathz.begin() ; }
-    std::list<ConservedPath>::const_iterator pend() const { return pathz.end() ; }
     size_t path_size() const { return refined_pathz.size(); }
     std::list<ExtendedConservedPath>::iterator rpbegin() { return refined_pathz.begin() ; }
-    std::list<ExtendedConservedPath>::const_iterator rpend() const { return refined_pathz.end() ; }
-    std::list<ExtendedConservedPath>::const_iterator rpbegin() const { return refined_pathz.begin() ; }
     std::list<ExtendedConservedPath>::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<ConservedPath> pathz;
diff --git a/py/CMakeLists.txt b/py/CMakeLists.txt
new file mode 100644 (file)
index 0000000..6c88db9
--- /dev/null
@@ -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)
+
index 55e5a2fd2c17a409f0ed1d451e87fd4120e2a152..b82cb43f2e589f5408a94ce8b7f565e8b284df30 100644 (file)
@@ -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>("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 "
index 73a13a9ec3034043041f672df0ee494edd843995..ee44e88e413adf4030a2fa1cc7585097764c9b1b 100644 (file)
@@ -6,10 +6,7 @@ using namespace boost::python;
 void export_nway_paths()
 {
   class_<NwayPaths>("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)) ;
 }
 
index be7a73cad652ac4d13a8243ea7ff75fa70ea467f..3167d56b1ec9edfe6a9eb6e05e856c8e606af6c5 100644 (file)
@@ -8,7 +8,7 @@ void export_sequence()
 {
   class_<Sequence>("Sequence")
     .def(init<std::string>())
-    .def("__str__", &Sequence::get_seq)
+    .def("__str__", &Sequence::get_seq, return_value_policy<return_by_value>())
     .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 (file)
index 0000000..23cdc93
--- /dev/null
@@ -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'))
index e4c058ef7bf99a8fb3ad7dcbaf3b281fa985324b..d72ffad34f3f680b2cfd9ac1da9dcd5aca24b58e 100644 (file)
@@ -49,8 +49,8 @@ void MussaAlignedWindow::setSelectedPaths(Mussa &m, const set<int>& sel_paths)
 {
   // sets are sorted
   set<int>::iterator sel_i = sel_paths.begin();
-  list<ExtendedConservedPath>::const_iterator path_i = m.paths().rpbegin();
-  list<ExtendedConservedPath>::const_iterator path_end = m.paths().rpend();
+  list<ExtendedConservedPath>::const_iterator path_i = m.paths().refined_pathz.begin();
+  list<ExtendedConservedPath>::const_iterator path_end = m.paths().refined_pathz.end();
   size_t path_size = m.paths().refined_pathz.size();
   size_t pathid=0;