From: Diane Trout Date: Mon, 20 Mar 2006 08:58:30 +0000 (+0000) Subject: Mussa aligned sequence view seems to work X-Git-Url: http://woldlab.caltech.edu/gitweb/?p=mussa.git;a=commitdiff_plain;h=07bb84ff490b0af983779b12ec75186f9ac73037 Mussa aligned sequence view seems to work I added a "normalizedIndexes" to the ConservedPath classes to return vectors which don't have any negative path values. I also think the use of menu entries is a bit annoying as it wont extend well to large numbers of selected paths. Additionally, deselecting an alignment doesnt seem to do much as I suspect there's a fair amount of overlap betwen the various alignments. But i was eventually able to make them all go away. --- diff --git a/alg/conserved_path.cpp b/alg/conserved_path.cpp index af8af7d..a3778da 100644 --- a/alg/conserved_path.cpp +++ b/alg/conserved_path.cpp @@ -142,6 +142,23 @@ vector ConservedPath::reverseComplimented() const } +std::vector ConservedPath::normalizedIndexes() const +{ + vector paths; + for (ConservedPath::const_iterator this_itor = begin(); + this_itor != end(); + ++this_itor) + { + if (*this_itor < 0) { + paths.push_back(-*this_itor); + } else { + paths.push_back(*this_itor); + } + } + return paths; +} + + ///////////////////// ExtendedConservedPath::ExtendedConservedPath() : ConservedPath(), @@ -169,6 +186,22 @@ ExtendedConservedPath::ExtendedConservedPath(int win_size, { } +std::vector ExtendedConservedPath::normalizedIndexes() const +{ + vector paths; + for (ConservedPath::const_iterator this_itor = begin(); + this_itor != end(); + ++this_itor) + { + if (*this_itor < 0) { + paths.push_back(-(*this_itor) - window_size); + } else { + paths.push_back((*this_itor)); + } + } + return paths; +} + ExtendedConservedPath& ExtendedConservedPath::extend(int growth) { window_size += growth; diff --git a/alg/conserved_path.hpp b/alg/conserved_path.hpp index cc2dda1..6217474 100644 --- a/alg/conserved_path.hpp +++ b/alg/conserved_path.hpp @@ -38,6 +38,8 @@ struct ConservedPath bool nextTo(const ConservedPath& next) const; //! indicate which elements of the path are reversed std::vector reverseComplimented() const; + //! return the list of indexes normalized (to the left) + std::vector normalizedIndexes() const; //! either number of conserved bases or average entropy double score; @@ -52,6 +54,7 @@ struct ExtendedConservedPath : public ConservedPath ExtendedConservedPath(int win_size, ConservedPath conserved_path); ExtendedConservedPath(int win_size, double score, std::vector path); + std::vector ExtendedConservedPath::normalizedIndexes() const; //! extend our current path /*! (aka increment our window size by growth) */ diff --git a/alg/glseqbrowser.cpp b/alg/glseqbrowser.cpp index ea5dc2e..0b85cb8 100644 --- a/alg/glseqbrowser.cpp +++ b/alg/glseqbrowser.cpp @@ -314,12 +314,10 @@ const std::vector& GlSeqBrowser::sequences() const void GlSeqBrowser::clear_links() { - path_segment_map_vector::iterator psmv_i; - for(psmv_i = path_segments.begin(); - psmv_i != path_segments.end(); - ++psmv_i) + path_segments.clear(); + for (int i = track_container.size()-1; i > 0; --i) { - psmv_i->clear(); + path_segments.push_back(pair_segment_map()); } } @@ -379,7 +377,8 @@ void GlSeqBrowser::centerOnPath(const vector& paths) for(size_t track_i = 0; track_i != track_container.size(); ++track_i) { - track_container[track_i].setX(viewport_center - paths[track_i]); + // -15 = shift more to the left + track_container[track_i].setX((viewport_center-15) - paths[track_i]); } } diff --git a/alg/test/test_conserved_path.cpp b/alg/test/test_conserved_path.cpp index ec1b54c..7050a73 100644 --- a/alg/test/test_conserved_path.cpp +++ b/alg/test/test_conserved_path.cpp @@ -137,3 +137,25 @@ BOOST_AUTO_TEST_CASE ( extended_conserved_path_growth ) ecp_base.extend(growth); BOOST_CHECK_EQUAL( ecp_base.window_size, window_size + growth ); } + +BOOST_AUTO_TEST_CASE ( extended_conserved_normalized ) +{ + vector path; + path += 3,-14,5,-19; // magic from boost assign + vector normalized_path; + normalized_path += 3,4, 5,9; + + ExtendedConservedPath ecp1; + ecp1.window_size = 10; + ecp1.score = 18; + ecp1.track_indexes = path; + BOOST_CHECK_EQUAL ( ecp1.size(), path.size() ); + + vector normalized_index(ecp1.normalizedIndexes()); + + for(int i=0; i != ecp1.size(); ++i) + { + BOOST_CHECK_EQUAL(normalized_index[i], normalized_path[i]); + } +} + diff --git a/alg/test/test_glseqbrowser.cpp b/alg/test/test_glseqbrowser.cpp index 3641d08..0a3f8c9 100644 --- a/alg/test/test_glseqbrowser.cpp +++ b/alg/test/test_glseqbrowser.cpp @@ -74,13 +74,13 @@ BOOST_AUTO_TEST_CASE( glseqbrowser_center ) // I didn't bother to compute how the path should shift things // by the magic number 3, i just ran the test and saw how it failed // and hard coded this in. - BOOST_CHECK_EQUAL( gt.left(), -3-gt.border() ); - BOOST_CHECK_EQUAL( gt.right(), 3 + s0.size() + gt.border() ); + BOOST_CHECK_EQUAL( gt.left(), -18-gt.border() ); + BOOST_CHECK_EQUAL( gt.right(), s0.size() + gt.border()-11 ); // aparently we end up with a different glsequence in the seqbrowser BOOST_CHECK( glseq1.x() != gt.sequences()[1].x() ); - BOOST_CHECK_EQUAL( gt.sequences()[0].x(), gt.viewportCenter()-path[0] ); - BOOST_CHECK_EQUAL( gt.sequences()[1].x(), gt.viewportCenter()-path[1] ); - BOOST_CHECK_EQUAL( gt.sequences()[2].x(), gt.viewportCenter()-path[2] ); + BOOST_CHECK_EQUAL( gt.sequences()[0].x(), (gt.viewportCenter()-15)-path[0] ); + BOOST_CHECK_EQUAL( gt.sequences()[1].x(), (gt.viewportCenter()-15)-path[1] ); + BOOST_CHECK_EQUAL( gt.sequences()[2].x(), (gt.viewportCenter()-15)-path[2] ); } diff --git a/mussagl.pro b/mussagl.pro index 7228685..c7e5aea 100644 --- a/mussagl.pro +++ b/mussagl.pro @@ -17,6 +17,7 @@ HEADERS += mussa_exceptions.hpp \ qui/ThresholdWidget.hpp \ qui/ImageScaler.hpp \ qui/ImageSaveDialog.hpp \ + qui/IntAction.hpp \ qui/seqbrowser/SequenceBrowserWidget.hpp \ qui/seqbrowser/SequenceBrowser.hpp \ qui/seqbrowser/SequenceBrowserSidebar.hpp \ @@ -38,6 +39,7 @@ SOURCES += mussagl.cpp \ qui/ThresholdWidget.cpp \ qui/ImageScaler.cpp \ qui/ImageSaveDialog.cpp \ + qui/IntAction.cpp \ qui/seqbrowser/SequenceBrowserWidget.cpp \ qui/seqbrowser/SequenceBrowser.cpp \ qui/seqbrowser/SequenceBrowserSidebar.cpp \ diff --git a/qui/IntAction.cpp b/qui/IntAction.cpp new file mode 100644 index 0000000..f2c5ff4 --- /dev/null +++ b/qui/IntAction.cpp @@ -0,0 +1,16 @@ +#include "qui/IntAction.hpp" + +#include +using namespace std; + +IntAction::IntAction(const QString &text, int value, QObject*parent) + : QAction(text, parent), + val(value) +{ + connect(this, SIGNAL(triggered()), this, SLOT(triggerWithValue())); +} + +void IntAction::triggerWithValue() +{ + emit triggered(val); +} diff --git a/qui/IntAction.hpp b/qui/IntAction.hpp new file mode 100644 index 0000000..38dac89 --- /dev/null +++ b/qui/IntAction.hpp @@ -0,0 +1,26 @@ +#ifndef _INT_ACTION_H +#define _INT_ACTION_H + +#include +#include + +class IntAction : public QAction +{ + Q_OBJECT + +public: + IntAction(const QString &text, int value, QObject*parent=0); + + int value() const { return val; } + +public slots: + void triggerWithValue(); + +signals: + void triggered(int); + +private: + int val; +}; +#endif + diff --git a/qui/MussaAlignedWindow.cpp b/qui/MussaAlignedWindow.cpp index e54f099..e3735bd 100644 --- a/qui/MussaAlignedWindow.cpp +++ b/qui/MussaAlignedWindow.cpp @@ -2,7 +2,9 @@ #include #include -#include +#include +#include +#include #include "qui/MussaAlignedWindow.hpp" #include "alg/sequence.hpp" @@ -12,25 +14,25 @@ using namespace std; MussaAlignedWindow::MussaAlignedWindow(Mussa& m, const set& sel_paths, QWidget *parent) - : QWidget(parent), - analysis(m)//, - //selected_paths(sel_paths) - + : QMainWindow(parent), + analysis(m), + pick_align_menu(tr("Choose Alignment")), + view_align_menu(tr("View Alignment")) { browser.setSequences(analysis.sequences(), analysis.colorMapper()); setSelectedPaths(m, sel_paths); setAlignment(0); browser.zoomToSequence(); computeMatchLines(); + setupMenus(); - QVBoxLayout *layout = new QVBoxLayout; - layout->addWidget(&browser); - layout->addWidget(&status); - setLayout(layout); + setCentralWidget(&browser); + menuBar()->addMenu(&pick_align_menu); + menuBar()->addMenu(&view_align_menu); ostringstream message; message << "Selected " << selected_paths.size() << " paths"; - status.showMessage(message.str().c_str(), 5000); + statusBar()->showMessage(message.str().c_str(), 5000); } @@ -44,13 +46,14 @@ void MussaAlignedWindow::setSelectedPaths(Mussa &m, const set& sel_paths) size_t pathid=0; selected_paths.reserve(sel_paths.size()); + view_paths.reserve(sel_paths.size()); while (pathid != path_size and sel_i != sel_paths.end()) { assert (*sel_i >= 0); size_t sel_pathid = (size_t)(*sel_i); if (pathid == sel_pathid) { - cout << "found one " << *path_i << endl; selected_paths.push_back(*path_i); + view_paths.push_back(true); ++pathid; ++path_i; ++sel_i; @@ -63,13 +66,59 @@ void MussaAlignedWindow::setSelectedPaths(Mussa &m, const set& sel_paths) } } +void MussaAlignedWindow::setupMenus() +{ + pick_align_menu.clear(); + view_align_menu.clear(); + pick_actions.clear(); + view_actions.clear(); + + for(vector::iterator pathz_i=selected_paths.begin(); + pathz_i != selected_paths.end(); + ++pathz_i) + { + ConservedPath::path_type normalized_path = pathz_i->normalizedIndexes(); + ostringstream menu_text; + menu_text << pathz_i->window_size << ":"; + ConservedPath::iterator element_i = normalized_path.begin(); + menu_text << *element_i++; + for (; + element_i != normalized_path.end(); + ++element_i) + { + menu_text << ", "; + menu_text << *element_i; + } + int index = pathz_i - selected_paths.begin(); + IntAction *pick = new IntAction(QString(menu_text.str().c_str()), index, this); + connect(pick, SIGNAL(triggered(int)), this, SLOT(setAlignment(size_t))); + pick_actions.push_back(pick); + pick_align_menu.addAction(pick); + IntAction *view = new IntAction(QString(menu_text.str().c_str()), index, this); + connect(view, SIGNAL(triggered(int)), this, SLOT(toggleViewAlignment(size_t))); + view->setCheckable(true); + view->setChecked(true); + view_actions.push_back(view); + view_align_menu.addAction(view); + } +} + void MussaAlignedWindow::setAlignment(size_t alignment_index) { if (selected_paths.size() > 0) { - browser.centerOnPath(selected_paths[alignment_index].track_indexes); + browser.centerOnPath(selected_paths[alignment_index].normalizedIndexes()); } } +void MussaAlignedWindow::toggleViewAlignment(size_t alignment_index) +{ + view_paths[alignment_index]= not view_paths[alignment_index]; + // perhaps it'd be better if we could erase specific sets + // of matches instead of erasing them all and recomputing them all + // but this is easier + computeMatchLines(); +} + void MussaAlignedWindow::computeMatchLines() { const vector& raw_sequence = analysis.sequences(); @@ -85,12 +134,13 @@ void MussaAlignedWindow::computeMatchLines() vector matched; int align_counter; + browser.clear_links(); align_counter = 0; for(vector::iterator pathz_i=selected_paths.begin(); pathz_i != selected_paths.end(); ++pathz_i) { - if (true /* show_aligns[align_counter] */) + if (view_paths[align_counter]) { ExtendedConservedPath& a_path = *pathz_i; window_length = a_path.window_size; diff --git a/qui/MussaAlignedWindow.hpp b/qui/MussaAlignedWindow.hpp index 10f7d16..d7b642e 100644 --- a/qui/MussaAlignedWindow.hpp +++ b/qui/MussaAlignedWindow.hpp @@ -3,14 +3,17 @@ #include -#include -#include +#include +#include #include "alg/mussa.hpp" +#include "qui/IntAction.hpp" #include "qui/seqbrowser/SequenceBrowserWidget.hpp" //! Show sequence alignments -class MussaAlignedWindow : public QWidget +class MussaAlignedWindow : public QMainWindow { + Q_OBJECT + public: //! construct an aligned window for an analysis and selected paths MussaAlignedWindow(Mussa&, const std::set&, QWidget *parent=0); @@ -18,16 +21,24 @@ public: public slots: //! use selected_paths[pathid] to set the starting position of our sequence void setAlignment(size_t pathid); + //! toggle whether or not to show the aligned basepairs of a window + void toggleViewAlignment(size_t alignment_index); protected: void setSelectedPaths(Mussa &m, const std::set& sel_paths); + //! set menus (must be called after setSelectedPaths) + void setupMenus(); void computeMatchLines(); Mussa& analysis; //std::vector sequences; //const std::set& selected_paths; std::vector selected_paths; + std::vector view_paths; SequenceBrowserWidget browser; - QStatusBar status; + QMenu pick_align_menu; + QMenu view_align_menu; + std::vector pick_actions; + std::vector view_actions; }; #endif