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.
11 #include "gui/ConnView.hpp"
17 #include <FL/fl_draw.H>
22 ConnView::setup(string name, int sq_num, int win_len,
23 vector<Sequence> *some_seqs,
24 NwayPaths *some_paths)
26 int i, i2, seq_length;
29 annot_color new_annot;
38 cout << "num of paths = " << some_paths->refined_pathz.size() << endl;
40 cout << "x()=" << x() << " y()=" << y() << " w()=" << w() << " h()=" << h();
44 for(i = 0; i < seq_num; ++i)
47 cout << a_seq.size() << endl;
48 seq_length = a_seq.size();
49 seq_lens.push_back(seq_length);
50 if (seq_length > max_seq_len)
51 max_seq_len = seq_length;
52 if (seq_length < 1000)
53 seq_scales.push_back(1);
54 else if (seq_length < 1000000)
55 seq_scales.push_back(2);
57 seq_scales.push_back(3);
63 x_scale_factor = (float) max_seq_len / (w() - name_pad);
64 cout << "scale factor is " << x_scale_factor << endl;
65 y_seq_incre = (h()-(y_pad*2)) / (seq_num - 1);
78 bar_interval = max_seq_len / 20;
79 line_interval = max_seq_len / 20;
84 for(i = 0; i < 5; ++i)
86 blank_motif = new_blank_motif();
87 some_motifs.push_back(blank_motif);
90 // find all unique annotation type ids
92 vector<annot_color>::iterator annot_type_i;
93 list<annot>::iterator annot_i;
95 // loop thru all sequences
96 for(i2 = 0; i2 < seq_num; i2++)
98 cout << "ConnView: annotation loop\n";
99 // loop thru all annotation entries in this sequence
100 for(annot_i = (*S)[i2].annots.begin(); annot_i != (*S)[i2].annots.end(); ++annot_i)
102 cout << annot_i->start << ", " << annot_i->end << " : ";
103 cout << annot_i->name << " " << annot_i->type << endl;
104 // loop thru annotation types
105 annot_type_i = some_annots.begin();
106 bool type_unfound = true;
107 while ((annot_type_i != some_annots.end()) && type_unfound)
109 if (annot_i->type == annot_type_i->type)
110 type_unfound = false; // stop search if found
113 //if unfound, then add to list
116 new_annot = new_blank_annot();
117 new_annot.type = annot_i->type;
118 some_annots.push_back(new_annot);
126 ConnView::scale_paths()
128 ExtendedConservedPath a_path;
129 list<ExtendedConservedPath >::iterator pathz_i;
133 scaled_pathz.clear();
135 for(pathz_i = P->refined_pathz.begin(); pathz_i != P->refined_pathz.end(); ++pathz_i)
138 a_path.window_size = (int)(a_path.window_size / x_scale_factor);
139 for(i2 = 0; i2 != a_path.size(); i2++)
141 a_path[i2] = (int) (a_path[i2] / x_scale_factor);
143 scaled_pathz.push_back(a_path);
148 ConnView::toggle_bars()
150 show_bars = !show_bars;
155 ConnView::set_bar_interval(int new_bar_len)
157 bar_interval = new_bar_len;
158 cout << "bar interval = " << bar_interval << endl;
163 ConnView::toggle_lines()
165 show_lines = !show_lines;
170 ConnView::set_line_interval(int new_line_len)
172 line_interval = new_line_len;
173 cout << "line interval = " << line_interval << endl;
181 // this is temporary - check if new motifs have been added
184 // clear drawing area and set background to white
186 fl_rectf(x(), y(), w(), h());
188 // draw the scale indicators if they are on
189 // put into own method soon...
190 int i, div_num, x_loc;
191 float div_len_scaled;
195 div_num = max_seq_len / bar_interval;
196 div_len_scaled = ((float) bar_interval) / x_scale_factor;
197 fl_color(230,230,230);
198 for(i = 0; i <= div_num; i+=2)
200 x_loc = (int)(i * div_len_scaled+x());
201 fl_rectf(x_loc, y(), (int) div_len_scaled, h());
207 div_num = max_seq_len / line_interval;
208 div_len_scaled = ((float) line_interval) / x_scale_factor;
210 fl_line_style(FL_SOLID, 1, NULL);
211 for(i = 0; i <= div_num; i++)
213 x_loc = (int)(i * div_len_scaled+x());
214 fl_line(x_loc, y(), x_loc, h()+y());
219 // divide up the space with some light blue lines
220 fl_color(150,200,255);
221 fl_line_style(FL_SOLID, 2, NULL);
222 fl_rect(x(), y(), w(), h());
223 fl_line(w()+x()-name_pad, y(), w()+x()-name_pad, h()+y());
227 // white out any overdraw from path area into name/info area
229 fl_rectf(w()+x()-name_pad, y(), w()+x(), h());
231 draw_sequence_stuff();
233 // draw selection box
238 fl_line_style(FL_SOLID, 1, NULL);
239 fl_rect(drag_start,(ref_seq_num*y_seq_incre)+y(),drag_end-drag_start,
247 ConnView::draw_paths()
249 list<ExtendedConservedPath >::iterator i;
250 int i2, i3, y_loc, x_loc, x_start, x_end;
251 list<bool>::iterator highlight_i;
254 int path_start, path_end;
256 // determine which paths to highlight
258 for(i = scaled_pathz.begin(); i != scaled_pathz.end(); ++i)
260 ExtendedConservedPath& a_path = *i;
261 // determine if path falls within the selected region and mark it for
263 path_start = abs(a_path[ref_seq_num]);
264 path_end = path_start + a_path[0];
265 if ( ( (path_start >= drag_start-x()) && (path_end <= drag_end-x()) ) ||
266 ( (path_start < drag_start-x()) && (path_end > drag_end-x()) ) ||
267 ( (path_start < drag_start-x()) && (path_end > drag_start-x()) ) ||
268 ( (path_start < drag_end-x()) && (path_end > drag_end-x()) ) )
269 highlight.push_back(true);
271 highlight.push_back(false);
274 fl_line_style(FL_SOLID, 1, NULL);
275 // draw non-highlight paths (ie not in the selection box)
276 highlight_i = highlight.begin();
277 for(i = scaled_pathz.begin(); i != scaled_pathz.end(); ++i)
279 ExtendedConservedPath& a_path = *i;
282 window_size = a_path.window_size;
283 // make sure width is at least 1 - might be zero to my slack rounding
284 if (window_size == 0)
288 for(i2 = 0; i2 < a_path.size()-1; i2++)
291 // ugh, an xor...only want blue if one of the nodes is rc
292 if ( ((a_path[i2] < 0) || (a_path[i2+1] < 0)) &&
293 !((a_path[i2] < 0) && (a_path[i2+1] < 0)) )
294 fl_color(200,200,255);
296 fl_color(255,200,200);
298 fl_line_style(FL_SOLID, 1, NULL);
299 fl_polygon((int)abs(a_path[i2])+x(), y_loc + 3,
300 (int)abs(a_path[i2])+window_size+x(), y_loc + 3,
301 (int)abs(a_path[i2+1])+window_size+x(), y_loc + y_seq_incre - 3,
302 (int)abs(a_path[i2+1])+x(), y_loc + y_seq_incre - 3);
304 y_loc += y_seq_incre;
309 // draw highlighted paths (ie in or partially in selection)
310 // drawing these separately and after other paths so they are on top
311 highlight_i = highlight.begin();
312 for(i = scaled_pathz.begin(); i != scaled_pathz.end(); ++i)
314 ExtendedConservedPath& a_path = *i;
317 // get window size to determine line width
318 window_size = a_path.window_size;
319 // make sure width is at least 1 - might be zero to my slack rounding
320 if (window_size == 0)
324 for(i2 = 0; i2 != a_path.size()-1 ; i2++)
327 // ugh, an xor...only want blue if one of the nodes is rc
328 if ( ((a_path[i2] < 0) || (a_path[i2+1] < 0)) &&
329 !((a_path[i2] < 0) && (a_path[i2+1] < 0)) )
334 fl_polygon((int)abs(a_path[i2])+x(), y_loc + 3,
335 (int)abs(a_path[i2])+window_size+x(), y_loc + 3,
336 (int)abs(a_path[i2+1])+window_size+x(), y_loc + y_seq_incre - 3,
337 (int)abs(a_path[i2+1])+x(), y_loc + y_seq_incre - 3);
339 y_loc += y_seq_incre;
346 list<vector<int> >::iterator i;
349 int path_start, path_end;
355 ConnView::draw_sequence_stuff()
357 int i2, i3, y_loc, y_offset, x_loc, x_start, x_end, mv_offset;
358 list<annot>::iterator annot_i;
359 string species_name, seq_length;
360 stringstream raw_length;
363 // draw sequence representation lines
364 fl_font(FL_COURIER, 14);
365 //fl_color(FL_BLACK);
366 fl_color(100,100,100);
367 // normally size 7, adjust for various screenshotage
368 fl_line_style(FL_SOLID, 11, NULL);
371 for(i2 = 0; i2 < seq_num; i2++)
373 if (i2 == seq_num - 1)
375 x_loc = (int)(seq_lens[i2] / x_scale_factor) + x();
376 //report_float("seq scaled len", x_loc);
377 fl_line(x(),y_loc,x_loc,y_loc);
379 species_name = (*S)[i2].species;
380 fl_draw(species_name.c_str(), x()+w()-name_pad+5, y_loc+y_offset);
382 // funkiness to figure out which genomic scale to report size in
383 if (seq_scales[i2] == 1)
384 raw_length << setprecision(3) << seq_lens[i2] << " bp";
385 else if (seq_scales[i2] == 2)
386 raw_length << setprecision(3) << seq_lens[i2] / 1000.0 << " Kb";
387 else if (seq_scales[i2] == 3)
388 raw_length << setprecision(3) << seq_lens[i2] /1000000.0<< " Mb";
389 seq_length = raw_length.str();
390 fl_draw(seq_length.c_str(), x()+w()-name_pad+5, y_loc+y_offset+15);
393 y_loc += y_seq_incre;
396 //fl_line(x(),y()+y_pad/2,w()-name_pad,y()+y_pad/2);
397 //fl_line(x(),y()+h()-y_pad/2,w()-name_pad,y()+h()-y_pad/2);
400 vector<annot_color>::iterator annot_type_i;
403 fl_line_style(FL_SOLID, 3, NULL);
405 for(i2 = 0; i2 < seq_num; i2++)
407 // loop thru all annotation entries
408 for(annot_i = (*S)[i2].annots.begin(); annot_i != (*S)[i2].annots.end(); ++annot_i)
410 fl_line_style(FL_SOLID, 7, NULL);
413 // loop thru annotation types to determine color
414 annot_type_i = some_annots.begin();
415 bool type_unfound = true;
416 while ((annot_type_i != some_annots.end()) && type_unfound)
418 if (annot_i->type == annot_type_i->type)
420 fl_color(annot_type_i->color);
421 type_unfound = false;
428 // calculate scaled start and end, and draw
429 x_start = (int)(annot_i->start / x_scale_factor) + x();
430 x_end = (int)(annot_i->end / x_scale_factor) + x();
431 fl_line(x_start,y_loc+mv_offset,x_end,y_loc+mv_offset);
433 y_loc += y_seq_incre;
438 vector<motif>::iterator motif_i;
439 vector<int> some_motif_locs;
440 vector<int>::iterator i_locs;
441 int scale_len, motif_len;
444 fl_line_style(FL_SOLID, 9, NULL);
445 motif_i = some_motifs.begin();
446 while (motif_i != some_motifs.end())
448 fl_color(motif_i->color);
449 motif_len = motif_i->seq.length();
450 scale_len = (int) (motif_len / x_scale_factor);
454 if (!motif_i->locations.empty())
455 for(i2 = 0; i2 < seq_num; i2++)
457 some_motif_locs = (*motif_i).locations[i2];
459 i_locs = some_motif_locs.begin();
460 while (i_locs != some_motif_locs.end())
462 x_start = (int)(*i_locs / x_scale_factor) + x();
463 fl_line(x_start,y_loc,x_start+scale_len,y_loc);
466 y_loc += y_seq_incre;
474 ConnView::resize(int new_x, int new_y, int new_w, int new_h)
482 x_scale_factor = (float) max_seq_len / (w() - name_pad);
483 cout << "scale factor is " << x_scale_factor << endl;
484 y_seq_incre = (h()-(2*y_pad)) / (seq_num - 1);
491 ConnView::reporter(string var, int value)
493 cout << var << " : " << value << endl;
498 ConnView::report_float(string var, float value)
500 cout << var << " : " << value << endl;
504 ConnView::handle(int e)
509 // this empty string needs to be put on cout, otherwise the -O optimize
510 // compile option seems to throw this function away with the following:
511 // gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
514 // why do I need a -O for this module? Well, originally I just used the
515 // same compile flags for all modules. I changed that. However, on debian
516 // systems I need the -O otherwise the behavior I observe on redhat machines
517 // with above compiler happens if I don't have that empty cout. WTF
522 if (Fl::event_button3())
527 else if (Fl::event_button2())
536 drag_start = Fl::event_x();
537 y_drag_start = (float) Fl::event_y();
538 ref_seq_num = (int) (round ( (y_drag_start/y_seq_incre) ) );
543 fl_line_style(FL_SOLID, 1, NULL);
544 fl_overlay_rect(drag_start, (ref_seq_num*y_seq_incre)+y(),
545 Fl::event_x()-drag_start, 16);
551 drag_end = Fl::event_x();
559 return_value = Fl_Widget::handle(e);
568 ConnView::check_new_motifs()
570 vector<motif>::iterator i;
572 vector<int> some_motif_locs;
573 vector<int>::iterator i_locs;
575 i = some_motifs.begin();
576 while (i != some_motifs.end())
580 cout << i->seq << " is new\n";
581 i->locations.clear();
582 //i_locs = i->locations;
583 for(i2 = 0; i2 < seq_num; i2++)
585 some_motif_locs = (*S)[i2].find_motif(i->seq);
586 (*i).locations.push_back(some_motif_locs);
589 i_locs = some_motif_locs.begin();
590 while (i_locs != some_motif_locs.end())
592 cout << *i_locs << " ";
609 list<ExtendedConservedPath > selected_paths;
610 list<ExtendedConservedPath >::iterator pathz_i;
611 int i2, i3, y_loc, x_loc, x_start, x_end;
612 list<bool>::iterator highlight_i;
618 // make new list of connections that are highlighted
619 selected_paths.clear();
620 highlight_i = highlight.begin();
621 for(pathz_i = P->refined_pathz.begin();
622 pathz_i != P->refined_pathz.end(); ++pathz_i)
626 ExtendedConservedPath& a_path = *pathz_i;
627 selected_paths.push_back(a_path);
632 // give 50 pixels of height per sequence
633 y_max = seq_num * 50;
634 window_name = "Mussa Sequence: " + analysis_name;
636 a_seq_win = new SeqWindow(800, y_max, (const char*) window_name.c_str(),
637 seq_num, S, selected_paths, seq_lens,
644 ConnView::find_motifs()
646 motif_find_window = new MotifWindow(300, 300, "Motifs", &some_motifs);
650 ConnView::annot_win()
652 annot_color_window = new AnnotWindow(300, 300, "Annotations", &some_annots);
655 // @!@! special hacked in color coding for the myf5/6 region annots
658 if (annot_i->type == "mvista")
661 fl_line_style(FL_SOLID, 8, NULL);
664 else if (annot_i->type == "reg")
666 fl_line_style(FL_SOLID, 10, NULL);
669 if (annot_i->name == "CNS")
671 else if (annot_i->name == "ELA")
673 else if (annot_i->name == "ES")
675 else if (annot_i->name == "NA")
676 fl_color(120,120,120);
677 else if (annot_i->name == "EA")
679 fl_line_style(FL_SOLID, 7, NULL);
683 else if (annot_i->name == "VS")
685 fl_line_style(FL_SOLID, 7, NULL);
689 else if (annot_i->name == "SP")
691 fl_line_style(FL_SOLID, 7, NULL);
693 fl_color(255,230,150);
695 else if (annot_i->name == "L")
697 fl_line_style(FL_SOLID, 7, NULL);
701 else if (annot_i->name == "TCM")