X-Git-Url: http://woldlab.caltech.edu/gitweb/?a=blobdiff_plain;f=alg%2Fglseqbrowser.cpp;h=04cc792ec441e3eeb375fb2ac47bf842d509b3c0;hb=a4ad0c27cefe62ecb4610706fae5aa34479cc9a7;hp=02334cb9f271b5846eefcdd819828835ac557810;hpb=0ec409b9f583b8920d74117b02d889d18f02958d;p=mussa.git diff --git a/alg/glseqbrowser.cpp b/alg/glseqbrowser.cpp index 02334cb..04cc792 100644 --- a/alg/glseqbrowser.cpp +++ b/alg/glseqbrowser.cpp @@ -1,6 +1,7 @@ #include "alg/glseqbrowser.hpp" #include "mussa_exceptions.hpp" +#include #include #include #include @@ -25,7 +26,8 @@ GlSeqBrowser::GlSeqBrowser(const GlSeqBrowser& gt) viewport_center(gt.viewport_center), zoom_level(gt.zoom_level), color_mapper(gt.color_mapper), - track_container(gt.track_container) + track_container(gt.track_container), + path_segments(gt.path_segments) { } @@ -223,6 +225,15 @@ float GlSeqBrowser::right() const } } +float GlSeqBrowser::get_pixel_width() const +{ + GLint viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + GLint vp_width = viewport[3]; // grab the viewport width + + return round((cur_ortho.right-cur_ortho.left)/vp_width); +} + void GlSeqBrowser::setViewportCenter(float x) { update_viewport(x, zoom_level); @@ -254,6 +265,16 @@ float GlSeqBrowser::viewportWidth() const return cur_ortho.right - cur_ortho.left; } +int GlSeqBrowser::viewportPixelHeight() const +{ + return viewport_size.y; +} + +int GlSeqBrowser::viewportPixelWidth() const +{ + return viewport_size.x; +} + double GlSeqBrowser::zoomOut() { @@ -358,7 +379,7 @@ void GlSeqBrowser::clear_links() } void -GlSeqBrowser::link(const vector& path, const vector& rc, int ) +GlSeqBrowser::link(const vector& path, const vector& rc, int length) { if (path.size() < 2) { // should i throw an error instead? @@ -390,12 +411,17 @@ GlSeqBrowser::link(const vector& path, const vector& 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; @@ -435,11 +461,12 @@ list GlSeqBrowser::selectedTracks() const //! copy sequence from selected track using formating function template -void GlSeqBrowser::copySelectedTracks(std::list& result, +size_t GlSeqBrowser::copySelectedTracks(std::list& result, Item (*formatter)(boost::shared_ptr s, int left, int right)) { + size_t base_pairs_copied = 0; result.clear(); for(selected_track_iterator track_i = selected_tracks.begin(); @@ -455,12 +482,14 @@ void GlSeqBrowser::copySelectedTracks(std::list& result, // we should be safe boost::shared_ptr seq = track_container[track_index]->sequence(); result.push_back(formatter(seq, track_i->left, track_i->right)); + base_pairs_copied += max(track_i->right-track_i->left, 0); } } + return base_pairs_copied; } //! copy sequence from selected tracks as FASTA sequences -void GlSeqBrowser::copySelectedTracksAsFasta(std::string& copy_buffer) +size_t GlSeqBrowser::copySelectedTracksAsFasta(std::string& copy_buffer) { std::list result; struct AsFasta { @@ -476,7 +505,7 @@ void GlSeqBrowser::copySelectedTracksAsFasta(std::string& copy_buffer) return s.str(); } }; - copySelectedTracks(result, AsFasta::formatter); + size_t base_pairs_copied = copySelectedTracks(result, AsFasta::formatter); // I wish there was some way to use for_each and bind here for (list::iterator result_i = result.begin(); result_i != result.end(); @@ -484,10 +513,11 @@ void GlSeqBrowser::copySelectedTracksAsFasta(std::string& copy_buffer) { copy_buffer.append(*result_i); } + return base_pairs_copied; } //! copy sequence from selected tracks as new sequences -void GlSeqBrowser::copySelectedTracksAsSequences(std::list& result) +size_t GlSeqBrowser::copySelectedTracksAsSequences(std::list& result) { struct AsSequence { static Sequence formatter(boost::shared_ptr seq, @@ -497,10 +527,10 @@ void GlSeqBrowser::copySelectedTracksAsSequences(std::list& result) return seq->subseq(left, right-left+1); } }; - copySelectedTracks(result, AsSequence::formatter); + return copySelectedTracks(result, AsSequence::formatter); } -void GlSeqBrowser::copySelectedTracksAsSeqLocation( +size_t GlSeqBrowser::copySelectedTracksAsSeqLocation( std::list& result) { struct AsSeqLocation { @@ -511,11 +541,11 @@ void GlSeqBrowser::copySelectedTracksAsSeqLocation( return SequenceLocation(seq, left, right); } }; - copySelectedTracks(result, AsSeqLocation::formatter); + return copySelectedTracks(result, AsSeqLocation::formatter); } //! copy sequence from selected tracks as plain sequences -void GlSeqBrowser::copySelectedTracksAsString(std::string& copy_buffer) +size_t GlSeqBrowser::copySelectedTracksAsString(std::string& copy_buffer) { std::list result; struct AsString { @@ -524,12 +554,12 @@ void GlSeqBrowser::copySelectedTracksAsString(std::string& copy_buffer) int right) { stringstream s; - s << seq->subseq(left, right-left+1) << std::endl; + s << seq->subseq(left, right-left+1); return s.str(); } }; - copySelectedTracks(result, AsString::formatter); + size_t base_pairs_copied = copySelectedTracks(result, AsString::formatter); // I wish there was some way to use for_each and bind here for (list::iterator result_i = result.begin(); result_i != result.end(); @@ -537,7 +567,7 @@ void GlSeqBrowser::copySelectedTracksAsString(std::string& copy_buffer) { copy_buffer.append(*result_i); } - + return base_pairs_copied; } void GlSeqBrowser::centerOnPath(const vector& paths) @@ -644,6 +674,9 @@ void GlSeqBrowser::draw_segments() const glLineWidth(1); glEnable(GL_BLEND); glDepthMask(GL_FALSE); + const float zdepth = -1.0; + const float min_segment_width = max((float)(1.0), get_pixel_width()); + // each vector contains path_segment_maps of all the connections // between this track and the next path_segment_map_vector::const_iterator psmv_i; @@ -671,33 +704,50 @@ void GlSeqBrowser::draw_segments() const back_inserter(selected)); if (not s.reversed) { + // forward if (selected_paths.size() == 0 or selected.size() > 0) { glColor4f(1.0, 0.0, 0.0, 1.0); } else { glColor4f(1.0, 0.7, 0.7, 0.4); } } else { + // reverse if (selected_paths.size() == 0 or selected.size() > 0) { glColor4f(0.0, 0.0, 1.0, 1.0); } 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(); + if (s.length <= min_segment_width) { + // use lines for elements of length <=1 or < 1 pixel. + // and try to center the line + const float offset = s.length * 0.5; + glBegin(GL_LINES); + glVertex3f(seq_start_x+offset, s.start.y, -1); + glVertex3f(seq_end_x +offset, s.end.y, -1); + glEnd(); + } else { + // otherwise use quads + // compute 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_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(); }