From: Diane Trout Date: Sat, 27 May 2006 01:15:29 +0000 (+0000) Subject: add callback for tracking analysis progress X-Git-Url: http://woldlab.caltech.edu/gitweb/?p=mussa.git;a=commitdiff_plain;h=8ec11a1ad6322fef191993fc1441b6389306f369 add callback for tracking analysis progress 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. --- diff --git a/alg/mussa.cpp b/alg/mussa.cpp index 003f68a..0dabf5b 100644 --- a/alg/mussa.cpp +++ b/alg/mussa.cpp @@ -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::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::size_type i = 0; i < the_seqs.size(); i++) for(vector::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 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); diff --git a/alg/mussa.hpp b/alg/mussa.hpp index 2ba1171..cfb9ece 100644 --- a/alg/mussa.hpp +++ b/alg/mussa.hpp @@ -22,6 +22,7 @@ #include #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 to the saved analysis bool thres_append; + //! callback, periodically called as we run an analysis + analysis_callback analysis_cb; //! sequence data std::vector 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 index 0000000..7f73d42 --- /dev/null +++ b/alg/mussa_callback.hpp @@ -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 */ diff --git a/alg/nway_other.cpp b/alg/nway_other.cpp index 70b5bd9..87ee972 100644 --- a/alg/nway_other.cpp +++ b/alg/nway_other.cpp @@ -251,6 +251,9 @@ NwayPaths::trans_path_search(vector > all_comparisons) all_matches); } } + if (progress_cb) { + progress_cb("transitive refinement", win_i, window_num); + } } //clog << "pathz=" << pathz.size() // << " all_cmp=" << all_comparisons.size(); diff --git a/alg/nway_paths.cpp b/alg/nway_paths.cpp index 4f49deb..419d5ed 100644 --- a/alg/nway_paths.cpp +++ b/alg/nway_paths.cpp @@ -15,6 +15,7 @@ #include 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; diff --git a/alg/nway_paths.hpp b/alg/nway_paths.hpp index 10aa6cb..6a1bec8 100644 --- a/alg/nway_paths.hpp +++ b/alg/nway_paths.hpp @@ -19,8 +19,9 @@ #include #include -#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 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 > all_comparisons); void trans_path_search(std::vector > all_comparisons); diff --git a/alg/parse_options.cpp b/alg/parse_options.cpp index 8a777d4..4cafee0 100644 --- a/alg/parse_options.cpp +++ b/alg/parse_options.cpp @@ -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")) { diff --git a/alg/test/test_mussa.cpp b/alg/test/test_mussa.cpp index 8e31eb4..0c4d66d 100644 --- a/alg/test/test_mussa.cpp +++ b/alg/test/test_mussa.cpp @@ -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 result; list > reversed; diff --git a/alg/test/test_nway.cpp b/alg/test/test_nway.cpp index 1c63a4a..4131f83 100644 --- a/alg/test/test_nway.cpp +++ b/alg/test/test_nway.cpp @@ -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::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::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(); } diff --git a/py/getm.py b/py/getm.py index e11d0c3..a36ac37 100644 --- a/py/getm.py +++ b/py/getm.py @@ -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() diff --git a/py/mussa.cpp b/py/mussa.cpp index ac29ff5..e8bcfb8 100644 --- a/py/mussa.cpp +++ b/py/mussa.cpp @@ -7,6 +7,7 @@ using namespace boost::python; void export_mussa() { 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") diff --git a/qui/MussaWindow.cpp b/qui/MussaWindow.cpp index 354f8b6..a34f1c1 100644 --- a/qui/MussaWindow.cpp +++ b/qui/MussaWindow.cpp @@ -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) { diff --git a/qui/mussa_setup_dialog/MussaSetupWidget.cpp b/qui/mussa_setup_dialog/MussaSetupWidget.cpp index 279231b..11f53b7 100644 --- a/qui/mussa_setup_dialog/MussaSetupWidget.cpp +++ b/qui/mussa_setup_dialog/MussaSetupWidget.cpp @@ -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;