9 #include "qui/MussaAlignedWindow.hpp"
10 #include "alg/sequence.hpp"
14 MussaAlignedWindow::MussaAlignedWindow(Mussa& m,
15 const set<int>& sel_paths,
17 : QMainWindow(parent),
19 pick_align_menu(tr("Choose Alignment")),
20 view_align_menu(tr("View Alignment"))
22 browser.setSequences(analysis.sequences(), analysis.colorMapper());
23 setSelectedPaths(m, sel_paths);
25 browser.zoomToSequence();
29 setCentralWidget(&browser);
30 menuBar()->addMenu(&pick_align_menu);
31 menuBar()->addMenu(&view_align_menu);
33 ostringstream message;
34 message << "Selected " << selected_paths.size() << " paths";
35 statusBar()->showMessage(message.str().c_str(), 5000);
36 browser.updatePosition();
40 void MussaAlignedWindow::setSelectedPaths(Mussa &m, const set<int>& sel_paths)
43 set<int>::iterator sel_i = sel_paths.begin();
44 list<ExtendedConservedPath>::const_iterator path_i = m.paths().rpbegin();
45 list<ExtendedConservedPath>::const_iterator path_end = m.paths().rpend();
46 size_t path_size = m.paths().refined_pathz.size();
49 selected_paths.reserve(sel_paths.size());
50 view_paths.reserve(sel_paths.size());
51 while (pathid != path_size and sel_i != sel_paths.end())
54 size_t sel_pathid = (size_t)(*sel_i);
55 if (pathid == sel_pathid) {
56 selected_paths.push_back(*path_i);
57 view_paths.push_back(true);
61 } else if (pathid < sel_pathid) {
64 } else if (pathid > sel_pathid) {
70 void MussaAlignedWindow::setupMenus()
72 pick_align_menu.clear();
73 view_align_menu.clear();
77 for(vector<ExtendedConservedPath >::iterator pathz_i=selected_paths.begin();
78 pathz_i != selected_paths.end();
81 ConservedPath::path_type normalized_path = pathz_i->normalizedIndexes();
82 ostringstream menu_text;
83 menu_text << pathz_i->window_size << ":";
84 ConservedPath::iterator element_i = normalized_path.begin();
85 menu_text << *element_i++;
87 element_i != normalized_path.end();
91 menu_text << *element_i;
93 int index = pathz_i - selected_paths.begin();
94 IntAction *pick = new IntAction(QString(menu_text.str().c_str()), index, this);
95 connect(pick, SIGNAL(triggered(int)), this, SLOT(setAlignment(size_t)));
96 pick_actions.push_back(pick);
97 pick_align_menu.addAction(pick);
98 IntAction *view = new IntAction(QString(menu_text.str().c_str()), index, this);
99 connect(view, SIGNAL(triggered(int)), this, SLOT(toggleViewAlignment(size_t)));
100 view->setCheckable(true);
101 view->setChecked(true);
102 view_actions.push_back(view);
103 view_align_menu.addAction(view);
107 void MussaAlignedWindow::setAlignment(size_t alignment_index)
109 if (selected_paths.size() > 0) {
110 browser.centerOnPath(selected_paths[alignment_index].normalizedIndexes());
114 void MussaAlignedWindow::toggleViewAlignment(size_t alignment_index)
116 view_paths[alignment_index]= not view_paths[alignment_index];
117 // perhaps it'd be better if we could erase specific sets
118 // of matches instead of erasing them all and recomputing them all
119 // but this is easier
123 void MussaAlignedWindow::update()
128 void MussaAlignedWindow::computeMatchLines()
130 const vector<Sequence>& raw_sequence = analysis.sequences();
131 vector<int> aligned_path;
134 int window_length, win_i;
138 vector<bool> rc_list;
140 vector<bool> matched;
143 browser.clear_links();
145 for(vector<ExtendedConservedPath >::iterator pathz_i=selected_paths.begin();
146 pathz_i != selected_paths.end();
149 if (view_paths[align_counter])
151 ExtendedConservedPath& a_path = *pathz_i;
152 window_length = a_path.window_size;
153 // determine which parts of the path are RC relative to first species
154 rc_list = a_path.reverseComplimented();
156 // loop over each bp in the conserved region for all sequences
157 for(win_i = 0; win_i < window_length; win_i++)
159 aligned_path.clear();
160 // determine which exact base pairs match between the sequences
162 for(i2 = 0; i2 < a_path.size()-1; i2++)
164 // assume not rc as most likely, adjust below
167 // no matter the case, any RC node needs adjustments
169 rc_1 = window_length-1;
170 if (a_path[i2+1] < 0)
171 rc_2 = window_length-1;
173 x_start = (abs(a_path[i2]-rc_1+win_i));
174 x_end = (abs(a_path[i2+1]-rc_2+win_i));
177 // ugh, and xor...only want rc coloring if just one of the nodes is rc
178 // if both nodes are rc, then they are 'normal' relative to each other
179 if ( ( rc_list[i2] || rc_list[i2+1] ) &&
180 !(rc_list[i2] && rc_list[i2+1] ) )
181 { //the hideous rc matching logic - not complex, but annoying
182 if ( !( ( (raw_sequence[i2][x_start] == 'A') &&
183 (raw_sequence[i2+1][x_end] == 'T') ) ||
184 ( (raw_sequence[i2][x_start] == 'T') &&
185 (raw_sequence[i2+1][x_end] == 'A') ) ||
186 ( (raw_sequence[i2][x_start] == 'G') &&
187 (raw_sequence[i2+1][x_end] == 'C') ) ||
188 ( (raw_sequence[i2][x_start] == 'C') &&
189 (raw_sequence[i2+1][x_end] == 'G') ) ) )
194 if (!( (raw_sequence[i2][x_start] == raw_sequence[i2+1][x_end]) &&
195 (raw_sequence[i2][x_start] != 'N') &&
196 (raw_sequence[i2+1][x_end] != 'N') ) )
201 // draw for matches stretching across all sequences
204 // now can draw the line for each bp in this window that matches
205 // grrr, need to ask if anyone cares if I switch the seq
209 for(i2 = 0; i2 < a_path.size()-1; i2++)
211 // assume not rc as most likely, adjust below
214 // no matter the case, any RC node needs adjustments
217 rc_1 = window_length;
221 rc_2 = window_length;
224 // maybe shouldn't recalc these, but store values from first loop
225 x_start = (abs((int) (a_path[i2]-rc_1+win_i)));
226 x_end = (abs((int) (a_path[i2+1]-rc_2+win_i)));
227 aligned_path.push_back(x_start);
228 // if we're on the last time through the loop, save x_end too
229 if (i2 == a_path.size()-2) {
230 aligned_path.push_back(x_end);
234 if (aligned_path.size() > 0) {
235 browser.link(aligned_path, rc_list,1);