add callback for tracking analysis progress
authorDiane Trout <diane@caltech.edu>
Sat, 27 May 2006 01:15:29 +0000 (01:15 +0000)
committerDiane Trout <diane@caltech.edu>
Sat, 27 May 2006 01:15:29 +0000 (01:15 +0000)
This version just writes the information to standard out, but
the callback should be useable bythe the GUI.

also I killed the parameters to analyze(), you need to customize the class
in order setup the analysis.

13 files changed:
alg/mussa.cpp
alg/mussa.hpp
alg/mussa_callback.hpp [new file with mode: 0644]
alg/nway_other.cpp
alg/nway_paths.cpp
alg/nway_paths.hpp
alg/parse_options.cpp
alg/test/test_mussa.cpp
alg/test/test_nway.cpp
py/getm.py
py/mussa.cpp
qui/MussaWindow.cpp
qui/mussa_setup_dialog/MussaSetupWidget.cpp

index 003f68aac8e045e2b8b309133c2914b75b167f2e..0dabf5b435274af524935f8654212c1f28d73a14 100644 (file)
@@ -24,6 +24,11 @@ namespace fs = boost::filesystem;
 
 using namespace std;
 
+void callback(const std::string& desc, int cur, int end)
+{
+  std::cout << "analysis:" << desc << " " << cur << "/" << end << std::endl;
+}
+
 Mussa::Mussa()
 {
   clear();
@@ -37,6 +42,7 @@ Mussa::Mussa(const Mussa& m)
     ana_mode(m.ana_mode),
     win_append(m.win_append),
     thres_append(m.thres_append),
+    analysis_cb(m.analysis_cb),
     motif_sequences(m.motif_sequences),
     color_mapper(m.color_mapper)
 {
@@ -53,6 +59,7 @@ Mussa::clear()
   soft_thres = 0;
   win_append = false;
   thres_append = false;
+  analysis_cb = callback;
   motif_sequences.clear();
   color_mapper.clear();
 }
@@ -80,6 +87,17 @@ Mussa::size() const
     return 0;
 }
 
