combine a declaration and assignment
[mussa.git] / qui / MussaAlignedWindow.cpp
1 #include <list>
2 #include <vector>
3 #include <sstream>
4
5 #include <QStatusBar>
6 #include <QString>
7 #include <QMenuBar>
8
9 #include "qui/MussaAlignedWindow.hpp"
10 #include "alg/sequence.hpp"
11
12 #include <iostream>
13 using namespace std;
14
15 MussaAlignedWindow::MussaAlignedWindow(Mussa& m, 
16                                        const set<int>& sel_paths, 
17                                        QWidget *parent)
18   : QMainWindow(parent),
19     analysis(m),
20     pick_align_menu(tr("Choose Alignment")),
21     view_align_menu(tr("View Alignment"))
22 {
23   browser.setSequences(analysis.sequences(), analysis.colorMapper());
24   setSelectedPaths(m, sel_paths);
25   setAlignment(0);
26   double zoom_level = browser.zoomToSequence();
27   zoom.setValue(zoom_level);
28   computeMatchLines();
29   setupMenus();
30
31   addToolBar(&alignTB);
32   alignTB.addWidget(&zoom);
33   
34   connect(&zoom, SIGNAL(valueChanged(double)), 
35           &browser, SLOT(setZoom(double)));
36  
37   setCentralWidget(&browser);
38
39   //Save pixel map action
40   saveBrowserPixmapAction = new QAction(tr("Save to image..."), this);
41   connect(saveBrowserPixmapAction, (SIGNAL(triggered())),
42           &browser, SLOT(promptSaveBrowserPixmap()));
43   saveBrowserPixmapAction->setIcon(QIcon(":/icons/image2.png"));
44   QMenu *newMenu = menuBar()->addMenu(tr("&File"));
45   newMenu->addAction(saveBrowserPixmapAction);
46   menuBar()->addMenu(&pick_align_menu);
47   menuBar()->addMenu(&view_align_menu);
48
49   ostringstream message;
50   message << "Selected " << selected_paths.size() << " paths";
51   statusBar()->showMessage(message.str().c_str(), 5000);
52   browser.updatePosition();
53 }
54
55
56 void MussaAlignedWindow::setSelectedPaths(Mussa &m, const set<int>& sel_paths)
57 {
58   // sets are sorted
59   set<int>::iterator sel_i = sel_paths.begin();
60   list<ConservedPath>::const_iterator path_i = m.paths().refined_pathz.begin();
61   list<ConservedPath>::const_iterator path_end = m.paths().refined_pathz.end();
62   size_t path_size = m.paths().refined_pathz.size();
63   size_t pathid=0;
64
65   selected_paths.reserve(sel_paths.size());
66   view_paths.reserve(sel_paths.size());
67   while (pathid != path_size and sel_i != sel_paths.end())
68   {
69     assert (*sel_i >= 0);
70     size_t sel_pathid = (size_t)(*sel_i);
71     if (pathid == sel_pathid) {
72       selected_paths.push_back(*path_i);
73       view_paths.push_back(true);
74       ++pathid;
75       ++path_i;
76       ++sel_i;
77     } else if (pathid < sel_pathid) {
78       ++pathid;
79       ++path_i;
80     } else if (pathid > sel_pathid) {
81       ++sel_i;
82     }
83   }
84 }
85
86 void MussaAlignedWindow::setupMenus()
87 {
88   pick_align_menu.clear();
89   view_align_menu.clear();
90   pick_actions.clear();
91   view_actions.clear();
92
93   for(vector<ConservedPath >::iterator pathz_i=selected_paths.begin(); 
94       pathz_i != selected_paths.end(); 
95       ++pathz_i)
96   {
97     ConservedPath::path_type normalized_path = pathz_i->normalizedIndexes();
98     ostringstream menu_text;
99     menu_text << pathz_i->window_size << ":";
100     ConservedPath::iterator element_i = normalized_path.begin();
101     menu_text << *element_i++;
102     for (;
103          element_i != normalized_path.end();
104          ++element_i)
105     {
106       menu_text << ", ";
107       menu_text << *element_i;
108     }
109     int index = pathz_i - selected_paths.begin();
110     IntAction *pick = new IntAction(QString(menu_text.str().c_str()), index, this);
111     connect(pick, SIGNAL(triggered(int)), this, SLOT(setAlignment(int)));
112     pick_actions.push_back(pick);
113     pick_align_menu.addAction(pick);
114     IntAction *view = new IntAction(QString(menu_text.str().c_str()), index, this);
115     connect(view, SIGNAL(triggered(int)), this, SLOT(toggleViewAlignment(int)));
116     view->setCheckable(true);
117     view->setChecked(true);
118     view_actions.push_back(view);
119     view_align_menu.addAction(view);
120   }
121 }
122
123 void MussaAlignedWindow::setAlignment(int alignment_index)
124 {
125   if (selected_paths.size() > 0) {
126     browser.centerOnPath(selected_paths[alignment_index].normalizedIndexes());
127   }
128 }
129
130 void MussaAlignedWindow::toggleViewAlignment(int alignment_index)
131 {
132   view_paths[alignment_index]= not view_paths[alignment_index]; 
133   // perhaps it'd be better if we could erase specific sets
134   // of matches instead of erasing them all and recomputing them all
135   // but this is easier
136   computeMatchLines();
137 }
138
139 void MussaAlignedWindow::update()
140 {
141   browser.update();
142 }
143
144 void MussaAlignedWindow::computeMatchLines()
145 {
146   browser.clear_links();
147   
148   // filter out conserved paths
149   list<ConservedPath> filtered_paths;
150   vector<ConservedPath>::iterator path_i = selected_paths.begin();
151   list<ConservedPath::path_type> result;
152   list<vector<bool> > reversed;
153
154   for(vector<ConservedPath>::size_type count = 0; 
155       count != selected_paths.size();
156       ++count, ++path_i)
157   {
158     if (view_paths[count]) 
159       filtered_paths.push_back(*path_i);
160   }
161   analysis.createLocalAlignment(filtered_paths.begin(), 
162                                 filtered_paths.end(),
163                                 result, 
164                                 reversed);
165
166   list<ConservedPath::path_type>::const_iterator result_i = result.begin();
167   list<vector<bool> >::const_iterator reversed_i = reversed.begin();
168   for(int i = 0; i != result.size(); ++i, ++result_i, ++reversed_i)
169   {
170     // make 1 base long links
171     browser.link(*result_i, *reversed_i, 1);
172   }
173 }