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