-// This file is part of the Mussa source distribution.
-// http://mussa.caltech.edu/
-// Contact author: Tristan De Buysscher, tristan@caltech.edu
-
-// This program and all associated source code files are Copyright (C) 2005
-// the California Institute of Technology, Pasadena, CA, 91125 USA. It is
-// under the GNU Public License; please see the included LICENSE.txt
-// file for more information, or contact Tristan directly.
-
-
-#include "gui/ConnView.hpp"
-
-#include <iomanip>
-#include <math.h>
-
-#include <FL/Fl.H>
-#include <FL/fl_draw.H>
-
-using namespace std;
-
-void
-ConnView::setup(string name, int sq_num, int win_len,
- vector<Sequence> *some_seqs,
- NwayPaths *some_paths)
-{
- int i, i2, seq_length;
- Sequence a_seq;
- fltk_motif blank_motif;
- annot_color new_annot;
-
-
- analysis_name = name;
- seq_num = sq_num;
- window = win_len;
- S = some_seqs;
- P = some_paths;
-
- cout << "num of paths = " << some_paths->refined_pathz.size() << endl;
-
- cout << "x()=" << x() << " y()=" << y() << " w()=" << w() << " h()=" << h();
- cout << endl;
-
- max_seq_len = 0;
- for(i = 0; i < seq_num; ++i)
- {
- a_seq = (*S)[i];
- cout << a_seq.size() << endl;
- seq_length = a_seq.size();
- seq_lens.push_back(seq_length);
- if (seq_length > max_seq_len)
- max_seq_len = seq_length;
- if (seq_length < 1000)
- seq_scales.push_back(1);
- else if (seq_length < 1000000)
- seq_scales.push_back(2);
- else
- seq_scales.push_back(3);
- }
-
- name_pad = 80;
- y_pad = 20;
-
- x_scale_factor = (float) max_seq_len / (w() - name_pad);
- cout << "scale factor is " << x_scale_factor << endl;
- y_seq_incre = (h()-(y_pad*2)) / (seq_num - 1);
-
-
- drag_start = -1000;
- drag_end = -1000;
- ref_seq_num = 0;
-
- dragging = false;
- selected = false;
-
- highlight.clear();
- show_bars = false;
- show_lines = false;
- bar_interval = max_seq_len / 20;
- line_interval = max_seq_len / 20;
- ref_seq_num = 0;
-
-
- some_motifs.clear();
- for(i = 0; i < 5; ++i)
- {
- blank_motif = new_blank_motif();
- some_motifs.push_back(blank_motif);
- }
-
- // find all unique annotation type ids
- some_annots.clear();
- vector<annot_color>::iterator annot_type_i;
- list<annot>::iterator annot_i;
-
- // loop thru all sequences
- for(i2 = 0; i2 < seq_num; i2++)
- {
- cout << "ConnView: annotation loop\n";
- // loop thru all annotation entries in this sequence
- for(annot_i = (*S)[i2].annots.begin(); annot_i != (*S)[i2].annots.end(); ++annot_i)
- {
- cout << annot_i->start << ", " << annot_i->end << " : ";
- cout << annot_i->name << " " << annot_i->type << endl;
- // loop thru annotation types
- annot_type_i = some_annots.begin();
- bool type_unfound = true;
- while ((annot_type_i != some_annots.end()) && type_unfound)
- {
- if (annot_i->type == annot_type_i->type)
- type_unfound = false; // stop search if found
- ++annot_type_i;
- }
- //if unfound, then add to list
- if (type_unfound)
- {
- new_annot = new_blank_annot();
- new_annot.type = annot_i->type;
- some_annots.push_back(new_annot);
- }
- }
- }
-}
-
-
-void
-ConnView::scale_paths()
-{
- ConservedPath a_path;
- list<ConservedPath >::iterator pathz_i;
- int i2;
-
-
- scaled_pathz.clear();
-
- for(pathz_i = P->refined_pathz.begin(); pathz_i != P->refined_pathz.end(); ++pathz_i)
- {
- a_path = *pathz_i;
- a_path.window_size = (int)(a_path.window_size / x_scale_factor);
- for(i2 = 0; i2 != a_path.size(); i2++)
- {
- a_path[i2] = (int) (a_path[i2] / x_scale_factor);
- }
- scaled_pathz.push_back(a_path);
- }
-}
-
-void
-ConnView::toggle_bars()
-{
- show_bars = !show_bars;
- redraw();
-}
-
-void
-ConnView::set_bar_interval(int new_bar_len)
-{
- bar_interval = new_bar_len;
- cout << "bar interval = " << bar_interval << endl;
- redraw();
-}
-
-void
-ConnView::toggle_lines()
-{
- show_lines = !show_lines;
- redraw();
-}
-
-void
-ConnView::set_line_interval(int new_line_len)
-{
- line_interval = new_line_len;
- cout << "line interval = " << line_interval << endl;
- redraw();
-}
-
-
-void
-ConnView::draw()
-{
- // this is temporary - check if new motifs have been added
- check_new_motifs();
-
- // clear drawing area and set background to white
- fl_color(FL_WHITE);
- fl_rectf(x(), y(), w(), h());
-
- // draw the scale indicators if they are on
- // put into own method soon...
- int i, div_num, x_loc;
- float div_len_scaled;
-
- if (show_bars)
- {
- div_num = max_seq_len / bar_interval;
- div_len_scaled = ((float) bar_interval) / x_scale_factor;
- fl_color(230,230,230);
- for(i = 0; i <= div_num; i+=2)
- {
- x_loc = (int)(i * div_len_scaled+x());
- fl_rectf(x_loc, y(), (int) div_len_scaled, h());
- }
- }
-
- if (show_lines)
- {
- div_num = max_seq_len / line_interval;
- div_len_scaled = ((float) line_interval) / x_scale_factor;
- fl_color(0,0,0);
- fl_line_style(FL_SOLID, 1, NULL);
- for(i = 0; i <= div_num; i++)
- {
- x_loc = (int)(i * div_len_scaled+x());
- fl_line(x_loc, y(), x_loc, h()+y());
- }
- }
-
-
- // divide up the space with some light blue lines
- fl_color(150,200,255);
- fl_line_style(FL_SOLID, 2, NULL);
- fl_rect(x(), y(), w(), h());
- fl_line(w()+x()-name_pad, y(), w()+x()-name_pad, h()+y());
-
- draw_paths();
-
- // white out any overdraw from path area into name/info area
- fl_color(FL_WHITE);
- fl_rectf(w()+x()-name_pad, y(), w()+x(), h());
-
- draw_sequence_stuff();
-
- // draw selection box
- /*
- if (selected)
- {
- fl_color(FL_BLACK);
- fl_line_style(FL_SOLID, 1, NULL);
- fl_rect(drag_start,(ref_seq_num*y_seq_incre)+y(),drag_end-drag_start,
- 16);
- }
- */
-}
-
-
-void
-ConnView::draw_paths()
-{
- list<ConservedPath >::iterator i;
- int i2, i3, y_loc, x_loc, x_start, x_end;
- list<bool>::iterator highlight_i;
- int window_size;
- bool rc_color;
- int path_start, path_end;
-
- // determine which paths to highlight
- highlight.clear();
- for(i = scaled_pathz.begin(); i != scaled_pathz.end(); ++i)
- {
- ConservedPath& a_path = *i;
- // determine if path falls within the selected region and mark it for
- // highlighted color
- path_start = abs(a_path[ref_seq_num]);
- path_end = path_start + a_path[0];
- if ( ( (path_start >= drag_start-x()) && (path_end <= drag_end-x()) ) ||
- ( (path_start < drag_start-x()) && (path_end > drag_end-x()) ) ||
- ( (path_start < drag_start-x()) && (path_end > drag_start-x()) ) ||
- ( (path_start < drag_end-x()) && (path_end > drag_end-x()) ) )
- highlight.push_back(true);
- else
- highlight.push_back(false);
- }
-
- fl_line_style(FL_SOLID, 1, NULL);
- // draw non-highlight paths (ie not in the selection box)
- highlight_i = highlight.begin();
- for(i = scaled_pathz.begin(); i != scaled_pathz.end(); ++i)
- {
- ConservedPath& a_path = *i;
- y_loc = y()+y_pad;
-
- window_size = a_path.window_size;
- // make sure width is at least 1 - might be zero to my slack rounding
- if (window_size == 0)
- window_size = 1;
-
- if (!(*highlight_i))
- for(i2 = 0; i2 < a_path.size()-1; i2++)
- {
- // RC case handling
- // ugh, an xor...only want blue if one of the nodes is rc
- if ( ((a_path[i2] < 0) || (a_path[i2+1] < 0)) &&
- !((a_path[i2] < 0) && (a_path[i2+1] < 0)) )
- fl_color(200,200,255);
- else
- fl_color(255,200,200);
-
- fl_line_style(FL_SOLID, 1, NULL);
- fl_polygon((int)abs(a_path[i2])+x(), y_loc + 3,
- (int)abs(a_path[i2])+window_size+x(), y_loc + 3,
- (int)abs(a_path[i2+1])+window_size+x(), y_loc + y_seq_incre - 3,
- (int)abs(a_path[i2+1])+x(), y_loc + y_seq_incre - 3);
-
- y_loc += y_seq_incre;
- }
- ++highlight_i;
- }
-
- // draw highlighted paths (ie in or partially in selection)
- // drawing these separately and after other paths so they are on top
- highlight_i = highlight.begin();
- for(i = scaled_pathz.begin(); i != scaled_pathz.end(); ++i)
- {
- ConservedPath& a_path = *i;
- y_loc = y()+y_pad;
-
- // get window size to determine line width
- window_size = a_path.window_size;
- // make sure width is at least 1 - might be zero to my slack rounding
- if (window_size == 0)
- window_size = 1;
-
- if (*highlight_i)
- for(i2 = 0; i2 != a_path.size()-1 ; i2++)
- {
- // RC case handling
- // ugh, an xor...only want blue if one of the nodes is rc
- if ( ((a_path[i2] < 0) || (a_path[i2+1] < 0)) &&
- !((a_path[i2] < 0) && (a_path[i2+1] < 0)) )
- fl_color(FL_BLUE);
- else
- fl_color(FL_RED);
-
- fl_polygon((int)abs(a_path[i2])+x(), y_loc + 3,
- (int)abs(a_path[i2])+window_size+x(), y_loc + 3,
- (int)abs(a_path[i2+1])+window_size+x(), y_loc + y_seq_incre - 3,
- (int)abs(a_path[i2+1])+x(), y_loc + y_seq_incre - 3);
-
- y_loc += y_seq_incre;
- }
- ++highlight_i;
- }
-}
-
-/*
- list<vector<int> >::iterator i;
- int window_size;
- bool rc_color;
- int path_start, path_end;
- Sequence a_seq;
- vector<int> a_path;
-*/
-
-void
-ConnView::draw_sequence_stuff()
-{
- int i2, i3, y_loc, y_offset, x_loc, x_start, x_end, mv_offset;
- list<annot>::iterator annot_i;
- string species_name, seq_length;
- stringstream raw_length;
-
-
- // draw sequence representation lines
- fl_font(FL_COURIER, 14);
- //fl_color(FL_BLACK);
- fl_color(100,100,100);
- // normally size 7, adjust for various screenshotage
- fl_line_style(FL_SOLID, 11, NULL);
- y_loc = y()+y_pad;
- y_offset = 5;
- for(i2 = 0; i2 < seq_num; i2++)
- {
- if (i2 == seq_num - 1)
- y_offset = -10;
- x_loc = (int)(seq_lens[i2] / x_scale_factor) + x();
- //report_float("seq scaled len", x_loc);
- fl_line(x(),y_loc,x_loc,y_loc);
-
- species_name = (*S)[i2].species;
- fl_draw(species_name.c_str(), x()+w()-name_pad+5, y_loc+y_offset);
-
- // funkiness to figure out which genomic scale to report size in
- if (seq_scales[i2] == 1)
- raw_length << setprecision(3) << seq_lens[i2] << " bp";
- else if (seq_scales[i2] == 2)
- raw_length << setprecision(3) << seq_lens[i2] / 1000.0 << " Kb";
- else if (seq_scales[i2] == 3)
- raw_length << setprecision(3) << seq_lens[i2] /1000000.0<< " Mb";
- seq_length = raw_length.str();
- fl_draw(seq_length.c_str(), x()+w()-name_pad+5, y_loc+y_offset+15);
- raw_length.str("");
-
- y_loc += y_seq_incre;
- }
-
- //fl_line(x(),y()+y_pad/2,w()-name_pad,y()+y_pad/2);
- //fl_line(x(),y()+h()-y_pad/2,w()-name_pad,y()+h()-y_pad/2);
-
- // draw annotations
- vector<annot_color>::iterator annot_type_i;
-
- fl_color(FL_GREEN);
- fl_line_style(FL_SOLID, 3, NULL);
- y_loc = y()+y_pad;
- for(i2 = 0; i2 < seq_num; i2++)
- {
- // loop thru all annotation entries
- for(annot_i = (*S)[i2].annots.begin(); annot_i != (*S)[i2].annots.end(); ++annot_i)
- {
- fl_line_style(FL_SOLID, 7, NULL);
- mv_offset = 0;
-
- // loop thru annotation types to determine color
- annot_type_i = some_annots.begin();
- bool type_unfound = true;
- while ((annot_type_i != some_annots.end()) && type_unfound)
- {
- if (annot_i->type == annot_type_i->type)
- {
- fl_color(annot_type_i->color);
- type_unfound = false;
- }
- else
- fl_color(FL_GREEN);
- ++annot_type_i;
- }
-
- // calculate scaled start and end, and draw
- x_start = (int)(annot_i->start / x_scale_factor) + x();
- x_end = (int)(annot_i->end / x_scale_factor) + x();
- fl_line(x_start,y_loc+mv_offset,x_end,y_loc+mv_offset);
- }
- y_loc += y_seq_incre;
- }
-
-
- // draw motifs found
- vector<fltk_motif>::iterator motif_i;
- vector<int> some_motif_locs;
- vector<int>::iterator i_locs;
- int scale_len, motif_len;
-
- fl_color(255,0,255);
- fl_line_style(FL_SOLID, 9, NULL);
- motif_i = some_motifs.begin();
- while (motif_i != some_motifs.end())
- {
- fl_color(motif_i->color);
- motif_len = motif_i->seq.length();
- scale_len = (int) (motif_len / x_scale_factor);
- if (scale_len == 0)
- scale_len = 1;
- y_loc = y()+y_pad;
- if (!motif_i->locations.empty())
- for(i2 = 0; i2 < seq_num; i2++)
- {
- some_motif_locs = (*motif_i).locations[i2];
-
- i_locs = some_motif_locs.begin();
- while (i_locs != some_motif_locs.end())
- {
- x_start = (int)(*i_locs / x_scale_factor) + x();
- fl_line(x_start,y_loc,x_start+scale_len,y_loc);
- ++i_locs;
- }
- y_loc += y_seq_incre;
- }
- ++motif_i;
- }
-}
-
-
-void
-ConnView::resize(int new_x, int new_y, int new_w, int new_h)
-{
-
- x(new_x);
- y(new_y);
- w(new_w);
- h(new_h);
-
- x_scale_factor = (float) max_seq_len / (w() - name_pad);
- cout << "scale factor is " << x_scale_factor << endl;
- y_seq_incre = (h()-(2*y_pad)) / (seq_num - 1);
-
- scale_paths();
-}
-
-
-void
-ConnView::reporter(string var, int value)
-{
- cout << var << " : " << value << endl;
-}
-
-
-void
-ConnView::report_float(string var, float value)
-{
- cout << var << " : " << value << endl;
-}
-
-int
-ConnView::handle(int e)
-{
- int return_value;
- float y_calc_tmp;
-
- // this empty string needs to be put on cout, otherwise the -O optimize
- // compile option seems to throw this function away with the following:
- // gcc version 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
- cout << "";
-
- // why do I need a -O for this module? Well, originally I just used the
- // same compile flags for all modules. I changed that. However, on debian
- // systems I need the -O otherwise the behavior I observe on redhat machines
- // with above compiler happens if I don't have that empty cout. WTF
-
- switch(e)
- {
- case FL_PUSH:
- if (Fl::event_button3())
- {
- spawnSeq();
- return_value = 1;
- }
- else if (Fl::event_button2())
- {
- find_motifs();
- return_value = 1;
- }
- break;
- case FL_DRAG:
- if (!dragging)
- {
- drag_start = Fl::event_x();
- y_drag_start = (float) Fl::event_y();
- ref_seq_num = (int) (round ( (y_drag_start/y_seq_incre) ) );
- dragging = true;
- selected = false;
- return_value = 1;
- }
- fl_line_style(FL_SOLID, 1, NULL);
- fl_overlay_rect(drag_start, (ref_seq_num*y_seq_incre)+y(),
- Fl::event_x()-drag_start, 16);
-
- break;
- case FL_RELEASE:
- if (dragging)
- {
- drag_end = Fl::event_x();
- dragging = false;
- selected = true;
- redraw();
- return_value = 1;
- }
- break;
- default:
- return_value = Fl_Widget::handle(e);
- }
-
- return return_value;
-}
-
-
-
-void
-ConnView::check_new_motifs()
-{
- vector<fltk_motif>::iterator i;
- int i2;
- vector<int> some_motif_locs;
- vector<int>::iterator i_locs;
-
- i = some_motifs.begin();
- while (i != some_motifs.end())
- {
- if (i->dirty)
- {
- cout << i->seq << " is new\n";
- i->locations.clear();
- //i_locs = i->locations;
- for(i2 = 0; i2 < seq_num; i2++)
- {
- some_motif_locs = (*S)[i2].find_motif(i->seq);
- (*i).locations.push_back(some_motif_locs);
-
-
- i_locs = some_motif_locs.begin();
- while (i_locs != some_motif_locs.end())
- {
- cout << *i_locs << " ";
- ++i_locs;
- }
- cout << endl;
-
- }
-
- i->dirty = false;
- }
- ++i;
- }
-}
-
-
-void
-ConnView::spawnSeq()
-{
- list<ConservedPath > selected_paths;
- list<ConservedPath >::iterator pathz_i;
- int i2, i3, y_loc, x_loc, x_start, x_end;
- list<bool>::iterator highlight_i;
- int y_max;
- string window_name;
-
- if (selected)
- {
- // make new list of connections that are highlighted
- selected_paths.clear();
- highlight_i = highlight.begin();
- for(pathz_i = P->refined_pathz.begin();
- pathz_i != P->refined_pathz.end(); ++pathz_i)
- {
- if (*highlight_i)
- {
- selected_paths.push_back(*pathz_i);
- }
- ++highlight_i;
- }
-
- // give 50 pixels of height per sequence
- y_max = seq_num * 50;
- window_name = "Mussa Sequence: " + analysis_name;
-
- a_seq_win = new SeqWindow(800, y_max, (const char*) window_name.c_str(),
- seq_num, S, selected_paths, seq_lens,
- &some_motifs);
- }
-}
-
-
-void
-ConnView::find_motifs()
-{
- motif_find_window = new MotifWindow(300, 300, "Motifs", &some_motifs);
-}
-
-void
-ConnView::annot_win()
-{
- annot_color_window = new AnnotWindow(300, 300, "Annotations", &some_annots);
-}
-
-// @!@! special hacked in color coding for the myf5/6 region annots
-
-/*
- if (annot_i->type == "mvista")
- {
- fl_color(255,230,0);
- fl_line_style(FL_SOLID, 8, NULL);
- mv_offset = -4;
- }
- else if (annot_i->type == "reg")
- {
- fl_line_style(FL_SOLID, 10, NULL);
- mv_offset = -8;
-
- if (annot_i->name == "CNS")
- fl_color(255,150,0);
- else if (annot_i->name == "ELA")
- fl_color(0,200,120);
- else if (annot_i->name == "ES")
- fl_color(0,200,200);
- else if (annot_i->name == "NA")
- fl_color(120,120,120);
- else if (annot_i->name == "EA")
- {
- fl_line_style(FL_SOLID, 7, NULL);
- mv_offset = -13;
- fl_color(0,200,120);
- }
- else if (annot_i->name == "VS")
- {
- fl_line_style(FL_SOLID, 7, NULL);
- mv_offset = -6;
- fl_color(255,255,0);
- }
- else if (annot_i->name == "SP")
- {
- fl_line_style(FL_SOLID, 7, NULL);
- mv_offset = -13;
- fl_color(255,230,150);
- }
- else if (annot_i->name == "L")
- {
- fl_line_style(FL_SOLID, 7, NULL);
- mv_offset = -6;
- fl_color(0,0,100);
- }
- else if (annot_i->name == "TCM")
- fl_color(0,130,230);
- }
-*/