+
+void Mussa::set_analysis_callback(analysis_callback cb)
+{
+  analysis_cb = cb;
+}
+
+analysis_callback Mussa::get_analysis_calback() const
+{
+  return analysis_cb;
+}
+
 void
 Mussa::set_window(int a_window)
 {
@@ -388,23 +406,13 @@ Mussa::load_mupa_file(fs::path para_file_path)
 
 
 void
-Mussa::analyze(int w, int t, enum Mussa::analysis_modes the_ana_mode, double new_ent_thres)
+Mussa::analyze()
 {
   time_t t1, t2, begin, end;
   double seqloadtime, seqcomptime, nwaytime, savetime, totaltime;
 
   begin = time(NULL);
 
-  ana_mode = the_ana_mode;
-  ent_thres = new_ent_thres;
-  if (w > 0)
-    window  = w;
-  if (t > 0)
-  {
-    threshold = t;
-    soft_thres = t;
-  }
-
   t1 = time(NULL);
         
   if (the_seqs.size() < 2) {
@@ -421,7 +429,6 @@ Mussa::analyze(int w, int t, enum Mussa::analysis_modes the_ana_mode, double new
   t2 = time(NULL);
   seqcomptime = difftime(t2, t1);
 
-
   t1 = time(NULL);
   the_paths.setup(window, threshold);
   nway();
@@ -463,6 +470,9 @@ Mussa::seqcomp()
   for(vector<Sequence>::size_type i = 0; i < the_seqs.size(); i++)
     seq_lens.push_back(the_seqs[i].size());
 
+  int seqcomps_done = 0;
+  int seqcomps_todo = (the_seqs.size() * (the_seqs.size()-1)) / 2;
+
   for(vector<Sequence>::size_type i = 0; i < the_seqs.size(); i++)
     for(vector<Sequence>::size_type i2 = i+1; i2 < the_seqs.size(); i2++)
     {
@@ -470,6 +480,10 @@ Mussa::seqcomp()
       all_comps[i][i2].setup(window, threshold);
       all_comps[i][i2].seqcomp(the_seqs[i].get_seq(), the_seqs[i2].get_seq(), false);
       all_comps[i][i2].seqcomp(the_seqs[i].get_seq(),the_seqs[i2].rev_comp(),true);
+      ++seqcomps_done;
+      if (analysis_cb) {
+        analysis_cb("seqcomp", seqcomps_done, seqcomps_todo);
+      } 
     }
 }
 
@@ -479,6 +493,7 @@ Mussa::nway()
   vector<string> some_Seqs;
 
   the_paths.set_soft_threshold(soft_thres);
+  the_paths.set_progress_callback(analysis_cb);
 
   if (ana_mode == TransitiveNway) {
     the_paths.trans_path_search(all_comps);
index 2ba11719bed212cbef33c4ce9093652a2919451c..cfb9ece6b95b9ef95d4ffce13283e8b9d03081b9 100644 (file)
@@ -22,6 +22,7 @@
 #include <istream>
 
 #include "alg/annotation_colors.hpp"
+#include "alg/mussa_callback.hpp"
 #include "alg/nway_paths.hpp"
 #include "alg/sequence.hpp"
 
@@ -29,7 +30,6 @@ std::string int_to_str(int an_int);
 
 class Mussa
 {
-  friend class ConnWindow;
   public:
     enum analysis_modes { TransitiveNway, RadialNway, EntropyNway, 
                           RecursiveNway };
@@ -62,6 +62,10 @@ class Mussa
      *  (silly delayed loading of sequence data)
      */
     int size() const;
+
+    void set_analysis_callback(analysis_callback cb);
+    analysis_callback get_analysis_calback() const;
+
     //! set number of bases for this window size
     void set_window(int a_window);
     //! get number of bases for the sliding window
@@ -94,12 +98,9 @@ class Mussa
     //! run seqcomp and the nway filtering algorithm.
     /*!analyze will run seqcomp and then the nway algorithm
      * on whatever sequences have been loaded into this mussa instance.
-     * w & t are for command line override functionality, set to 0 to ignore
      * \throws mussa_analysis_error 
      */
-    void analyze(int w=0, int t=0, 
-                 enum analysis_modes ana_mode=TransitiveNway,
-                 double ent_thres=0.0);
+    void analyze();
     /*! Run the nway filtering algorithm, 
      *  this might be used when changing the soft threshhold?
      */
@@ -173,6 +174,8 @@ class Mussa
     bool win_append; 
     //! should we append _t<threshold> to the saved analysis
     bool thres_append;
+    //! callback, periodically called as we run an analysis
+    analysis_callback analysis_cb;
 
     //! sequence data
     std::vector<Sequence> the_seqs;
@@ -187,7 +190,7 @@ class Mussa
     AnnotationColors color_mapper;
 
     // Private methods
-    //! loads sequence and annotations from fasta and annotation file
+    //! runs all the seqcomps needed to support the nway comparison
     void seqcomp();
 
 };
diff --git a/alg/mussa_callback.hpp b/alg/mussa_callback.hpp
new file mode 100644 (file)
index 0000000..7f73d42
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef _MUSSA_CALLBACK_HPP
+#define _MUSSA_CALLBACK_HPP
+
+typedef void (*analysis_callback)(const std::string& name, int step, int max_step);
+
+#endif /* _MUSSA_CALLBACK_HPP */
index 70b5bd9e35f143d946cacf716ab5a54b465821d5..87ee972e48a21d00c3495f401d15d4861db36b87 100644 (file)
@@ -251,6 +251,9 @@ NwayPaths::trans_path_search(vector<vector<FLPs> > all_comparisons)
                                             all_matches);
       }
     }
+    if (progress_cb) {
+      progress_cb("transitive refinement", win_i, window_num);
+    }
   }
   //clog << "pathz=" << pathz.size()
   //     << " all_cmp=" << all_comparisons.size();
index 4f49deb6806c4694c47faac9112b19a7c582af98..419d5edfbf03441171fb3f32add1fdd8f609aced 100644 (file)
@@ -15,6 +15,7 @@
 #include <boost/filesystem/fstream.hpp>
 namespace fs = boost::filesystem;
 
+#include "alg/mussa_callback.hpp"
 #include "alg/nway_paths.hpp"
 #include "alg/conserved_path.hpp"
 #include "mussa_exceptions.hpp"
@@ -25,6 +26,7 @@ namespace fs = boost::filesystem;
 using namespace std;
 
 NwayPaths::NwayPaths()
+  : progress_cb(0)
 {
 }
 
@@ -34,6 +36,7 @@ NwayPaths::setup(int w, int t)
   threshold = t;
   soft_thres = threshold;
   win_size = w;
+  progress_cb = 0;
   pathz.clear();
 
   //cout << "nway: thres = " << threshold
@@ -56,6 +59,16 @@ int NwayPaths::get_window() const
   return win_size;
 }
 
