draw link lines with a width
authorDiane Trout <diane@caltech.edu>
Thu, 5 Oct 2006 01:29:19 +0000 (01:29 +0000)
committerDiane Trout <diane@caltech.edu>
Thu, 5 Oct 2006 01:29:19 +0000 (01:29 +0000)
ticket:134
Segments connecting two sequence locations together now have a "length"
field which is drawn as a width across the screen.

The problem with this patch is that on the sequence view, where you want
a narrow line, it's drawing something the width of the base pair.

perhaps that's ok, or perhaps in that case I can have a length of 0,
or perhaps lenghts of 1 could also be drawn as a line, or perhaps
the edges of one of these rectangles should be shrunk a bit.

(that might also make things look a bit more centered.

alg/glseqbrowser.cpp
alg/glseqbrowser.hpp
alg/test/test_glseqbrowser.cpp

index 02334cb9f271b5846eefcdd819828835ac557810..e82cfe1f48fab2cd13fb3f82dba47e6d62bef5f9 100644 (file)
@@ -358,7 +358,7 @@ void GlSeqBrowser::clear_links()
 }
 
 void 
-GlSeqBrowser::link(const vector<int>& path, const vector<bool>& rc, int )
+GlSeqBrowser::link(const vector<int>& path, const vector<bool>& rc, int length)
 {
   if (path.size() < 2) {
     // should i throw an error instead?
@@ -390,12 +390,17 @@ GlSeqBrowser::link(const vector<int>& path, const vector<bool>& rc, int )
             y2 += track_container[track_i+1]->height()/2;
       
       bool rcFlag = (prev_rc or *rc_i) and !(prev_rc and *rc_i);
-      Segment s(prev_x, y1, *path_i, y2, rcFlag);
+      Segment s(prev_x, y1, *path_i, y2, rcFlag, length);
       s.path_ids.insert(pathid);
       path_segments[track_i][p] = s;
     } else {
       //found
       found_segment->second.path_ids.insert(pathid);
+      // make each segment the size of the largest of any link between these 
+      // two bases
+      if (found_segment->second.length < length) {
+        found_segment->second.length = length;
+      }
     }
     prev_x = *path_i;
     prev_rc = *rc_i;
@@ -644,6 +649,7 @@ void GlSeqBrowser::draw_segments() const
   glLineWidth(1);
   glEnable(GL_BLEND);
   glDepthMask(GL_FALSE);
+  const float zdepth = -1.0;
   // each vector contains path_segment_maps of all the connections
   // between this track and the next
   path_segment_map_vector::const_iterator psmv_i;
@@ -682,22 +688,31 @@ void GlSeqBrowser::draw_segments() const
         } else {
           glColor4f(0.7, 0.7, 1.0, 0.4);
         }
-        /*
-        if (selected_paths.size() == 0 or selected.size() > 0) {
-          glColor3f(0.0, 0.0, 1.0);
-        } else {
-          glColor3f(0.8, 0.8, 1.0);
-        }
-        */
       }
       // save the multipart name for our segment
       glPushName(path_index); glPushName(key.first); glPushName(key.second);
-      glBegin(GL_LINES);
-      float seq_start_x = track_container[path_index]->x();
-      float seq_end_x = track_container[path_index+1]->x();
-      glVertex3f(s.start.x + seq_start_x, s.start.y, -1);
-      glVertex3f(s.end.x   + seq_end_x  , s.end.y, -1);
-      glEnd();
+      float seq_start_x = s.start.x 
+                        + track_container[path_index]->x();
+      float seq_end_x = s.end.x
+                      + track_container[path_index+1]->x();
+      // add in length
+      float seq_start_x_length = s.start.x 
+                               + s.length
+                               + track_container[path_index]->x();
+      float seq_end_x_length = s.end.x
+                             + s.length
+                             + track_container[path_index+1]->x();
+      //glBegin(GL_LINES);
+      //  glVertex3f(seq_start_x, s.start.y, -1);
+      //  glVertex3f(seq_end_x  , s.end.y, -1);
+      //glEnd();
+      
+      glBegin(GL_QUADS);
+        glVertex3f(seq_start_x, s.start.y, zdepth);
+        glVertex3f(seq_end_x, s.end.y, zdepth);
+        glVertex3f(seq_end_x_length, s.end.y, zdepth);
+        glVertex3f(seq_start_x_length, s.start.y, zdepth);
+      glEnd();      
       // clear the names
       glPopName(); glPopName(); glPopName();
     }
index ba33704bb481f492b116385841889b01c20ffdf8..9b2e16f26572bf4d1d55afdb0113b226cba822a9 100644 (file)
@@ -142,11 +142,13 @@ public:
     point<float> start;
     point<float> end;
     bool reversed;
+    int length;
+    // each integer represents an index into our list of paths
     std::set<int> path_ids;
 
-    Segment() : start(0.0, 0.0), end(0.0, 0.0) {}
-    Segment(float x1, float y1, float x2, float y2, bool isRC) 
-      : start(x1, y1), end(x2, y2), reversed(isRC) {}
+    Segment() : start(0.0, 0.0), end(0.0, 0.0), reversed(false), length(0) {}
+    Segment(float x1, float y1, float x2, float y2, bool isRC, int length_
+      : start(x1, y1), end(x2, y2), reversed(isRC), length(length_) {}
   };
 
   //! data structure holding our line segments
