13 #include "qui/MussaWindow.hpp"
14 #include "qui/MussaAlignedWindow.hpp"
15 #include "mussa_exceptions.hpp"
21 MussaWindow::MussaWindow(Mussa *analysis_, QWidget *parent) :
25 mussaViewTB("Path Views"),
29 closeAction(0) // initialize one of the pointers to null as a saftey flag
34 //This next setWhatsThis function prevents
35 // a segfault when using WhatsThis feature with
37 //scene->setWhatsThis(tr("Mussa in OpenGL!"));
38 setCentralWidget(&browser);
40 mussaViewTB.addAction(toggleMotifsAction);
42 zoomLabel.setPixmap(QIcon("icons/viewmag.png").pixmap(16, 16));
43 zoomLabel.setToolTip(tr("Zoom"));
44 zoomLabel.setWhatsThis(tr("Zoom magnification factor"));
45 mussaViewTB.addWidget(&zoomLabel);
47 zoomBox.setToolTip(tr("Zoom"));
48 zoomBox.setWhatsThis(tr("Zoom magnification factor"));
49 zoomBox.setRange(1,10000000);
50 mussaViewTB.addWidget(&zoomBox);
51 connect(&zoomBox, SIGNAL(valueChanged(int)),
52 &browser, SLOT(setZoom(int)));
54 threshold.setRange(19, 30);
55 threshold.setThreshold(19);
56 //scene->setClipPlane(20);
57 // FIXME: for when we get the paths drawn at the appropriate depth
58 //connect(&threshold, SIGNAL(thresholdChanged(int)),
59 // this, SLOT(setClipPlane(int)));
60 connect(&threshold, SIGNAL(thresholdChanged(int)),
61 this, SLOT(setSoftThreshold(int)));
62 mussaViewTB.addWidget(&threshold);
64 addToolBar(&mussaViewTB);
66 statusBar()->showMessage("Welcome to mussa", 2000);
70 void MussaWindow::setupActions()
72 // we really don't want to run this more than once.
73 assert (closeAction == 0);
75 // the ever popular about box
76 aboutAction = new QAction(tr("&About"), this);
77 connect(aboutAction, SIGNAL(triggered()), this, SLOT(about()));
78 aboutAction->setIcon(QIcon("icons/info.png"));
81 closeAction = new QAction(tr("&Close"), this);
82 closeAction->setStatusTip(tr("Close this window"));
83 connect(closeAction, SIGNAL(triggered()), this, SLOT(close()));
84 closeAction->setIcon(QIcon("icons/exit.png"));
86 createNewAnalysisAction = new QAction(tr("Define Analysis"), this);
87 connect(createNewAnalysisAction, SIGNAL(triggered()),
88 this, SLOT(createNewAnalysis()));
89 createNewAnalysisAction->setIcon(QIcon("icons/filenew.png"));
91 createSubAnalysisAction = new QAction(tr("Define SubAnalysis"), this);
92 connect(createSubAnalysisAction, SIGNAL(triggered()),
93 this, SLOT(createSubAnalysis()));
95 loadMotifListAction = new QAction(tr("Load Motif List"), this);
96 connect(loadMotifListAction, SIGNAL(triggered()),
97 this, SLOT(loadMotifList()));
99 loadMupaAction = new QAction(tr("Load Mussa Parameters"), this);
100 connect(loadMupaAction, SIGNAL(triggered()),
101 this, SLOT(loadMupa()));
103 loadSavedAnalysisAction = new QAction(tr("Load &Analysis"), this);
104 connect(loadSavedAnalysisAction, SIGNAL(triggered()),
105 this, SLOT(loadSavedAnalysis()));
106 loadSavedAnalysisAction->setIcon(QIcon("icons/fileopen.png"));
108 saveMotifListAction = new QAction(tr("Save Motifs"), this);
109 connect(saveMotifListAction, SIGNAL(triggered()),
110 this, SLOT(saveMotifList()));
111 saveMotifListAction->setIcon(QIcon("icons/filesave.png"));
113 showMussaViewToolbarAction = new QAction(tr("Show Toolbar"), this);
114 connect(showMussaViewToolbarAction, SIGNAL(triggered()),
115 this, SLOT(showMussaToolbar()));
116 showMussaViewToolbarAction->setCheckable(true);
117 showMussaViewToolbarAction->setChecked(true);
119 toggleMotifsAction = new QAction(tr("Toggle Motifs"), this);
120 connect(toggleMotifsAction, SIGNAL(triggered()),
121 this, SLOT(toggleMotifs()));
122 toggleMotifsAction->setCheckable(true);
123 toggleMotifsAction->setIcon(QIcon("icons/motif_icon.png"));
124 toggleMotifsAction->setWhatsThis(tr("Toggle motif annotations on/off\n\n"
125 "You can load motif annotations via "
126 "'File->Load Motif List' menu option."));
128 //Save pixel map action
129 saveBrowserPixmapAction = new QAction(tr("Save to image..."), this);
130 connect(saveBrowserPixmapAction, (SIGNAL(triggered())),
131 &browser, SLOT(promptSaveBrowserPixmap()));
132 saveBrowserPixmapAction->setIcon(QIcon("icons/image2.png"));
134 viewMussaAlignmentAction = new QAction(tr("View mussa alignment"), this);
135 connect(viewMussaAlignmentAction, SIGNAL(triggered()),
136 this, SLOT(viewMussaAlignment() ));
137 viewMussaAlignmentAction->setWhatsThis(tr("Create a zoomed in window "
138 "showing alignment of the seqcomp "
141 whatsThisAction = QWhatsThis::createAction(this);
142 whatsThisAction->setIcon(QIcon("icons/help.png"));
146 void MussaWindow::setupMainMenu()
148 // we need to run setupActions first
149 assert (closeAction != 0);
152 newMenu = menuBar()->addMenu(tr("&File"));
153 newMenu->addAction(createNewAnalysisAction);
154 newMenu->addAction(loadMupaAction);
155 newMenu->addAction(loadSavedAnalysisAction);
156 newMenu->addAction(createSubAnalysisAction);
157 newMenu->addSeparator();
158 newMenu->addAction(loadMotifListAction);
159 newMenu->addAction(saveMotifListAction);
160 newMenu->addSeparator();
161 newMenu->addAction(saveBrowserPixmapAction);
162 newMenu->addSeparator();
163 newMenu->addAction(closeAction);
165 newMenu = menuBar()->addMenu(tr("&View"));
166 newMenu->addAction(viewMussaAlignmentAction);
167 newMenu->addAction(showMussaViewToolbarAction);
169 newMenu = menuBar()->addMenu(tr("&Help"));
170 newMenu->addAction(whatsThisAction);
171 newMenu->addSeparator();
172 newMenu->addAction(aboutAction);
175 void MussaWindow::about()
177 QMessageBox::about(this, tr("About mussa"),
178 tr("Welcome to Multiple Species Sequence Analysis\n"
179 "(c) 2005-2006 California Institute of Technology\n"
180 "Tristan De Buysscher, Diane Trout\n"));
183 void MussaWindow::createNewAnalysis()
188 void MussaWindow::createSubAnalysis()
194 void MussaWindow::loadMotifList()
196 QString caption("Load a motif list");
197 QString filter("Motif list(*.txt *.mtl)");
198 QString path = QFileDialog::getOpenFileName(this,
205 // try to load safely
207 analysis->load_motifs(path.toStdString());
208 } catch (runtime_error e) {
209 QString msg("Unable to load ");
213 QMessageBox::warning(this, "Load Motifs", msg);
215 assert (analysis != 0);
218 void MussaWindow::saveMotifList()
223 void MussaWindow::loadMupa()
225 QString caption("Load a mussa parameter file");
226 QString filter("Mussa Parameters (*.mupa)");
227 QString mupa_path = QFileDialog::getOpenFileName(this,
232 if (mupa_path.isNull())
234 // try to load safely
236 Mussa *m = new Mussa;
237 m->load_mupa_file(mupa_path.toStdString());
238 m->analyze(0, 0, Mussa::TransitiveNway, 0.0);
239 // only switch mussas if we loaded without error
243 } catch (mussa_load_error e) {
244 QString msg("Unable to load ");
248 QMessageBox::warning(this, "Load Parameter", msg);
250 assert (analysis != 0);
253 void MussaWindow::loadSavedAnalysis()
255 QString caption("Load a previously run analysis");
256 QString muway_dir = QFileDialog::getExistingDirectory(this,
258 QDir::currentPath());
260 if (muway_dir.isNull())
262 // try to safely load
264 Mussa *m = new Mussa;
265 m->load(muway_dir.toStdString());
266 // only switch mussas if we loaded without error
270 } catch (mussa_load_error e) {
271 QString msg("Unable to load ");
275 QMessageBox::warning(this, "Load Parameter", msg);
277 assert (analysis != 0);
280 void MussaWindow::setSoftThreshold(int threshold)
282 if (analysis->get_soft_thres() != threshold) {
283 analysis->set_soft_thres(threshold);
290 void MussaWindow::showMussaToolbar()
292 if (mussaViewTB.isVisible())
298 void MussaWindow::toggleMotifs()
303 void MussaWindow::NotImplementedBox()
305 QMessageBox::warning(this, QObject::tr("mussa"), QObject::tr("Not implemented yet"));
308 void MussaWindow::viewMussaAlignment()
310 const set<int>& selected_paths = browser.selectedPaths();
311 if (selected_paths.size() == 0 ) {
312 QMessageBox::warning(this,
313 QObject::tr("mussa"),
314 QObject::tr("you should probably select some paths "
317 QWidget *ma_win = new MussaAlignedWindow(*analysis, selected_paths);
322 void MussaWindow::updateAnalysis()
324 cout << "analysis updated" << endl;
326 const vector<Sequence>& seqs = analysis->sequences();
327 browser.setSequences(seqs, analysis->colorMapper());
330 cout << "browser zoom " << browser.zoom() << endl;
331 zoomBox.setValue(browser.zoom());
334 void MussaWindow::updateLinks()
336 browser.clear_links();
337 bool reversed = false;
338 const NwayPaths& nway = analysis->paths();
340 typedef list<ExtendedConservedPath> conserved_paths;
341 typedef conserved_paths::const_iterator const_conserved_paths_itor;
342 for(const_conserved_paths_itor path_itor = nway.refined_pathz.begin();
343 path_itor != nway.refined_pathz.end();
346 // since we were drawing to the start of a window, and opengl lines
347 // are centered around the two connecting points our lines were slightly
348 // offset. the idea of window_offset is to adjust them to the
349 // right for forward compliment or left for reverse compliment
350 // FIXME: figure out how to unit test these computations
351 //GLfloat window_offset = (path_itor->window_size)/2.0;
353 size_t track_len = path_itor->track_indexes.size();
354 vector<int> normalized_path;
355 normalized_path.reserve(track_len);
356 vector<bool> rc_flags(false, track_len);
357 for (size_t track_i=0; track_i != track_len; ++track_i)
359 int x = path_itor->track_indexes[track_i];
360 // at some point when we modify the pathz data structure to keep
361 // track of the score we can put grab the depth here.
363 // are we reverse complimented?
368 x = -x; // make positive
370 normalized_path.push_back(x);
371 rc_flags.push_back(reversed);
373 browser.link(normalized_path, rc_flags, path_itor->window_size);