+void NwayPaths::set_progress_callback(analysis_callback cb)
+{
+  progress_cb = cb;
+}
+
+analysis_callback NwayPaths::get_progress_callback() const
+{
+  return progress_cb;
+}
+
 // dumbly goes thru and combines path windows exactly adjacent (ie + 1 index)
 // doesn't deal with interleaved adjacency
 void
@@ -72,17 +85,20 @@ NwayPaths::simple_refine()
 
   //cout << "path number is: " << pathz.size() << endl;
   pathz_i = pathz.begin();
+  int path_count = 0;
 
   // only try to extend when pathz isn't empty.
   if (pathz_i != pathz.end())
   {
     ext_path = *pathz_i;
+    ++path_count;
 
     while(pathz_i != pathz.end())
     {
       // keep track of current path and advance to next path
       cur_path = pathz_i;
       ++pathz_i;
+      ++path_count;
 
       if (pathz_i == pathz.end()) {
         end = true;
@@ -111,6 +127,9 @@ NwayPaths::simple_refine()
           ext_path = *next_path;
         }
       }
+      if (progress_cb) {
+        progress_cb("refine", path_count-1, pathz.size());
+      }
     }
   }
   //cout << "r_path number is: " << refined_pathz.size() << endl;
index 10aa6cba8581d861d0b47773b02d5adb8334ce46..6a1bec85eead18aac4afddc7693fc53df5d325d2 100644 (file)
@@ -19,8 +19,9 @@
 #include <string>
 #include <vector>
 
-#include "alg/flp.hpp"
 #include "alg/conserved_path.hpp"
+#include "alg/flp.hpp"
+#include "alg/mussa_callback.hpp"
 
 class NwayPaths
 {
@@ -33,6 +34,7 @@ class NwayPaths
 
     double ent_thres;
     std::vector<char *> c_sequences; //used by entropy_path_search
+    analysis_callback progress_cb;
 
   public:
     NwayPaths();
@@ -45,6 +47,10 @@ class NwayPaths
     int get_threshold() const;
     //! return window size used for this analysis
     int get_window() const;
+    //! set analysis progress callback
+    void set_progress_callback(analysis_callback cb);
+    //! get analysis progress callback
+    analysis_callback get_progress_callback() const;
 
     void radiate_path_search(std::vector<std::vector<FLPs> > all_comparisons);
     void trans_path_search(std::vector<std::vector<FLPs> > all_comparisons);
index 8a777d4b740c3d90ac25a43bd5ce4ebb892042f4..4cafee0d213924f4c111ee455c012141cacc86c4 100644 (file)
@@ -40,6 +40,7 @@ void initialize_mussa(MussaOptions& opts, int argc, char **argv)
   }
 
   opts.analysis = new Mussa();
