Sub-analysis failure to draw on init fix (ticket:254)
[mussa.git] / qui / subanalysis / SubanalysisWindow.cpp
1 #include "qui/subanalysis/SubanalysisWindow.hpp"
2 #include "qui/MussaWindow.hpp"
3
4 #include "mussa_exceptions.hpp"
5 #include "alg/mussa.hpp"
6
7 #include <QMessageBox>
8 #include <QVBoxLayout>
9 #include <QHBoxLayout>
10 #include <QGridLayout>
11
12 SubanalysisWindow::SubanalysisWindow(MussaRef m, QWidget *parent)
13   : QWidget(parent),
14     analysis(m),
15     parameterLayout(0),
16     thresholdLabel(0),
17     windowLabel(0),
18     window(0),
19     threshold(0),
20     table(0),
21     ok(0),
22     cancel(0)
23 {
24   parameterLayout = new QGridLayout;
25
26   thresholdLabel = new QLabel(tr("threshold (bp)"));
27   parameterLayout->addWidget(thresholdLabel, 0, 0);
28   threshold = new QSpinBox(this);
29   threshold->setValue(8);
30   parameterLayout->addWidget(threshold, 1, 0);
31   windowLabel = new QLabel(tr("window (bp)"));
32   parameterLayout->addWidget(windowLabel, 0, 1);
33   window = new QSpinBox(this);
34   window->setValue(10);
35   parameterLayout->addWidget(window, 1, 1);
36
37   ok = new QPushButton(tr("&OK"), this);
38   ok->setEnabled( false );
39   connect(ok, SIGNAL(clicked()), this, SLOT(run()));
40
41   cancel = new QPushButton(tr("Cancel"), this);
42   connect(cancel, SIGNAL(clicked()), this, SLOT(abort()));
43
44   table = new QTableView(this);
45   table->setModel(&model);
46
47   // layout buttons
48   QHBoxLayout *buttonLayout = new QHBoxLayout;
49   buttonLayout->addWidget(ok);
50   buttonLayout->addWidget(cancel);
51
52   // layout vertical space
53   QVBoxLayout *verticalLayout = new QVBoxLayout;
54   verticalLayout->addLayout(parameterLayout);
55   verticalLayout->addWidget(table);
56   verticalLayout->addLayout(buttonLayout);
57   setLayout(verticalLayout);
58
59   // now that we're all setup lets get notices when we're updated
60   connect(&model, SIGNAL(rowsInserted(const QModelIndex&, int, int)), 
61           this, SLOT(modelUpdated(const QModelIndex&, int, int)));
62   connect(&model, SIGNAL(rowsRemoved(const QModelIndex&, int, int)), 
63           this, SLOT(modelUpdated(const QModelIndex&, int, int)));
64           
65   updateTitle();        
66 }
67
68 SequenceLocationModel& SubanalysisWindow::getModel()
69 {
70   return model;
71 }
72
73 void SubanalysisWindow::abort()
74 {
75   model.clear();
76   hide();
77 }
78
79 void SubanalysisWindow::run()
80 {
81   if (window == 0 or threshold == 0) {
82     throw std::runtime_error("SubanalysisWindow misconstructed");
83   }
84
85   if (model.size() == 0) {
86     throw std::runtime_error("It shouldn't be possible to call run with an "
87                              "empty model now.");
88   }
89
90   MussaRef new_m(new Mussa);
91   
92   for(SequenceLocationModel::iterator itor = model.begin();
93       itor != model.end();
94       ++itor)
95   {
96     // append_sequence from a const Sequence & will make a copy 
97     // for the shared pointer.
98     Sequence s = itor->getSelectedSequence();
99     s.clear_motifs();
100     new_m->append_sequence(s);
101   }
102
103   try {
104     new_m->set_window(window->value());
105     new_m->set_threshold(threshold->value());
106     new_m->analyze();
107     // FIXME: why isn't the nway_paths refined_pathz structure just initialized
108     // FIXME: with the contents of pathz?
109     new_m->set_soft_threshold(threshold->value());
110     // copy over motifs
111     std::vector<Sequence> motifs_copy;
112     std::vector<Color> color_copy;
113     const Mussa::motif_set motifs = analysis->motifs();
114     boost::shared_ptr<AnnotationColors> mapper = analysis->colorMapper();
115     for(Mussa::motif_set::const_iterator motif_i = motifs.begin();
116         motif_i != motifs.end();
117         ++motif_i)
118     {
119       motifs_copy.push_back(*motif_i);
120       color_copy.push_back(mapper->lookup("motif", motif_i->get_sequence()));
121     }
122     new_m->set_motifs(motifs_copy, color_copy);
123     MussaWindow *mw = new MussaWindow(new_m);
124     mw->show();
125         mw->setSoftThreshold(threshold->value());
126     model.clear();
127     hide();
128   } catch(mussa_error e) {
129     QMessageBox::critical(this,
130                           "Mussa Subanalysis Error",
131                           QString(e.what()),
132                           QMessageBox::Ok, 0, 0);
133   }
134 }
135
136 void SubanalysisWindow::modelUpdated(const QModelIndex&, int, int )
137 {
138   // if the model is empty we shouldn't be able to click ok
139   if (ok) ok->setEnabled(not model.empty());
140 }
141
142 void SubanalysisWindow::updateTitle()
143 {
144   std::string title("Subanalysis: ");
145   if (analysis) {
146     title += analysis->get_title();
147   }
148   setWindowTitle(title.c_str());  
149 }