NCBI C++ ToolKit
seq_graph.cpp
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* $Id: seq_graph.cpp 41823 2018-10-17 17:34:58Z katargir $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Colleen Bollin (adapted from a file by Andrey Yazhuk)
27  *
28  * File Description:
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
33 #include <corelib/ncbistl.hpp>
35 
36 #include <gui/objutils/utils.hpp>
37 #include <gui/objutils/label.hpp>
38 #include <gui/opengl/glhelpers.hpp>
39 #include <gui/opengl/irender.hpp>
40 
41 #include <objmgr/seq_vector.hpp>
42 #include <objmgr/util/sequence.hpp>
43 
44 #include <math.h>
45 
48 
50 : m_pSeqFont(NULL),
51  m_BackColor(0.9f, 0.9f, 0.9f),
52  m_TextColor(0.0f, 0.0f, 0.0f),
53  m_FeatColor(0.0f, 0.6f, 0.0f),
54  m_SpliceBoxColor(0.5f, 0.5f, 0.5f),
55  m_TextHeight(0),
56  m_TextOffset(0),
57  m_pHost(NULL),
58  m_pGeometry(NULL)
59 {
60 }
61 
63 {
64  m_pSeqFont = seq_font;
65 }
66 
68 {
69  m_DataSource = p_ds;
70 }
71 
72 
74 {
75  m_Config = p_cfg;
76 }
77 
78 
80 {
81  m_pHost = pHost;
82 }
83 
84 
86 {
87  m_pGeometry = pGeometry;
88 }
89 
90 
91 static const int kMargin = 2;
92 static const int kTextOffset = 2;
93 
95 {
96  int spacing = 2 * kMargin;
97  TVPPoint size(spacing, spacing);
98 
100  size.m_Y += 2 * kTextOffset + (int) ceil(seq_h);
101  return size;
102 }
103 
104 
105 void
107 (CSeqTextDefs::TSpliceSiteVector splice_sites,
108  TSeqPos seq_start, TSeqPos num_chars_per_row,
109  TModelUnit offset_X, TModelUnit offset_Y)
110 {
111  IRender& gl = GetGl();
112 
113  unsigned int i;
114  TModelUnit x1, x2, y1, y2;
115 
116  /* use a fine line to indicate feature location */
117  gl.LineWidth (0.5);
119  for (i = seq_start; i < seq_start + num_chars_per_row; i++) {
120  if (splice_sites [i]) {
121  x1 = offset_X + i - seq_start - 0.5;
122  x2 = offset_X + i - seq_start + 0.5;
123  y1 = offset_Y - m_TextOffset;
124  y2 = offset_Y + m_TextHeight - m_TextOffset;
125  gl.Begin (GL_LINES);
126  gl.Vertex2d(x1, y1);
127  gl.Vertex2d(x2, y1);
128 
129  gl.Vertex2d(x2, y1);
130  gl.Vertex2d(x2, y2);
131 
132  gl.Vertex2d(x2, y2);
133  gl.Vertex2d(x1, y2);
134 
135  gl.Vertex2d(x1, y2);
136  gl.Vertex2d(x1, y1);
137  gl.End();
138  }
139  }
140 }
141 
142 
143 void
147  TSeqPos seq_start, TSeqPos num_chars_per_row)
148 {
149  unsigned int i;
150 
151  colors.clear();
152  for (i = seq_start; i < subtypes.size() && i - seq_start < num_chars_per_row; i++) {
153  if (m_Config && subtypes[i] != CSeqFeatData::eSubtype_bad)
154  {
155  colors.push_back (m_Config->GetColor(subtypes[i]));
156  }
157  else
158  {
159  colors.push_back (&m_TextColor);
160  }
161  }
162 }
163 
164 
167  TSeqPos seq_start, TSeqPos num_chars_per_row)
168 {
169  IRender& gl = GetGl();
170 
171  unsigned int i;
172 
173  for (i = 0; i < breaks.size(); i++) {
174  if (breaks[i] >= seq_start && breaks[i] <= seq_start + num_chars_per_row) {
176  gl.Begin(GL_LINES);
177  gl.Vertex2d (x + breaks[i] - seq_start - 0.5, y);
178  gl.Vertex2d (x + breaks[i] - seq_start - 0.5, y + m_TextHeight - m_TextOffset);
179 
180  gl.Vertex2d (x + breaks[i] - seq_start, y + m_TextHeight - m_TextOffset);
181  gl.Vertex2d (x + breaks[i] - seq_start - 1, y + m_TextHeight - m_TextOffset);
182  gl.End();
183  }
184  }
185 }
186 
187 
188 void
190 (TSeqPos seq_start,
191  TSeqPos num_chars_per_row,
192  float scale_x,
193  float scale_y,
195 {
196  unsigned int first_var = 0, i;
198  CRgbaColor* variation_color;
199 
200  if (!m_Config) {
201  return;
202  }
203 
204  for (i = 0; i < variations.size(); i++) {
205  for (unsigned int k = i + 1;
206  k < variations.size() && variations[k].GetFeatLeft() < variations[i].GetFeatLeft() + variations[i].GetDrawWidth();
207  k++) {
208  variations[k].SetDisplayLine(max (variations[i].GetDisplayLine() + 1, variations[k].GetDisplayLine()));
209  }
210  }
211 
212  while (first_var < variations.size() && variations[first_var].GetFeatRight() < seq_start) {
213  first_var++;
214  }
215 
216  if (first_var == variations.size()) {
217  return;
218  }
219 
220  colors.clear();
221  // start with 5 - add more if a longer variation is encountered
223  colors.push_back (variation_color);
224  colors.push_back (variation_color);
225  colors.push_back (variation_color);
226  colors.push_back (variation_color);
227  colors.push_back (variation_color);
228 
229  while (first_var < variations.size() && variations[first_var].GetFeatLeft() < seq_start + num_chars_per_row) {
230  TSeqPos varlinestart = max (seq_start, variations[first_var].GetFeatLeft());
231  TSeqPos varlinestop = min (seq_start + num_chars_per_row - 1,
232  variations[first_var].GetFeatLeft() + variations[first_var].GetDrawWidth());
233  if (varlinestart <= varlinestop) {
234  TModelPoint seq_left = m_pGeometry->STG_GetModelPointBySourcePos(varlinestart);
235  TModelPoint seq_right = m_pGeometry->STG_GetModelPointBySourcePos(varlinestop);
236  //TSeqPos draw_width = min (variations[first_var].GetDrawWidth(), varlinestop - varlinestart + 1);
237  seq_left.m_Y -= variations[first_var].GetDisplayLine();
238  seq_right.m_Y -= variations[first_var].GetDisplayLine();
239 
240  // print variation text
241  TSeqPos var_start = 0;
242  if (varlinestart > variations[first_var].GetFeatLeft()) {
243  var_start = varlinestart - variations[first_var].GetFeatLeft();
244  }
245  // add extra colors to vector as needed
246  while (colors.size() < varlinestop - varlinestart + 1) {
247  colors.push_back (variation_color);
248  }
249  m_pSeqFont->ArrayTextOut((float) seq_left.m_X + 0.5, (float) seq_left.m_Y, 1.0f, 0.0f,
250  variations[first_var].GetText().substr(var_start, varlinestop - varlinestart + 1).c_str(),
251  &colors,
252  scale_x, scale_y);
253  }
254  first_var++;
255  }
256 }
257 
258 
260 {
261  IRender& gl = GetGl();
262 
263  if (m_DataSource)
264  {
267 
268  TSeqPos chars_in_line, lines_in_seq;
269  m_pGeometry->STG_GetLineInfo(chars_in_line, lines_in_seq);
270  if (chars_in_line < 1) {
271  return;
272  }
273 
274  TModelUnit scale_x = pane.GetScaleX();
275  TModelUnit scale_y = pane.GetScaleY();
276 
277  if (scale_x < 0) return;
278 
281 
282 
283  // fill background
284  gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
285 /*
286  TVPRect rc_back(m_VPRect);
287  rc_back.Inflate(0, -kMargin);
288 
289  {
290  CGlPaneGuard GUARD(pane, CGlPane::ePixels);
291  gl.ColorC(m_BackColor);
292  gl.Rectd(rc_back.Left(), rc_back.Bottom(), rc_back.Right(), rc_back.Top());
293  }
294 */
295  // draw sequence
296  CGlPaneGuard GUARD(pane, CGlPane::eOrtho);
297  gl.ColorC(m_TextColor);
298 
300  colors.reserve(chars_in_line);
301 
303  CSeqTextDefs::TSpliceSiteVector splice_sites;
306  string seq;
307 
308  breaks.clear();
309  variations.clear();
310  string substr;
311  // if this is an mRNA Bioseq, color exons alternately
312  bool color_exons_for_mrna = true;
313 
314  TSeqPos vis_start, vis_stop;
315  m_pGeometry->STG_GetVisibleRange (vis_start, vis_stop);
316  subtypes.reserve((vis_stop - vis_start) + 1);
317  splice_sites.reserve((vis_stop - vis_start) + 1);
318 
319  // get sequence data and feature data for entire pane
320  m_DataSource->GetFeatureData (vis_start, vis_stop, m_Config, m_pGeometry, subtypes, splice_sites, variations);
321 
322  // if choice is selected or mouseover, recalculate subtypes
323  if (m_pHost && m_Config) {
325  if (disp == CSeqTextPaneConfig::eSelected) {
327  color_exons_for_mrna = false;
328  } else if (disp == CSeqTextPaneConfig::eMouseOver) {
330  color_exons_for_mrna = false;
331  }
332  }
333 
334  if (color_exons_for_mrna) {
335  m_DataSource->GetSubtypesForAlternatingExons (vis_start, vis_stop, m_pGeometry, subtypes);
336  }
337 
338  // mark breaks in sequence
339  m_DataSource->GetIntervalBreaks (vis_start > 0 ? vis_start - 1 : vis_start, vis_stop, breaks);
340 
341  // show "case feature" in different case
342  m_DataSource->GetSeqData (vis_start, vis_stop, seq,
344  m_Config ? m_Config->GetShowFeatAsLower() : false);
345 
346  TSeqPos row_start = vis_start;
348  while (row_start < vis_stop && row_start < len)
349  {
350  TModelPoint start_point = m_pGeometry->STG_GetModelPointBySourcePos (row_start);
351  start_point.m_X += 0.5;
352 
353  // draw boxes around splice junction characters
354  x_BoxCharacters (splice_sites, row_start - vis_start, chars_in_line, start_point.m_X, start_point.m_Y);
355 
356  // draw lines to indicate discontigous sequence
357  x_DrawIntervalBreaks (start_point.m_X, start_point.m_Y, breaks, row_start, chars_in_line);
358 
359  // show features in foreground color
360  colors.clear();
361  x_GetColors (subtypes, colors, row_start - vis_start, chars_in_line);
362 
363  substr = seq.substr (row_start - vis_start, chars_in_line);
364  m_pSeqFont->ArrayTextOut((float) start_point.m_X, (float) start_point.m_Y, 1.0f, 0.0f,
365  substr.c_str(), &colors,
366  (float) scale_x, (float) scale_y);
367 
368  // draw variations
369  x_DrawVariations (row_start, chars_in_line, (float) scale_x, (float) scale_y, variations);
370 
371  row_start += chars_in_line;
372  }
373  }
374 }
375 
376 
378 {
379  x_RenderSequence (pane);
380 }
381 
382 
383 bool CSequenceTextGraph::NeedTooltip(CGlPane& /*pane*/, int vp_x, int vp_y)
384 {
385  return m_VPRect.PtInRect(vp_x, vp_y);
386 }
387 
388 
390 {
391  if (m_DataSource) {
392  return m_DataSource->GetTitle();
393  } else {
394  return "No sequence loaded";
395  }
396 }
397 
398 
400 {
401  // TODO initialize m_ModelRect in the place where Data Source is set
402  // then use m_ModelRect here
403  TSeqPos len = 0;
404 
405  if (m_DataSource) {
406  CSequenceTextGraph* nc_this = const_cast<CSequenceTextGraph*>(this);
407  len = nc_this->m_DataSource->GetDataLen();
408  }
409  TModelRect rc_model(0.0, 0.0, len, 1.0);
410  return rc_model;
411 }
412 
413 
415 {
416  _ASSERT(false); // not supported
417 }
418 
419 
class CGlPane
Definition: glpane.hpp:62
class CRgbaColor provides a simple abstraction for managing colors.
Definition: rgba_color.hpp:58
@ eSubtype_bad
These no longer need to match the FEATDEF values in the C toolkit's objfdef.h.
bool GetShowFeatAsLower()
CRgbaColor * GetColor(int subtype) const
objects::SAnnotSelector * GetCaseFeature()
CSeqTextPaneConfig::EFeatureDisplayType GetFeatureColorationChoice()
CSeqTextDataSource implements Adapter design pattern.
void GetSeqData(TSeqPos start, TSeqPos stop, string &buffer, objects::SAnnotSelector *feat_sel=NULL, bool showFeatAsLower=false)
void GetFeatureData(TSeqPos start_offset, TSeqPos stop_offset, CSeqTextConfig *cfg, ISeqTextGeometry *pParent, CSeqTextDefs::TSubtypeVector &subtypes, CSeqTextDefs::TSpliceSiteVector &splice_sites, CSeqTextDefs::TVariationGraphVector &variations)
void GetIntervalBreaks(TSeqPos start_offset, TSeqPos stop_offset, CSeqTextDefs::TSeqPosVector &breaks)
void GetSubtypesForAlternatingExons(TSeqPos start_offset, TSeqPos stop_offset, ISeqTextGeometry *pParent, CSeqTextDefs::TSubtypeVector &subtypes)
vector< CSeqTextVariationGraph > TVariationGraphVector
vector< bool > TSpliceSiteVector
vector< int > TSubtypeVector
vector< TSeqPos > TSeqPosVector
CSequenceTextGraph.
Definition: seq_graph.hpp:60
ISequenceTextGraphHost * m_pHost
Definition: seq_graph.hpp:113
virtual TVPPoint PreferredSize()
Definition: seq_graph.cpp:94
virtual void Render(CGlPane &pane)
Definition: seq_graph.cpp:377
void SetFont(CGlTextureFont *seq_font)
Definition: seq_graph.cpp:62
void x_GetColors(CSeqTextDefs::TSubtypeVector &subtypes, TColorVector &colors, TSeqPos seq_start, TSeqPos num_chars_per_row)
Definition: seq_graph.cpp:145
vector< CRgbaColor * > TColorVector
Definition: seq_graph.hpp:64
void x_BoxCharacters(ncbi::CSeqTextDefs::TSpliceSiteVector splice_sites, TSeqPos seq_start, TSeqPos num_chars_per_row, TModelUnit offset_X, TModelUnit offset_Y)
Definition: seq_graph.cpp:107
virtual void SetModelRect(const TModelRect &rc)
Definition: seq_graph.cpp:414
virtual bool NeedTooltip(CGlPane &pane, int vp_x, int vp_y)
Definition: seq_graph.cpp:383
void x_RenderSequence(CGlPane &pane)
Definition: seq_graph.cpp:259
void SetGeometry(ISeqTextGeometry *pGeometry)
Definition: seq_graph.cpp:85
virtual void SetDataSource(CSeqTextDataSource *p_ds)
Definition: seq_graph.cpp:67
void SetConfig(CSeqTextConfig *p_cfg)
Definition: seq_graph.cpp:73
CRef< CSeqTextConfig > m_Config
Definition: seq_graph.hpp:112
virtual TModelRect GetModelRect() const
Definition: seq_graph.cpp:399
void x_DrawVariations(TSeqPos seq_start, TSeqPos num_chars_per_row, float scale_x, float scale_y, CSeqTextDefs::TVariationGraphVector &variations)
Definition: seq_graph.cpp:190
CRgbaColor m_TextColor
Definition: seq_graph.hpp:104
ISeqTextGeometry * m_pGeometry
Definition: seq_graph.hpp:114
void x_DrawIntervalBreaks(TModelUnit x, TModelUnit y, CSeqTextDefs::TSeqPosVector &breaks, TSeqPos seq_start, TSeqPos num_chars_per_row)
Definition: seq_graph.cpp:165
TModelUnit m_TextHeight
Definition: seq_graph.hpp:108
CRef< CGlTextureFont > m_pSeqFont
Definition: seq_graph.hpp:101
virtual string GetTooltip()
Definition: seq_graph.cpp:389
CRgbaColor m_SpliceBoxColor
Definition: seq_graph.hpp:106
CRef< CSeqTextDataSource > m_DataSource
Definition: seq_graph.hpp:111
void SetHost(ISequenceTextGraphHost *pHost)
Definition: seq_graph.cpp:79
TModelUnit m_TextOffset
Definition: seq_graph.hpp:109
class ISeqTextGeometry
virtual void STG_GetVisibleRange(TSeqPos &seq_start, TSeqPos &seq_stop)=0
virtual TModelPoint STG_GetModelPointBySourcePos(TSeqPos z)=0
virtual void STG_GetLineInfo(TSeqPos &chars_in_line, TSeqPos &lines_in_pane)=0
class ISequenceTextGraphHost
virtual void STGH_GetMouseOverFeatureSubtypes(CSeqTextDefs::TSubtypeVector &subtypes)=0
virtual void STGH_GetSelectedFeatureSubtypes(CSeqTextDefs::TSubtypeVector &subtypes)=0
static const Colors colors
Definition: cn3d_colors.cpp:50
unsigned int TSeqPos
Type for sequence locations and lengths.
Definition: ncbimisc.hpp:875
#define NULL
Definition: ncbistd.hpp:225
GLdouble TModelUnit
Definition: gltypes.hpp:48
virtual void Begin(GLenum mode)=0
Start rendering.
IRender & GetGl()
convenience function for getting current render manager
void Vertex2d(GLdouble x, GLdouble y)
Definition: irender.hpp:185
void ArrayTextOut(TModelUnit x, TModelUnit y, TModelUnit dx, TModelUnit dy, const char *text, const vector< CRgbaColor * > *colors=NULL, TModelUnit scale_x=1.0f, TModelUnit scale_y=1.0f) const
prints array of characters in positions (x + i*dx, y + i*dy) where "i" is index of a character in the...
bool PtInRect(T x, T y) const
Definition: glrect.hpp:154
virtual void End()=0
Finish rendering (create buffer and send to renderer)
virtual void PolygonMode(GLenum face, GLenum mode)=0
Set the polygon rasterization mode.
virtual TModelUnit GetMetric(EMetric metric, const char *text=NULL, int len=-1) const
virtual void LineWidth(GLfloat w)=0
Set line width for drawing: glLineWidth()
TModelUnit GetScaleX(void) const
Definition: glpane.cpp:118
TModelUnit GetScaleY(void) const
Definition: glpane.cpp:123
virtual void ColorC(const CRgbaColor &c)=0
Set current color (glColor{3,4}{f,d}{v,})
@ eOrtho
Definition: glpane.hpp:66
@ eMetric_FullCharHeight
Definition: glfont.hpp:80
@ eMetric_CharHeight
Definition: glfont.hpp:76
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
USING_SCOPE(objects)
int i
int len
const struct ncbi::grid::netcache::search::fields::SIZE size
The NCBI C++/STL use hints.
T max(T x_, T y_)
T min(T x_, T y_)
static const int kMargin
Definition: seq_graph.cpp:91
static const int kTextOffset
Definition: seq_graph.cpp:92
#define _ASSERT
Modified on Wed May 22 11:28:26 2024 by modify_doxy.py rev. 669887