From e171f5dc2f6f0412f20ba2c8dcbd663790bddc37 Mon Sep 17 00:00:00 2001 From: Diane Trout Date: Sat, 18 Mar 2006 02:01:58 +0000 Subject: [PATCH] define window for showing a mussa alignment Create a new window to hold the mussa sequence alignment. (aka show all the sequences lined up at a starting point with lines connecting base pairs.) (This also fixes a bug I introduced into the fltk version of mussa back when I changed paths from just being a vector of ints into an actual class.) I still need to actually allow the user to pick the aligned path and show the conserved base pairs. --- alg/conserved_path.cpp | 18 ++++++++++- alg/conserved_path.hpp | 2 ++ alg/glseqbrowser.cpp | 19 ++++++----- alg/glseqbrowser.hpp | 6 ++-- alg/test/test_conserved_path.cpp | 20 ++++++++++++ gui/ConnView.cpp | 3 +- gui/SeqView.cpp | 22 +++++-------- gui/SeqWindow.cpp | 40 ++---------------------- mussagl.pro | 2 ++ qui/MussaAlignedWindow.cpp | 21 +++++++++++++ qui/MussaAlignedWindow.hpp | 22 +++++++++++++ qui/MussaWindow.cpp | 30 ++++++++++++++++-- qui/MussaWindow.hpp | 6 +++- qui/seqbrowser/SequenceBrowser.hpp | 2 ++ qui/seqbrowser/SequenceBrowserWidget.cpp | 5 +++ qui/seqbrowser/SequenceBrowserWidget.hpp | 2 ++ 16 files changed, 153 insertions(+), 67 deletions(-) create mode 100644 qui/MussaAlignedWindow.cpp create mode 100644 qui/MussaAlignedWindow.hpp diff --git a/alg/conserved_path.cpp b/alg/conserved_path.cpp index af2a4a0..56253c9 100644 --- a/alg/conserved_path.cpp +++ b/alg/conserved_path.cpp @@ -22,7 +22,7 @@ ConservedPath::ConservedPath(double s, ConservedPath::path_type path) track_indexes(path) { } - + void ConservedPath::clear() { score = 0.0; @@ -126,6 +126,22 @@ bool ConservedPath::nextTo(const ConservedPath& next) const return true; } +vector ConservedPath::reverseComplimented() const +{ + vector reversed; + for (ConservedPath::const_iterator this_itor = begin(); + this_itor != end(); + ++this_itor) + { + if (*this_itor < 0) + reversed.push_back(true); + else + reversed.push_back(false); + } + return reversed; + +} + ///////////////////// ExtendedConservedPath::ExtendedConservedPath() : ConservedPath(), diff --git a/alg/conserved_path.hpp b/alg/conserved_path.hpp index f5f4953..17f1bb7 100644 --- a/alg/conserved_path.hpp +++ b/alg/conserved_path.hpp @@ -36,6 +36,8 @@ struct ConservedPath * that definition may not properly track reverse compliment */ bool nextTo(const ConservedPath& next) const; + //! indicate which elements of the path are reversed + std::vector reverseComplimented() const; //! either number of conserved bases or average entropy double score; diff --git a/alg/glseqbrowser.cpp b/alg/glseqbrowser.cpp index cb6b0e3..70637a0 100644 --- a/alg/glseqbrowser.cpp +++ b/alg/glseqbrowser.cpp @@ -76,8 +76,8 @@ void GlSeqBrowser::processSelection(GLuint hits, GLuint buffer[], GLuint bufsize GLuint pair_key_0 = 0; GLuint pair_key_1 = 0; - selectedPaths.clear(); - selectedTracks.clear(); + selected_paths.clear(); + selected_tracks.clear(); std::cout << "hits = " << hits << std::endl; ptr = (GLuint *) buffer; @@ -104,7 +104,7 @@ void GlSeqBrowser::processSelection(GLuint hits, GLuint buffer[], GLuint bufsize psm_i = path_segments[path_index].find(k); if (psm_i != path_segments[path_index].end()) { Segment &seg = psm_i->second; - selectedPaths.insert(seg.path_ids.begin(), seg.path_ids.end()); + selected_paths.insert(seg.path_ids.begin(), seg.path_ids.end()); } // else something else is wrong } else { @@ -116,7 +116,7 @@ void GlSeqBrowser::processSelection(GLuint hits, GLuint buffer[], GLuint bufsize break; case MussaTrack: objid = *ptr++; ++consumed_names; - selectedTracks.insert(objid); + selected_tracks.insert(objid); break; default: cout << "unknown type " << objtype << " "; @@ -317,6 +317,11 @@ GlSeqBrowser::link(const vector& path, const vector& rc, int length) ++pathid; } +const set& GlSeqBrowser::selectedPaths() const +{ + return selected_paths; +} + void GlSeqBrowser::update_viewport(float center, int new_zoom) { float max_width = max_ortho.width(); @@ -429,18 +434,18 @@ void GlSeqBrowser::draw_segments() const const Segment &s = psm_i->second; // need to do something so we can detect our selection vector selected; - set_intersection(selectedPaths.begin(), selectedPaths.end(), + set_intersection(selected_paths.begin(), selected_paths.end(), s.path_ids.begin(), s.path_ids.end(), back_inserter(selected)); if (not s.reversed) { - if (selectedPaths.size() == 0 or selected.size() > 0) { + if (selected_paths.size() == 0 or selected.size() > 0) { glColor3f(1.0, 0.0, 0.0); } else { glColor3f(1.0, 0.8, 0.8); } } else { - if (selectedPaths.size() == 0 or selected.size() > 0) { + if (selected_paths.size() == 0 or selected.size() > 0) { glColor3f(0.0, 0.0, 1.0); } else { glColor3f(0.8, 0.8, 1.0); diff --git a/alg/glseqbrowser.hpp b/alg/glseqbrowser.hpp index fa337a5..af7efdc 100644 --- a/alg/glseqbrowser.hpp +++ b/alg/glseqbrowser.hpp @@ -58,6 +58,8 @@ public: void clear_links(); //! define a path void link(const std::vector& path, const std::vector& isRC, int length); + //! returns the index of pathids based on order added by link + const std::set& selectedPaths() const; //! Provide a logical name for a type discriminator for our glName stack enum FeatureType { MussaTrack, MussaSegment }; @@ -151,9 +153,9 @@ protected: //! true if we have a selection bool selectedMode; //! indicate which paths are selected - std::set selectedPaths; + std::set selected_paths; //! which track is selected (it only makes sense to have one track selected). - std::set selectedTracks; + std::set selected_tracks; }; #endif diff --git a/alg/test/test_conserved_path.cpp b/alg/test/test_conserved_path.cpp index b28c635..ec1b54c 100644 --- a/alg/test/test_conserved_path.cpp +++ b/alg/test/test_conserved_path.cpp @@ -63,6 +63,26 @@ BOOST_AUTO_TEST_CASE ( conserved_path_vector ) BOOST_CHECK_EQUAL( cp.size(), 1 ); } +// does the reverse compliment test work? +BOOST_AUTO_TEST_CASE ( conserved_path_reverse_compliment ) +{ + vector path; + path += 3,4,-5,1; // magic from boost assign + + ConservedPath cp1(10, path); + vector reversed = cp1.reverseComplimented(); + + BOOST_CHECK_EQUAL( path.size(), reversed.size()); + vector::iterator path_i = path.begin(); + vector::iterator reversed_i = reversed.begin(); + for(; path_i != path.end() and reversed_i != reversed.end(); + ++path_i, ++reversed_i) + { + // if we're less than zero our reversed flag should be true + BOOST_CHECK_EQUAL( *path_i < 0, *reversed_i); + } +} + BOOST_AUTO_TEST_CASE ( extended_conserved_path_simple ) { vector path; diff --git a/gui/ConnView.cpp b/gui/ConnView.cpp index a25d632..b6ba946 100644 --- a/gui/ConnView.cpp +++ b/gui/ConnView.cpp @@ -623,8 +623,7 @@ ConnView::spawnSeq() { if (*highlight_i) { - ExtendedConservedPath& a_path = *pathz_i; - selected_paths.push_back(a_path); + selected_paths.push_back(*pathz_i); } ++highlight_i; } diff --git a/gui/SeqView.cpp b/gui/SeqView.cpp index 24f7819..419d21e 100644 --- a/gui/SeqView.cpp +++ b/gui/SeqView.cpp @@ -24,7 +24,6 @@ SeqView::setup(string name, int sq_num, vector *some_motifs) { int seq_i; - list::iterator pathz_i; analysis_name = name; seq_num = sq_num; @@ -46,7 +45,9 @@ SeqView::setup(string name, int sq_num, for(seq_i = 0; seq_i < seq_num; ++seq_i) raw_sequence.push_back( (*S)[seq_i].get_seq() ); - for(pathz_i = P.begin(); pathz_i != P.end(); ++pathz_i) + for(list::iterator pathz_i = P.begin(); + pathz_i != P.end(); + ++pathz_i) { show_aligns.push_back(true); } @@ -217,7 +218,6 @@ void SeqView::draw_match_lines(double ch_width) { int i, y_loc; - list::iterator pathz_i; int i2, i3; int x_start, y_start, x_end, y_end; int window_length, win_i; @@ -233,22 +233,16 @@ SeqView::draw_match_lines(double ch_width) align_counter = 0; - for(pathz_i = P.begin(); pathz_i != P.end(); ++pathz_i) + for(list::iterator pathz_i = P.begin(); + pathz_i != P.end(); + ++pathz_i) { if (show_aligns[align_counter]) { ExtendedConservedPath& a_path = *pathz_i; window_length = a_path.window_size; - // determine which parts of the path are RC relative to first species - rc_list.clear(); - for(i2 = 0; i2 < a_path.size()-1; i2++) - { - if (a_path[i2] < 0) - rc_list.push_back(true); - else - rc_list.push_back(false); - } + rc_list = a_path.reverseComplimented(); // loop over each bp in the conserved region for all sequences for(win_i = 0; win_i < window_length; win_i++) @@ -428,7 +422,7 @@ SeqView::align_offsets(int align_num) for(i = 0; i < seq_num ; i++) { //cout << (*pathz_i)[i+1] << endl; - seq_align_offsets.push_back( abs((*pathz_i)[i+1]) ); + seq_align_offsets.push_back( abs((*pathz_i).track_indexes[i]) ); // for testing purposes: to see everything in the short test sequences //seq_align_offsets.push_back(0); } diff --git a/gui/SeqWindow.cpp b/gui/SeqWindow.cpp index 46a73b8..8578f49 100644 --- a/gui/SeqWindow.cpp +++ b/gui/SeqWindow.cpp @@ -48,7 +48,6 @@ SeqWindow::real_show_align_cb(int which_align) vector a_path; int window_length; - cout << "fumish\n"; seq_box->toggle_align(which_align); seq_box->redraw(); @@ -135,9 +134,9 @@ SeqWindow::SeqWindow(int w, int h, const char* title, int sq_num, some_menu_data = new menu_align_data_bundle; some_menu_data->swm_ptr = this; some_menu_data->which_align = align_number; - align_id_ostr << (*align_iter)[0] << ": "; - for(i = 1; i <= seq_num; i++) - align_id_ostr << (*align_iter)[i] << ", "; + align_id_ostr << (*align_iter).window_size << ": "; + for(i = 0; i != seq_num; i++) + align_id_ostr << (*align_iter).track_indexes[i] << ", "; align_id_string = align_id_ostr.str(); choose_align_menu->add((const char*)align_id_string.c_str(), 0, (Fl_Callback *) set_align_cb, @@ -151,13 +150,6 @@ SeqWindow::SeqWindow(int w, int h, const char* title, int sq_num, ++align_iter; } - /* - show_align_menu->add("f&ee"); - show_align_menu->add("f&ie"); - show_align_menu->add("f&oe"); - show_align_menu->add("f&um"); - */ - Fl_Button *test_but = new Fl_Button(375, 2, 150, 30, "Toggle Motifs"); test_but->color(FL_WHITE,FL_BLUE); test_but->box(FL_BORDER_BOX); @@ -178,29 +170,3 @@ SeqWindow::SeqWindow(int w, int h, const char* title, int sq_num, Fl::visual(FL_DOUBLE|FL_INDEX); show(); } - - - -/* - some_menu_data = new menu_align_data_bundle; - some_menu_data->swm_ptr = this; - some_menu_data->which_align = 2; - choose_align_menu->add("f&ie", FL_ALT+'i', (Fl_Callback *) set_align_cb, - (void*) some_menu_data); - - some_menu_data = new menu_align_data_bundle; - some_menu_data->swm_ptr = this; - some_menu_data->which_align = 3; - choose_align_menu->add("f&oe", FL_ALT+'o', (Fl_Callback *) set_align_cb, - (void*) some_menu_data); - - some_menu_data = new menu_align_data_bundle; - some_menu_data->swm_ptr = this; - some_menu_data->which_align = 4; - choose_align_menu->add("f&um", FL_ALT+'u', (Fl_Callback *) set_align_cb, - (void*) some_menu_data); -*/ - - - - diff --git a/mussagl.pro b/mussagl.pro index 8c06335..7228685 100644 --- a/mussagl.pro +++ b/mussagl.pro @@ -13,6 +13,7 @@ INCLUDEPATH += . alg qui # Input HEADERS += mussa_exceptions.hpp \ qui/MussaWindow.hpp \ + qui/MussaAlignedWindow.hpp \ qui/ThresholdWidget.hpp \ qui/ImageScaler.hpp \ qui/ImageSaveDialog.hpp \ @@ -33,6 +34,7 @@ HEADERS += mussa_exceptions.hpp \ alg/sequence.hpp SOURCES += mussagl.cpp \ qui/MussaWindow.cpp \ + qui/MussaAlignedWindow.cpp \ qui/ThresholdWidget.cpp \ qui/ImageScaler.cpp \ qui/ImageSaveDialog.cpp \ diff --git a/qui/MussaAlignedWindow.cpp b/qui/MussaAlignedWindow.cpp new file mode 100644 index 0000000..bd647a5 --- /dev/null +++ b/qui/MussaAlignedWindow.cpp @@ -0,0 +1,21 @@ +#include "qui/MussaAlignedWindow.hpp" + +#include + +using namespace std; + +MussaAlignedWindow::MussaAlignedWindow(Mussa& m, + const set& sel_paths, + QWidget *parent) + : QWidget(parent), + analysis(m), + selected_paths(sel_paths) + +{ + browser.setSequences(analysis.sequences(), analysis.colorMapper()); + + QVBoxLayout *layout = new QVBoxLayout; + layout->addWidget(&browser); + setLayout(layout); +} + diff --git a/qui/MussaAlignedWindow.hpp b/qui/MussaAlignedWindow.hpp new file mode 100644 index 0000000..a9cbbfc --- /dev/null +++ b/qui/MussaAlignedWindow.hpp @@ -0,0 +1,22 @@ +#ifndef MUSSA_ALIGNED_WINDOW_H +#define MUSSA_ALIGNED_WINDOW_H + +#include + +#include +#include "alg/mussa.hpp" +#include "qui/seqbrowser/SequenceBrowserWidget.hpp" + +//! Show sequence alignments +class MussaAlignedWindow : public QWidget +{ +public: + MussaAlignedWindow(Mussa& m, const std::set& sel_paths, QWidget *parent=0); + +protected: + Mussa &analysis; + const std::set& selected_paths; + + SequenceBrowserWidget browser; +}; +#endif diff --git a/qui/MussaWindow.cpp b/qui/MussaWindow.cpp index f8945c4..8696913 100644 --- a/qui/MussaWindow.cpp +++ b/qui/MussaWindow.cpp @@ -11,6 +11,7 @@ #include #include "qui/MussaWindow.hpp" +#include "qui/MussaAlignedWindow.hpp" #include "mussa_exceptions.hpp" #include @@ -124,14 +125,22 @@ void MussaWindow::setupActions() "You can load motif annotations via " "'File->Load Motif List' menu option.")); - whatsThisAction = QWhatsThis::createAction(this); - whatsThisAction->setIcon(QIcon("icons/help.png")); - //Save pixel map action saveBrowserPixmapAction = new QAction(tr("Save to image..."), this); connect(saveBrowserPixmapAction, (SIGNAL(triggered())), &browser, SLOT(promptSaveBrowserPixmap())); saveBrowserPixmapAction->setIcon(QIcon("icons/image2.png")); + + viewMussaAlignmentAction = new QAction(tr("View mussa alignment"), this); + connect(viewMussaAlignmentAction, SIGNAL(triggered()), + this, SLOT(viewMussaAlignment() )); + viewMussaAlignmentAction->setWhatsThis(tr("Create a zoomed in window " + "showing alignment of the seqcomp " + "defined paths")); + + whatsThisAction = QWhatsThis::createAction(this); + whatsThisAction->setIcon(QIcon("icons/help.png")); + } void MussaWindow::setupMainMenu() @@ -154,6 +163,7 @@ void MussaWindow::setupMainMenu() newMenu->addAction(closeAction); newMenu = menuBar()->addMenu(tr("&View")); + newMenu->addAction(viewMussaAlignmentAction); newMenu->addAction(showMussaViewToolbarAction); newMenu = menuBar()->addMenu(tr("&Help")); @@ -295,6 +305,20 @@ void MussaWindow::NotImplementedBox() QMessageBox::warning(this, QObject::tr("mussa"), QObject::tr("Not implemented yet")); } +void MussaWindow::viewMussaAlignment() +{ + const set& selected_paths = browser.selectedPaths(); + if (selected_paths.size() == 0 ) { + QMessageBox::warning(this, + QObject::tr("mussa"), + QObject::tr("you should probably select some paths " + "first")); + } else { + QWidget *ma_win = new MussaAlignedWindow(*analysis, selected_paths); + ma_win->show(); + } +} + void MussaWindow::updateAnalysis() { cout << "analysis updated" << endl; diff --git a/qui/MussaWindow.hpp b/qui/MussaWindow.hpp index 26e16bc..d748b0d 100644 --- a/qui/MussaWindow.hpp +++ b/qui/MussaWindow.hpp @@ -48,6 +48,9 @@ public slots: void setSoftThreshold(int thres); void showMussaToolbar(); + + //! open new window showing our alignment + void viewMussaAlignment(); protected: Mussa *analysis; @@ -68,8 +71,9 @@ protected: QAction *saveMotifListAction; QAction *showMussaViewToolbarAction; QAction *toggleMotifsAction; - QAction *whatsThisAction; QAction *saveBrowserPixmapAction; + QAction *whatsThisAction; + QAction *viewMussaAlignmentAction; //! initialze the actions void setupActions(); diff --git a/qui/seqbrowser/SequenceBrowser.hpp b/qui/seqbrowser/SequenceBrowser.hpp index ed3da99..d77b5d4 100644 --- a/qui/seqbrowser/SequenceBrowser.hpp +++ b/qui/seqbrowser/SequenceBrowser.hpp @@ -7,6 +7,8 @@ #include #include +#include + #include "alg/mussa.hpp" #include "alg/glsequence.hpp" #include "alg/glseqbrowser.hpp" diff --git a/qui/seqbrowser/SequenceBrowserWidget.cpp b/qui/seqbrowser/SequenceBrowserWidget.cpp index 215bcd3..8d4f44e 100644 --- a/qui/seqbrowser/SequenceBrowserWidget.cpp +++ b/qui/seqbrowser/SequenceBrowserWidget.cpp @@ -90,6 +90,11 @@ void SequenceBrowserWidget::link(const std::vector& path, scrollable_browser.browser().link(path, isRC, length); } +const std::set SequenceBrowserWidget::selectedPaths() const +{ + return scrollable_browser.browser().selectedPaths(); +} + /* This could theoretically be pushed down to some set * of signals and slots connecting SequenceDescriptions and * some signal emitted by the browser's viewportChanged code diff --git a/qui/seqbrowser/SequenceBrowserWidget.hpp b/qui/seqbrowser/SequenceBrowserWidget.hpp index e51f445..87f5b28 100644 --- a/qui/seqbrowser/SequenceBrowserWidget.hpp +++ b/qui/seqbrowser/SequenceBrowserWidget.hpp @@ -37,6 +37,8 @@ public: void clear_links(); //! set per species links void link(const std::vector &path, const std::vector& isRC, int length); + // return set of pathids defined by order of link calls + const std::set selectedPaths() const; public slots: //! set the zoom level of our browser -- 2.30.2