Extend the python mussa interface.
[mussa.git] / py / mussa.cpp
index b82cb43f2e589f5408a94ce8b7f565e8b284df30..cd46d4941ff1e9de5f168e82ac595e7b7d48c268 100644 (file)
@@ -1,37 +1,61 @@
 #include <boost/python.hpp>
-
-using namespace boost::python;
+namespace py = boost::python;
 
 #include "alg/mussa.hpp"
+#include "alg/sequence.hpp"
+#include "stl_container_adapter.hpp"
 
 void export_mussa()
 {
-  //BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(mussa_analyze_overloads, 
-  //                                       &Mussa::analyze, 0, 4);
+  void (Mussa::*save_string)(const std::string &) = &Mussa::save;
+  void (Mussa::*load_mupa_string)(const std::string &) = &Mussa::load_mupa_file;
+  void (Mussa::*load_string)(const std::string &) = &Mussa::load;
+  void (Mussa::*append_sequence_ref)(const Sequence&) = &Mussa::append_sequence;
+  void (Mussa::*append_sequence_ptr)(const boost::shared_ptr<Sequence>) = &Mussa::append_sequence;
 
-  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")
+  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", py::no_init)
+    .def("save", save_string, "Save analysis in the specified directory")
+    .def("load", load_string, "Load previous run analysis")
     .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 "
-                               "in this analysis")
+    .add_property("name", &Mussa::get_name, &Mussa::set_name, "Set the name of the analysis")
+    .def("size", &Mussa::size, "Number of sequences attached to "
+                               "this analysis")
     .add_property("window", &Mussa::get_window, &Mussa::set_window,
                   "the number of base pairs in the sliding window")
     .add_property("threshold", &Mussa::get_threshold, &Mussa::set_threshold,
                   "how many base pairs must match between two windows")
-    .def("softThreshold", &Mussa::set_soft_thres)
+    .add_property("softThreshold", &Mussa::get_soft_threshold,
+                  &Mussa::set_soft_threshold)
     .add_property("analysisMode", &Mussa::get_analysis_mode, 
                                    &Mussa::set_analysis_mode)
     .add_property("analysisModeName", &Mussa::get_analysis_mode_name)
     .def("analyze", &Mussa::analyze, "Run the analysis")
-    .def("paths", &Mussa::paths, return_internal_reference<>())
-    //.def("sequences", &Mussa::sequences)
-    .def("addSequence", &Mussa::add_a_seq)  ;
-
-  enum_<Mussa::analysis_modes>("analysis_modes")
+    .def("paths", &Mussa::paths, py::return_internal_reference<>(), "return list of paths")
+    .def("sequences", &Mussa::sequences, py::return_internal_reference<>(), "return list of sequences")
+    .def("add_sequence", append_sequence_ref, "attach a sequence to the analysis")  
+  ;
+  py::def("Mussa", &Mussa::init, 
+          "Construct a new Mussa object.\n"
+          "You can use this to load a previous analysis or to construct\n"
+          "a new analysis.\n");
+  py::register_ptr_to_python< boost::shared_ptr<Mussa> >();
+  
+  py::enum_<Mussa::analysis_modes>("analysis_modes")
     .value("TransitiveNway", Mussa::TransitiveNway )
     .value("RadialNway", Mussa::RadialNway )
     .value("EntropyNway", Mussa::EntropyNway )