@@ -154,7 +156,7 @@ public:
    *  it's indexed by the pair x1, x2 (the two x coordinates between
    *  the two tracks
    */
-  typedef std::pair<int, int> segment_key;
+  typedef std::pair<int, int> segment_key;  
   typedef std::map<segment_key, Segment> pair_segment_map;
   typedef std::vector<pair_segment_map> path_segment_map_vector;
   path_segment_map_vector path_segments;
index 9e23d28436b32e03dcaf93d3f6f82b6471170620..8dae0d0feee8fbc8d35ecc857570a06408caa514 100644 (file)
@@ -34,19 +34,80 @@ BOOST_AUTO_TEST_CASE ( gltracks_connect )
   vector<int> path;
                 path += 1,1,1; gt.link(path, rc, 1);
   path.clear(); path += 1,1,3; gt.link(path, rc, 1); 
+  path.clear(); path += 1,2,1; gt.link(path, rc, 1);                 
   path.clear(); path += 2,3,3; gt.link(path, rc, 1); 
   path.clear(); path += 3,3,3; gt.link(path, rc, 1);
 
+  // this represents the "depth" of the path_segment AKA sequences -1
   BOOST_CHECK_EQUAL( gt.path_segments.size(), 2 );
-  GlSeqBrowser::segment_key p(1, 1);
-  GlSeqBrowser::pair_segment_map::iterator psm_i = gt.path_segments[0].find(p);
+  BOOST_CHECK_EQUAL( gt.path_segments[0].size(), 4);
+  BOOST_CHECK_EQUAL( gt.path_segments[1].size(), 4);
+  GlSeqBrowser::segment_key p11(1, 1);
+  GlSeqBrowser::segment_key p23(2, 3);
+  GlSeqBrowser::segment_key p33(3, 3);
+  GlSeqBrowser::segment_key p13(1, 3);
+  GlSeqBrowser::pair_segment_map::iterator psm_i = gt.path_segments[0].find(p11);
   BOOST_CHECK( psm_i != gt.path_segments[0].end() );
   BOOST_CHECK_EQUAL( psm_i->second.path_ids.size(), 2 );
-
+  // exaustively test the other keys in the first row
+  psm_i = gt.path_segments[0].find(p23);
+  BOOST_CHECK( psm_i != gt.path_segments[0].end());
+  psm_i = gt.path_segments[0].find(p33);
+  BOOST_CHECK( psm_i != gt.path_segments[0].end());
+  // should be missing
+  psm_i = gt.path_segments[0].find(p13); 
+  BOOST_CHECK( psm_i == gt.path_segments[0].end());
+  
   gt.clear();
   BOOST_CHECK_EQUAL( gt.path_segments.size(), 0 );
 }
 
+BOOST_AUTO_TEST_CASE ( gltracks_connect_different_lengths )
+{
+  string s0("AAGGCCTT");
+  string s1("TTGGCCAA");
+  string s2("GATTACAA");
+  Sequence seq0(s0);
+  Sequence seq1(s1);
+  Sequence seq2(s2);
+
+  GlSeqBrowser gt;
+  gt.push_sequence(seq0);
+  gt.push_sequence(seq1);
+  gt.push_sequence(seq2);
+
+  // make up some sample data
+  vector<bool> rc;
+  rc += false, false, false;
+  vector<int> path;
+                path += 1,1,1; gt.link(path, rc, 5);
+  path.clear(); path += 1,1,3; gt.link(path, rc, 1); 
+  path.clear(); path += 2,3,3; gt.link(path, rc, 1); 
+  path.clear(); path += 3,3,3; gt.link(path, rc, 3);
+  path.clear(); path += 4,3,3; gt.link(path, rc, 2);
+
+  // this represents the "depth" of the path_segment AKA sequences -1
+  BOOST_CHECK_EQUAL( gt.path_segments.size(), 2 );
+  BOOST_CHECK_EQUAL( gt.path_segments[0].size(), 4);
+  BOOST_CHECK_EQUAL( gt.path_segments[1].size(), 3);
+  GlSeqBrowser::segment_key p1(1, 1);
+  GlSeqBrowser::pair_segment_map::iterator psm1_i = gt.path_segments[0].find(p1);
+  BOOST_CHECK( psm1_i != gt.path_segments[0].end() );
+  BOOST_CHECK_EQUAL( psm1_i->second.start.x, 1); //start segment x coordinate
+  BOOST_CHECK_EQUAL( psm1_i->second.end.x, 1); //end segment x coordinate
+  BOOST_CHECK_EQUAL( psm1_i->second.length, 5); 
+  // there should be two paths, the sizes don't match
+  BOOST_CHECK_EQUAL( psm1_i->second.path_ids.size(), 2 );
+  
+  // look at the second row
+  GlSeqBrowser::segment_key p2(3,3);
+  GlSeqBrowser::pair_segment_map::iterator psm2_i = gt.path_segments[1].find(p2);
+  BOOST_CHECK( psm2_i != gt.path_segments[1].end() );
+  BOOST_CHECK_EQUAL( psm2_i->second.start.x, 3); //start segment x coordinate
+  BOOST_CHECK_EQUAL( psm2_i->second.end.x, 3); //end segment x coordinate
+  BOOST_CHECK_EQUAL( psm2_i->second.length, 3); 
+}
+
 BOOST_AUTO_TEST_CASE( glseqbrowser_center )
 {
   string s0("AAGGCCTT");