+
   // currently we can only have one analysis loaded, so 
   // running trumps viewing.
   if (vm.count("run-analysis")) {
index 8e31eb4de4bb9b1b6a6c28c694f7883b21f1809f..0c4d66d21d2550f429e11ddf9cb966e6de62543d 100644 (file)
@@ -95,7 +95,7 @@ BOOST_AUTO_TEST_CASE( mussa_load_mupa )
 
   Mussa m1;
   m1.load_mupa_file( mupa_path );
-  m1.analyze(0, 0);
+  m1.analyze();
   BOOST_CHECK_EQUAL( m1.get_name(), std::string("mck3test") );
   BOOST_CHECK( m1.size() > 0 );
 
@@ -112,7 +112,7 @@ BOOST_AUTO_TEST_CASE( mussa_load_full_path )
   Mussa m1;
   fs::path full_path(fs::path(EXAMPLE_DIR) / "mck3test.mupa");
   m1.load_mupa_file( full_path );
-  m1.analyze(0, 0);
+  m1.analyze();
 
   BOOST_CHECK( m1.size() > 0);
   BOOST_CHECK_EQUAL( m1.get_window(), 30 );
@@ -124,7 +124,7 @@ BOOST_AUTO_TEST_CASE( mussa_load_analysis )
   fs::path example_dir(EXAMPLE_DIR);
   Mussa m1;
   m1.load_mupa_file( example_dir / "mck3test.mupa" );
-  m1.analyze(0, 0);
+  m1.analyze();
 
   Mussa m2;
   m2.load( fs::initial_path() / "mck3test_w30_t20");
@@ -214,7 +214,9 @@ BOOST_AUTO_TEST_CASE( local_alignment )
   Mussa analysis;
   analysis.add_a_seq(s0);
   analysis.add_a_seq(s1);
-  analysis.analyze(4,3);
+  analysis.set_threshold(3);
+  analysis.set_window(4);
+  analysis.analyze();
   NwayPaths npath = analysis.paths();
   list<ConservedPath::path_type> result;
   list<vector<bool> > reversed;
index 1c63a4a9681af26cdcc8883f3a377ed75c960b41..4131f83ab3c1ac65a86b71825f586efd97c62927 100644 (file)
@@ -22,7 +22,9 @@ BOOST_AUTO_TEST_CASE( nway_null )
   analysis.add_a_seq(s0);
   analysis.add_a_seq(s1);
   analysis.add_a_seq(s2);
-  analysis.analyze(4,3);
+  analysis.set_window(4);
+  analysis.set_threshold(3);
+  analysis.analyze();
   NwayPaths npath = analysis.paths();
   // there should be no paths for these sequences
   for (std::list<ConservedPath >::iterator pathz_i = npath.pathz.begin();
@@ -42,7 +44,9 @@ BOOST_AUTO_TEST_CASE( nway_test )
   Mussa analysis;
   analysis.add_a_seq(s0);
   analysis.add_a_seq(s1);
-  analysis.analyze(4,3);
+  analysis.set_window(4);
+  analysis.set_threshold(3);
+  analysis.analyze();
   NwayPaths npath = analysis.paths();
   for (std::list<ConservedPath >::iterator pathz_i = npath.pathz.begin();
        pathz_i != npath.pathz.end();
@@ -63,7 +67,7 @@ BOOST_AUTO_TEST_CASE( nway_refine )
   mupa_path /= "mck3test.mupa";
   Mussa m1;
   m1.load_mupa_file( mupa_path );
-  m1.analyze(0, 0);
+  m1.analyze();
   const NwayPaths& npath = m1.paths();
   BOOST_CHECK_EQUAL (npath.path_size(), npath.refined_path_size());
   size_t first_refined_size = npath.refined_path_size();
@@ -183,7 +187,9 @@ GTTTTAATAAATGCACAATGCTCTCTTCCTGTTCTTC";
   m1.add_a_seq(seq2);
   m1.add_a_seq(seq3);
 
-  m1.analyze(10, 8);
+  m1.set_window(10);
+  m1.set_threshold(8);
+  m1.analyze();
   m1.set_soft_threshold(10);
   m1.nway();
 }
index e11d0c3cfc61b73d84ff402151354a8cf13e3925..a36ac370f6a2bea47576b03e0f5d57b4baaa8e4c 100644 (file)
@@ -3,7 +3,7 @@
 import mussa
 m = mussa.Mussa()
 #m.load_mupa("examples/mck3test.mupa")
-#m.analyze(0, 0, mussa.analysis_modes.TransitiveNway, 0)
+#m.analyze()
 m.load("../../mussa_analyses/land/myogenin_w30_t21")
 path = m.paths()
 
index ac29ff5cdb61926ba1096b12a712b936bb4f30c9..e8bcfb8a2ebcfc86a2f4836dd6ad17cd55b2468e 100644 (file)
@@ -7,6 +7,7 @@ using namespace boost::python;
 void export_mussa()
 {
   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")
index 354f8b65697f8560350b321992c4f8dac3daf019..a34f1c168f131e953c29c7c1de020091bf69dde2 100644 (file)
@@ -352,7 +352,7 @@ void MussaWindow::loadMupa()
     Mussa *m = new Mussa;
     fs::path converted_path(mupa_path.toStdString(), fs::native);
     m->load_mupa_file(converted_path);
-    m->analyze(0, 0, Mussa::TransitiveNway, 0.0);
+    m->analyze();
     setAnalysis(m);
     setWindowTitle(converted_path.native_file_string().c_str());
   } catch (mussa_load_error e) {
index 279231b940ed09302a4e402c0c7d79e178e66472..11f53b79eaa5d088fbde8f94c4d34f3d042ad0b3 100644 (file)
@@ -128,7 +128,11 @@ Mussa* MussaSetupWidget::getMussaObject()
   if (win_size == 0 or threshold == 0) {
     throw mussa_load_error("must set analysis parameters");
   } else {
-    mussa->analyze(win_size, threshold, Mussa::TransitiveNway, 0.0);
+    mussa->set_window(win_size);
+    mussa->set_threshold(threshold);
+    mussa->set_analysis_mode(Mussa::TransitiveNway);
+    //mussa->set_entropy(0); // might want to add this at some point
+    mussa->analyze();
   }
 
   return mussa;