1 // This file is part of the Mussa source distribution.
2 // http://mussa.caltech.edu/
3 // Contact author: Tristan De Buysscher, tristan@caltech.edu
5 // This program and all associated source code files are Copyright (C) 2005
6 // the California Institute of Technology, Pasadena, CA, 91125 USA. It is
7 // under the GNU Public License; please see the included LICENSE.txt
8 // file for more information, or contact Tristan directly.
16 #include <FL/fl_draw.H>
21 SeqView::setup(string name, int sq_num,
22 vector<Sequence> *some_seqs,
23 list<ExtendedConservedPath > some_paths, vector<int> some_lens,
24 vector<motif> *some_motifs)
27 list<ExtendedConservedPath >::iterator pathz_i;
34 the_motifs = some_motifs;
36 y_seq_incre = (y_max-10-10) / (seq_num - 1);
38 fl_font(FL_COURIER, 14);
39 cout << "font width: " << fl_width('A') << endl;
41 index_pad = 6 * (int) fl_width('A') + 5;
46 for(seq_i = 0; seq_i < seq_num; ++seq_i)
47 raw_sequence.push_back( (*S)[seq_i].get_seq() );
49 for(pathz_i = P.begin(); pathz_i != P.end(); ++pathz_i)
51 show_aligns.push_back(true);
60 cout << x() << " " << y() << " " << w() << " " << h() << endl;
64 SeqView::resize(int new_x, int new_y, int new_w, int new_h)
71 // hmmm, why do I use these values on the the widgets inherent ones?
72 // I think there was a reason...once?
78 // things that need to be recalculated
79 y_seq_incre = (y_max-10-10) / (seq_num - 1);
89 // clear drawing area and set background to white
91 fl_rectf(x(), y(), w(), h());
93 fl_font(FL_COURIER, 14);
94 //blatantly stolen from FR2
95 ch_width = fl_width('A'); // monospaced: all characters are same width
100 int grey_box_num, grey_box_len;
102 // draw in some light grey boxes every 10bp to delineate for user
103 //fl_color(200,235,235);
104 fl_color(180,180,180);
105 grey_box_num = (((x_max - index_pad) / (int) ch_width) / 10) + 1;
106 grey_box_len = 10 * (int) ch_width;
107 for(i = 0; i < grey_box_num; i++)
109 fl_rectf(x()+index_pad-1 + (i * grey_box_len), y(), grey_box_len, h());
113 draw_motifs(ch_width);
115 draw_sequence(ch_width);
117 draw_match_lines(ch_width);
119 draw_indices(ch_width);
122 // draw some bounding boxes to visually separate things
123 fl_color(150,200,255);
124 fl_line_style(FL_SOLID, 2, NULL);
125 fl_rect(x(), y(), w(), h());
126 fl_rect(x()+index_pad-1, y(), w()-2*(index_pad-1), h());
130 SeqView::draw_motifs(double ch_width)
132 vector<motif>::iterator motif_i;
133 vector<int> some_motif_locs;
134 vector<int>::iterator i_locs;
135 int scale_len, motif_len, i2;
138 //fl_color(255,0,255);
139 fl_line_style(FL_SOLID, 10, NULL);
140 motif_i = the_motifs->begin();
141 while (motif_i != the_motifs->end())
143 fl_color(motif_i->color);
144 motif_len = motif_i->seq.length();
145 scale_len = (int) (motif_len * ch_width);
147 if (!motif_i->locations.empty())
148 for(i2 = 0; i2 < seq_num; i2++)
150 some_motif_locs = (*motif_i).locations[i2];
152 i_locs = some_motif_locs.begin();
153 while (i_locs != some_motif_locs.end())
155 x_start = (int) ((*i_locs +scroll_offset - seq_align_offsets[i2])
156 * ch_width) + index_pad + x();
158 //cout << *i_locs << ":" << x_start << " ";
159 // don't draw highlights outside of box range, they can wraparound past some boundry
160 if ((x_start > 0) && (x_start < w()))
161 fl_line(x_start,y_loc,x_start+scale_len,y_loc);
165 y_loc += y_seq_incre;
172 SeqView::draw_sequence(double ch_width)
177 int seq_len, sub_seq_start, sub_seq_len;
182 y_loc = y_min + 10 + 5;
184 for(seq_i = 0; seq_i < seq_num; seq_i++)
186 seq_len = raw_sequence[seq_i].length();
187 sub_seq_start = seq_align_offsets[seq_i] - scroll_offset;
188 sub_seq_len = (x_max - index_pad) / (int) ch_width;
189 //cout << x_max << " index_pad: " << index_pad << " y - ip: " << (x_max - index_pad) << endl;
191 // gotta check thru boundary conditions to make sure we're producing the
192 // right string for the current position (otherwise gonna crash due to
193 // illegal indexing into substr
194 if (sub_seq_start < 0)
196 sub_seq_len = sub_seq_len - sub_seq_start;
201 else if (sub_seq_start >= seq_len)
203 sub_seq_start = seq_len;
206 else if ((sub_seq_start + sub_seq_len) >= seq_len)
207 sub_seq_len = seq_len - sub_seq_start;
209 sub_seq = raw_sequence[seq_i].substr(sub_seq_start, sub_seq_len);
210 fl_draw(sub_seq.c_str(), index_pad, y_loc);
211 y_loc += y_seq_incre;
217 SeqView::draw_match_lines(double ch_width)
220 list<ExtendedConservedPath >::iterator pathz_i;
222 int x_start, y_start, x_end, y_end;
223 int window_length, win_i;
226 int offset1, offset2;
227 float center1, center2;
229 vector<bool> rc_list;
231 vector<bool> matched;
236 for(pathz_i = P.begin(); pathz_i != P.end(); ++pathz_i)
238 if (show_aligns[align_counter])
240 ExtendedConservedPath& a_path = *pathz_i;
241 window_length = a_path.window_size;
243 // determine which parts of the path are RC relative to first species
245 for(i2 = 0; i2 < a_path.size()-1; i2++)
248 rc_list.push_back(true);
250 rc_list.push_back(false);
253 // loop over each bp in the conserved region for all sequences
254 for(win_i = 0; win_i < window_length; win_i++)
256 // determine which exact base pairs match between the sequences
258 for(i2 = 0; i2 < a_path.size()-1; i2++)
260 // assume not rc as most likely, adjust below
263 // no matter the case, any RC node needs adjustments
265 rc_1 = window_length-1;
266 if (a_path[i2+1] < 0)
267 rc_2 = window_length-1;
269 x_start = (abs(a_path[i2]-rc_1+win_i));
270 x_end = (abs(a_path[i2+1]-rc_2+win_i));
273 // ugh, and xor...only want rc coloring if just one of the nodes is rc
274 // if both nodes are rc, then they are 'normal' relative to each other
275 if ( ( rc_list[i2] || rc_list[i2+1] ) &&
276 !(rc_list[i2] && rc_list[i2+1] ) )
277 { //the hideous rc matching logic - not complex, but annoying
278 if ( !( ( (raw_sequence[i2][x_start] == 'A') &&
279 (raw_sequence[i2+1][x_end] == 'T') ) ||
280 ( (raw_sequence[i2][x_start] == 'T') &&
281 (raw_sequence[i2+1][x_end] == 'A') ) ||
282 ( (raw_sequence[i2][x_start] == 'G') &&
283 (raw_sequence[i2+1][x_end] == 'C') ) ||
284 ( (raw_sequence[i2][x_start] == 'C') &&
285 (raw_sequence[i2+1][x_end] == 'G') ) ) )
290 if (!( (raw_sequence[i2][x_start] == raw_sequence[i2+1][x_end]) &&
291 (raw_sequence[i2][x_start] != 'N') &&
292 (raw_sequence[i2+1][x_end] != 'N') ) )
297 // draw for matches stretching across all sequences
300 fl_line_style(FL_SOLID, 1, NULL);
302 // now can draw the line for each bp in this window that matches
303 // grrr, need to ask if anyone cares if I switch the seq
307 for(i2 = 0; i2 < a_path.size()-1; i2++)
309 // assume not rc as most likely, adjust below
312 // this makes the lines start in the middle of the drawn char/bp
315 // no matter the case, any RC node needs adjustments
318 rc_1 = window_length;
323 rc_2 = window_length;
327 // set offset based on current alignment for which bp to show
328 offset1 = seq_align_offsets[i2];
329 offset2 = seq_align_offsets[i2+1];
331 if ( ( rc_list[i2] || rc_list[i2+1] ) &&
332 !(rc_list[i2] && rc_list[i2+1] ) )
337 // maybe shouldn't recalc these, but store values from first loop
338 x_start = (abs((int) (a_path[i2]-rc_1+win_i)));
339 x_end = (abs((int) (a_path[i2+1]-rc_2+win_i)));
341 fl_line( (int)((x_start+center1-offset1+scroll_offset)*ch_width)
342 + index_pad, y_loc + 10,
343 (int)((x_end+center2-offset2+scroll_offset)*ch_width)
344 + index_pad, y_loc+y_seq_incre );
345 y_loc += y_seq_incre;
355 SeqView::draw_indices(double ch_width)
360 ostringstream an_index;
364 // clear out space on sides to draw in index values
365 // I block out the sides rather than adding offsets to the drawing of seq
366 // and conservation lines since the lines need to draw off the 'edge'
368 fl_rectf(0, y_min, index_pad, h()+y_min);
369 fl_rectf(w()-index_pad, y_min, index_pad, h()+y_min);
371 // now can draw in the indices of the start and end of the shown sequence
373 y_loc = y_min + 10 + 5;
374 for(seq_i = 0; seq_i < seq_num; seq_i++)
377 an_index << (seq_align_offsets[seq_i]-scroll_offset);
378 fl_draw((an_index.str()).c_str(), 2, y_loc);
380 shown_seq_len = (w() - 2 * index_pad) / (int) ch_width;
382 an_index << (seq_align_offsets[seq_i]-scroll_offset+shown_seq_len);
383 fl_draw((an_index.str()).c_str(), w()-index_pad+2, y_loc);
384 y_loc += y_seq_incre;
390 SeqView::toggle_align(int align_num)
392 //cout << align_num << endl;
393 //cout << show_aligns[align_num] << endl;
394 show_aligns[align_num] = !show_aligns[align_num];
395 //cout << show_aligns[align_num] << endl;
400 SeqView::align_offsets(int align_num)
402 list<ExtendedConservedPath >::iterator pathz_i;
406 cout << "alignment: " << align_num << endl;
408 if (P.begin() == P.end())
409 cout << "crud....\n";
414 while(pathz_i != P.end())
417 // find the path specified
420 while( (i < align_num) && (pathz_i != P.end()) )
426 // now set the alignment offsets - basically where the path starts
427 seq_align_offsets.clear();
428 for(i = 0; i < seq_num ; i++)
430 //cout << (*pathz_i)[i+1] << endl;
431 seq_align_offsets.push_back( abs((*pathz_i)[i+1]) );
432 // for testing purposes: to see everything in the short test sequences
433 //seq_align_offsets.push_back(0);
435 // reset any dragging done, otherwise might be hard to find selected align
443 SeqView::handle(int e)
447 // this empty string needs to be put on cout, otherwise the -O optimize
448 // compile option seems to throw this function away with the following:
449 // gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
455 if (Fl::event_button3())
457 cout << "menu menu menu!\n";
464 drag_change = Fl::event_x();
468 drag_change = Fl::event_x() - drag_change;
469 scroll_offset += drag_change;
470 drag_change = Fl::event_x();
476 //scroll_offset += Fl::event_x() - drag_start;
477 //scroll_dist = Fl::event_x() - drag_start;
478 //scroll_offset += scroll_dist;
479 //scroll_offset += scroll_pos;
486 return_value = Fl_Widget::handle(e);
493 SeqView::toggle_bars()
495 show_bars = !show_bars;
501 SeqView::toggle_motifs()
503 show_motifs = !show_motifs;
509 SeqView::reporter(string id, int value)
511 cout << id << " : " << value << endl;