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

Go to the SVN repository for this file.

1 /*
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: Andrei Shkeda
27 *
28 * File Description:
29 * CTraceGlyph -- utility class for
30 * drawing Trace chromatograms
31 *
32 */
33 
34 #include <ncbi_pch.hpp>
37 #include <gui/objutils/tooltip.hpp>
39 #include <gui/objutils/utils.hpp>
40 #include <gui/opengl/irender.hpp>
41 #include <gui/opengl/glutils.hpp>
45 
46 #include <gui/opengl/glpoint.hpp>
48 
49 
52 
53 #define M_NCBI_E 2.71828182845904523536
54 
55 const static int kGradColors = 32;
56 
57 
58 CRgbaColor s_GradientToWhite(const CRgbaColor& rgb, float degree)
59 {
60  if (degree == 0.)
61  return rgb;
62  _ASSERT(degree >= 0. && degree <= kGradColors);
63  float h, s, v;
64  CRgbaColor::RgbToHsv(rgb, h, s, v);
65  float k_s = s / kGradColors;
66  s -= k_s * degree;
67  float k_v = (1. - v) / kGradColors;
68  v += k_v * degree;
69  return CRgbaColor::HsvToRgb(h, s, v);
70 }
71 
72 //
73 // CTraceGlyph
74 //
76  : m_DlgHost(NULL)
77  , m_Config(config)
78  , m_Data(data)
79  , m_ShowTitle(false)
80 {
81 
82  bool b_ch = m_Data->GetSamplesCount() > 0;
83  m_Config->m_SignalGraphState = b_ch ?
86 }
87 
88 
90 {
91 }
92 
94 {
95  m_vSignalColors.resize(4 * kGradColors);
96  for (int j = 0; j < kGradColors; j++) {
97  float v = kGradColors - j;
98  for (int ch = 0; ch < 4; ++ch) {
100  }
101  }
102 }
103 // vertical spacing between graph area border and graph
104 static const int kGraphOffsetY = 1;
105 
106 static const int kCollapsedGraphH = 11;
107 
108 static const double kConfGraphPrefHR = 0.4;
109 static const double kSignalGraphPrefHR = 0.6;
110 
111 
113 {
114  switch (m_Config->m_ConfGraphState) {
116  return kCollapsedGraphH;
118  return floor(GetHeight() * kConfGraphPrefHR);
120  return 0;
121  }
122  return 0;
123 }
124 
125 
127 {
128  switch (m_Config->m_SignalGraphState) {
130  return kCollapsedGraphH;
132  return floor(GetHeight() * kSignalGraphPrefHR);
134  return 0;
135  }
136  return 0;
137 }
138 
139 
140 
142 {
143  return true;
144 }
145 
146 
147 bool CTraceGlyph::NeedTooltip(const TModelPoint& p, ITooltipFormatter& tt, string& t_title) const
148 {
149  GetTooltip(p, tt, t_title);
150  return true;
151 }
152 
153 void CTraceGlyph::GetTooltip(const TModelPoint& p, ITooltipFormatter& tt, string& /*t_title*/) const
154 {
155  tt.AddRow("DNA Sequencing Chromatograms");
156 }
157 
158 
160 {
161  _ASSERT(p_areas);
162 }
163 
164 
166 {
167  return false;
168 }
169 
170 
172 {
173  IRender& gl = GetGl();
174  CGlPane& pane = *m_Context->GetGlPane();
175 
177 
178  TModelRect m_ModelRect = GetModelRect();
179 
180  //LOG_POST(Info << " Viewport " << m_VPRect.ToString() << "\n Visible " << m_ModelRect.ToString());
181 
182  CGlAttrGuard AttrGuard(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_HINT_BIT
183  | GL_LINE_SMOOTH | GL_POLYGON_MODE | GL_LINE_BIT);
184 
185 
186  int conf_h = x_GetConfGraphH();
187  int sig_h = (conf_h == 0) ? GetHeight() : x_GetSignalGraphH();
188 
189  //int top_y = int(m_ModelRect.Top() - pane.GetOffsetY());
190  int top_y = m_ModelRect.Top();
191 
192  //pane.OpenOrtho();
193 
194  x_RenderContour(pane, top_y, sig_h, conf_h + sig_h); // render background
195 
197  // if (pane.GetScaleX() < 1.0) { // render signal graph
198  if (m_Config->m_SignalStyle == CTraceGraphConfig::eCurve) { // render curves
199  gl.Enable(GL_BLEND);
200  gl.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
201  gl.Enable(GL_LINE_SMOOTH);
202  glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
203  gl.LineWidth(0.5);
204 
205  x_RenderSignalGraph(pane, top_y, sig_h);
206  } else { // render intensity bands
207  TVPRect rcVP = pane.GetViewport();
208  pane.Close();
209  TVPRect flipped_rect(rcVP.Left(), rcVP.Top(), rcVP.Right(), rcVP.Bottom());
210  pane.SetViewport(flipped_rect);
211  pane.OpenPixels();
212 
213  gl.Disable(GL_BLEND);
214  gl.Disable(GL_LINE_SMOOTH);
215  gl.LineWidth(1.0);
216  x_RenderIntensityGraphs(pane, top_y, sig_h);
217 
218  pane.Close();
219  pane.SetViewport(rcVP);
220  pane.OpenOrtho();
221  }
222  // }
223  top_y += sig_h;
224  }
225 
227  // render confidence graph
228  x_RenderConfGraph(pane, top_y, conf_h);
229  }
230  //pane.Close();
231 
232 
233 }
234 
236 {
238  const TModelRange& vr = m_Context->GetVisibleRange();
239  SetLeft(vr.GetFrom());
240  SetWidth(vr.GetLength() - 1.0);
241 }
242 
243 
244 void CTraceGlyph::x_RenderContour(CGlPane& pane, int y, int top_h, int total_h) const
245 {
246  IRender& gl = GetGl();
247 
248  gl.Disable(GL_BLEND);
249  gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
250  gl.Color3d(0.9, 0.9, 0.9);
251 
252  TModelUnit offset_x = pane.GetOffsetX();
253  TModelUnit y1 = y;
254  TModelUnit y2 = y + top_h - 1;
255  TModelUnit y3 = y + top_h + 1;
256  TModelUnit y4 = y + total_h - 1;
258  TModelUnit x1 = r.Left() - offset_x;
259  TModelUnit x2 = r.Right() - offset_x;
260  gl.Rectd(x1, y1, x2, y2);
261  gl.Rectd(x1, y3, x2, y4);
262 
263 }
264 
265 
266 // renders confidence graph
267 void CTraceGlyph::x_RenderConfGraph(CGlPane& pane, int y, int h) const
268 {
269  const TVPRect& rc_vp = pane.GetViewport();
270  const TModelRect rc_vis = pane.GetVisibleRect();
271 
272  IRender& gl = GetGl();
273 
274  gl.Disable(GL_BLEND);
275  gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
276 
277 
278  TModelUnit amp = 0.0;
279  // guard against the situation where confidence data is not available
280  // or fails to load
281  if (m_Data->GetMaxConfidence() != 0.0) {
282  amp = ((TModelUnit)h - 2 * kGraphOffsetY - 1)
284  }
285 
286  TModelUnit base_y = y + kGraphOffsetY;
287  TModelUnit scale_x = abs(pane.GetScaleX());
288 
289  TSignedSeqPos gr_from = m_Data->GetSeqFrom();
290  TSignedSeqPos gr_to = m_Data->GetSeqTo();
291 
292  bool b_average = (scale_x > 0.5);
293  b_average = false; // doesn't work yet
294 
295  if (b_average) {
296  TVPRect rcVP = pane.GetViewport();
297  pane.Close();
298  TVPRect flipped_rect(rcVP.Left(), rc_vis.Bottom(), rcVP.Right(), rc_vis.Top());
299  pane.SetViewport(flipped_rect);
300  pane.OpenPixels();
301  TModelUnit left = floor(rc_vis.Left());
302 
303  //calculate visible range in seq coords
304  TVPUnit range_pix_start = rc_vp.Left();
305  TVPUnit range_pix_end = rc_vp.Right();
306 
307  TModelUnit top_y = rc_vp.Bottom() + (y + kGraphOffsetY);
308 
309  TModelUnit pos_pix_left, pos_pix_right;
310 
311  TSignedSeqPos pos = gr_from, pos_inc = 1;
312  double v = 0, v_min = 0, v_max = 0;
313 
314  TSignedSeqPos vis_from = (TSignedSeqPos)floor(rc_vis.Left());
315  TSignedSeqPos vis_to = (TSignedSeqPos)ceil(rc_vis.Right());
316  if (vis_from > vis_to) {
318  swap(vis_from, vis_to);
319  }
320 
321  // calculate intersection of the segment in seq_coords with graph range
322  TSignedSeqPos from = max<TSignedSeqPos>(vis_from, gr_from);
323  TSignedSeqPos to = min<TSignedSeqPos>(vis_to, gr_to);
324 
325  if (m_Context->IsFlippedStrand()) {
326  left = pos = to;
327  pos_inc = -1;
328  } else {
329  left = pos = from;
330  pos_inc = 1;
331  }
332 
333 
334  gl.Begin(GL_LINES);
335  for (int pix = range_pix_start; pix <= range_pix_end;) { // iterate by pixels
336 
337  if (pos < gr_from || pos > gr_to)
338  break;
339 
340  bool b_first = true;
341  if (m_Context->IsFlippedStrand()) {
342  pos_pix_left = range_pix_start + (left - pos) / scale_x;
343  } else {
344  pos_pix_left = range_pix_start + (pos - left) / scale_x;
345  }
346  pos_pix_right = pos_pix_left + 1 / scale_x;
347 
348  pos_pix_left = max((TModelUnit)pix, pos_pix_left);
349 
350  _ASSERT(pos_pix_left >= pix);
351 
352  while (pos_pix_left < pix + 1) {
353  if (pos < from || pos > to)
354  break;
355  // calculate overlap with pixel and integrate
356  v = amp * m_Data->GetConfidence(pos);
357  if (b_first) {
358  v_min = v_max = v;
359  b_first = false;
360  } else {
361  v_min = min(v_min, v);
362  v_max = max(v_max, v);
363  }
364 
365  if (pos_pix_right >= pix + 1)
366  break;
367  pos += pos_inc; // advance to next pos
368  if (m_Context->IsFlippedStrand()) {
369  pos_pix_left = range_pix_start + (left - pos) / scale_x;
370  } else {
371  pos_pix_left = range_pix_start + (pos - left) / scale_x;
372  }
373  pos_pix_right = pos_pix_left + 1 / scale_x;
374 
375  }
376 
378  gl.Vertex2d(pix, top_y);
379  gl.Vertex2d(pix, top_y + v_min);
380 
382  gl.Vertex2d(pix, top_y + v_min);
383  gl.Vertex2d(pix, top_y + v_max);
384 
385  pix++;
386  v = v_min = v_max = 0;
387  }
388  gl.End();
389 
390  pane.Close();
391  pane.SetViewport(rcVP);
392  pane.OpenOrtho();
393  } else { // render without averaging
395 
396  TModelUnit offset_x = pane.GetOffsetX();
397  gl.ColorC(m_Config->m_colorConfMin); //###
398  TSignedSeqPos from = floor(rc_vis.Left());
399  TSignedSeqPos to = ceil(rc_vis.Right());
400  if (from > to) {
401  swap(from, to);
402  }
403 
404  from = max<TSignedSeqPos>(gr_from, from);
405  to = min<TSignedSeqPos>(gr_to, to);
406 
407  for (TSignedSeqPos pos = from; pos <= to; pos++) {
408  double v = m_Data->GetConfidence(pos);
409  v *= amp;
410  TSignedSeqPos aln_pos = pos;
411  double x = aln_pos - offset_x;
412  gl.Rectd(x, base_y, x + 1.0, base_y + v);
413  }
414  }
415 }
416 
417 void CTraceGlyph::x_RenderSignalGraph(CGlPane& pane, int y, int h) const
418 {
419  IRender& gl = GetGl();
420 
421  CSGTraceData::TSignalValue MaxSignal = 0;
422  for (int ch = CSGTraceData::eA; ch <= CSGTraceData::eG; ch++) {
423  MaxSignal = max(MaxSignal, m_Data->GetMax((CSGTraceData::EChannel) ch));
424  }
425  TModelUnit amp = ((TModelUnit)(h - 2 * kGraphOffsetY)) / MaxSignal;
426  int bottom_y = y + (h - 1) - kGraphOffsetY;
427 
428  for (int i_ch = 0; i_ch < 4; i_ch++) { // for every channel (i_ch - channel index)
429  int ch_index = (m_Config->m_bReverseColors && m_Context->IsFlippedStrand()) ? (i_ch ^ 2) : i_ch;
430  int ch = CSGTraceData::eA + ch_index;
431 
432  const CSGTraceData::TPositions& positions = m_Data->GetPositions();
433 
435  const CSGTraceData::TValues& values = m_Data->GetValues(channel);
436 
437  CRgbaColor c(m_Config->m_colors[ch]);
438  c.SetAlpha(0.5f);
439  gl.ColorC(c);
440  gl.PolygonMode(GL_FRONT_AND_BACK, GL_LINE);
441 
443 
444  x_RenderCurveSegment(pane, positions, values, bottom_y, h, (int) amp);
445 
446  gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
447  }
448 }
449 
450 
451 // Renders chromatogram corresponding to given segment of sequence.
452 // This function renders data as a curve for a single channel specified by "values".
454  const CSGTraceData::TPositions& positions,
455  const CSGTraceData::TValues& values,
456  int bottom_y, int /*h*/, int amp) const
457 {
458  IRender& gl = GetGl();
459 
460  const TModelRect rc_vis = pane.GetVisibleRect();
461 
462  bool b_neg = m_Context->IsFlippedStrand();
463 
464  // [from, to] - is sequence range for which graph is rendered
465  double from = m_Data->GetSeqFrom();
466  double to = m_Data->GetSeqTo();
467 
468  double vis_from = rc_vis.Left();
469  double vis_to = rc_vis.Right();
470  if (vis_to < vis_from) {
471  _ASSERT(b_neg);
472  swap(vis_from, vis_to);
473  }
474 
475  from = max(from, vis_from);
476  to = min(to, vis_to);
477 
478  if (from <= to) {
479  int sm_start = x_FindSampleToLeft(from);
480  int sm_end = x_FindSampleToRight(to + 1);
481  sm_start = max(0, sm_start);
482  sm_end = min(sm_end, m_Data->GetSamplesCount() - 1);
483 
484  if (sm_start <= sm_end) {
485  gl.Begin(GL_TRIANGLE_STRIP);
486  TModelUnit offset_x = pane.GetOffsetX();
487 
488  // check if start interpolation is needed
489  CSGTraceData::TFloatSeqPos sm_start_seqpos = positions[sm_start];
490  if (sm_start_seqpos < from) {
491  if (sm_start + 1 < sm_end) {
492  double v1 = values[sm_start];
493  double v2 = values[sm_start + 1];
494  double x1 = sm_start_seqpos;
495  double x2 = positions[sm_start + 1];
496  double v = v1 + ((from - x1) * (v2 - v1) / (x2 - x1));
497  v *= amp;
498 
499  double aln_from = from + (b_neg ? -1 : 0);
500  gl.Vertex2d(aln_from - offset_x, bottom_y - v);
501  //gl.Vertex2d(aln_from - offset_x, bottom_y);
502  }
503  sm_start++;
504  }
505  // render regular samples
506  for (int i_sm = sm_start; i_sm < sm_end; i_sm++) {
507  TModelUnit seqpos = positions[i_sm];
508  double v = values[i_sm];
509  v *= amp;
510 
511  double aln_pos = seqpos + (b_neg ? -1 : 0);
512  gl.Vertex2d(aln_pos - offset_x, bottom_y - v);
513  //gl.Vertex2d(aln_pos - offset_x, bottom_y);
514  }
515  // render end point
516  if (sm_end - 1 > sm_start) { // interpolate end point
517  double v1 = values[sm_end - 1];
518  double v2 = values[sm_end];
519  double x1 = positions[sm_end - 1];
520  double x2 = positions[sm_end];
521  double v = v1 + ((to + 1 - x1) * (v2 - v1) / (x2 - x1));
522  v *= amp;
523 
524  double aln_to = to + (b_neg ? 0 : 1);
525  gl.Vertex2d(aln_to - offset_x, bottom_y - v);
526  //gl.Vertex2d(aln_to - offset_x, bottom_y);
527  } else {
528  TModelUnit seqpos = positions[sm_end];
529  double v = values[sm_end];
530  v *= amp;
531 
532  double aln_pos = seqpos;
533  gl.Vertex2d(aln_pos - offset_x, bottom_y - v);
534  //gl.Vertex2d(aln_pos - offset_x, bottom_y);
535  }
536  gl.End();
537  }
538  }
539 }
540 
541 
542 /// Render signals for all channels as gradient-color bands with color intensity
543 /// proprotional to signal strength.
544 void CTraceGlyph::x_RenderIntensityGraphs(CGlPane& pane, int y, int h) const
545 {
546  IRender& gl = GetGl();
547 
548  //_TRACE("\nx_RenderIntensityGraphs");
549  const CSGTraceData::TPositions& positions = m_Data->GetPositions();
550 
551  const TVPRect& rc_vp = pane.GetViewport();
552  const TModelRect rc_vis = pane.GetVisibleRect();
553 
554  // calculate layout
555  int av_h = h - 2 * kGraphOffsetY; // height available for intensity bands
556  int band_h = av_h / 4;
557  int off = (av_h - 4 * band_h) / 2; // rounding error compensation
558  int top_y = rc_vp.Bottom() + (y + kGraphOffsetY + off);
559 
560  TModelUnit left = rc_vis.Left();
561  TModelUnit scale_x = abs(pane.GetScaleX());
562 
563  TVPUnit range_pix_start = rc_vp.Left();
564  TVPUnit range_pix_end = rc_vp.Right();
565 
566  gl.Begin(GL_LINES);
567 
568  // calculate samples range by segment
569 
570  double vis_from = rc_vis.Left();
571  double vis_to = rc_vis.Right();
572  if (vis_to < vis_from) {
574  swap(vis_from, vis_to);
575  }
576 
577  // [from, to] - is sequence range for which graph is rendered
578  double from = max<TVPUnit>(m_Data->GetSeqFrom(), floor(vis_from));
579  double to = min<TVPUnit>(m_Data->GetSeqTo(), ceil(vis_to));
580 
581  // [sm_start, sm_end] - samples range being rendered
582  int sm_start = x_FindSampleToLeft(from);
583  int sm_end = x_FindSampleToRight(to + 1);
584  sm_start = max(sm_start, 0);
585  sm_end = min(sm_end, m_Data->GetSamplesCount() - 1);
586 
587  // calculate pixels range to render
588  double aln_from = from;
589  double aln_to = to;
590  aln_to += 1;
591 
592 
593  TVPUnit pix_start = range_pix_start + (aln_from - floor(vis_from)) / scale_x;;
594  TVPUnit pix_end = range_pix_start + (TVPUnit)ceil((aln_to - floor(vis_from)) / scale_x);
595 
596  pix_start = max(pix_start, range_pix_start);
597  pix_end = min(pix_end, range_pix_end);
598 
599  int sm_inc = m_Context->IsFlippedStrand() ? -1 : +1;
600 
601  int band_y = top_y;
602  for (int i_ch = 0; i_ch < 4; i_ch++) { // for every channel (i_ch - channel index)
603  int ch_index = (m_Config->m_bReverseColors &&
604  m_Context->IsFlippedStrand()) ? (i_ch ^ 2) : i_ch;
605  int ch = CSGTraceData::eA + ch_index;
606 
609 
610  double x1 = 0.0, x2 = 0.0, pix_x1 = 0.0, pix_x2 = 0.0;
611  double v1, v2, s, dx, sum, sum_pix_x;
612 
613  int sample = m_Context->IsFlippedStrand() ? sm_end : sm_start;
614  _ASSERT(sample >= 0);
615 
616  for (TVPUnit pix = pix_start; pix <= pix_end; pix++) { // for each pixel
617  // calculate average value for "pix" pixel by integrating values
618  // over the range [pix, pix+1]
619  sum = 0; // integral from values by pix_x
620  sum_pix_x = 0; // length of integrated range
621 
622  x1 = positions[sample];
623  pix_x1 = range_pix_start;
624  TModelUnit dist = m_Context->IsFlippedStrand() ? left - x1 : x1 - left;
625  if (dist > 0)
626  pix_x1 += dist / scale_x;
627 
628  v1 = v2 = values[sample]; //#####
629 
630  if (pix_x1 < pix + 1) {
631 
632  bool b_next_point = m_Context->IsFlippedStrand() ? (sample > sm_start) : (sample < sm_end);
633  if (b_next_point) { // there is second point available
634  x2 = positions[sample + sm_inc];
635  pix_x2 = range_pix_start;
636  TModelUnit dist = m_Context->IsFlippedStrand() ? left - x2 : x2 - left;
637  if (dist > 0)
638  pix_x2 += dist / scale_x;
639 
640  v2 = values[sample + sm_inc];
641 
642  if (pix_x1 < pix) { // fisrt sample is to the left of this pixel
643  // replace it fake interpolated sample at x = "pix"
644  v1 += (v2 - v1) * (pix - pix_x1) / (pix_x2 - pix_x1);
645  pix_x1 = pix;
646  }
647  }
648 
649  while (b_next_point && pix_x2 <= pix + 1) // while second point is inside pixel
650  {
651  dx = pix_x2 - pix_x1;
652  s = 0.5 * (v1 + v2) * dx;
653  _ASSERT(s >= 0 && dx >= 0);
654 
655  sum += s;
656  sum_pix_x += dx;
657 
658  sample += sm_inc; // advance, x2 becomes x1
659  pix_x1 = pix_x2;
660  v1 = v2;
661 
662  b_next_point = m_Context->IsFlippedStrand() ? (sample > sm_start) : (sample < sm_end);
663  if (!b_next_point)
664  break;
665  x2 = positions[sample + sm_inc];
666  pix_x2 = range_pix_start;
667  TModelUnit dist = m_Context->IsFlippedStrand() ? left - x2 : x2 - left;
668  if (dist > 0)
669  pix_x2 += dist / scale_x;
670  v2 = values[sample + sm_inc];
671  }
672  _ASSERT(pix_x1 <= pix + 1);
673 
674  if (b_next_point && pix_x2 > pix + 1) { // second point is outside pixel
675  dx = pix + 1 - pix_x1;
676  _ASSERT(dx >= 0);
677 
678  double v = v1 + (v2 - v1) * dx / (pix_x2 - pix_x1);
679  s = 0.5 * (v1 + v) * dx;
680 
681  _ASSERT(s >= 0 && dx >= 0);
682 
683  sum += s;
684  sum_pix_x += dx;
685  }
686  double av_v = (sum_pix_x) > 0 ? sum / sum_pix_x : 0;
687 
688  // render pixel
689  double norm = (MaxSignal == 0) ? 0 : (av_v / MaxSignal);
690  const CRgbaColor& col = GetColorByValue(norm, i_ch);
691  gl.ColorC(col);
692  gl.Vertex2d(pix, band_y);
693  gl.Vertex2d(pix, band_y + band_h - 1);
694  } // if(pix < pix + 1)
695  }
696  band_y += band_h;
697  }
698  gl.End();
699 }
700 
701 
702 // returns gradient color corresponding to normalized [0, 1.0] value "value"
703 // for channel specified by "signal"
704 const CRgbaColor& CTraceGlyph::GetColorByValue(double value, int signal) const
705 {
706  _ASSERT(value >= 0 && value <= 1.0);
707  _ASSERT(signal >= 0 && signal <= 3);
708 
709  int i = (int)(value * kGradColors);
710  i = min(i, kGradColors);
711  int index = signal * kGradColors + i;
712  if (m_vSignalColors.empty())
713  x_InitColors();
714  _ASSERT(index < m_vSignalColors.size());
715  return m_vSignalColors[index];
716 }
717 
718 /// returns index of rightmost sample having m_SeqPos less then "pos".
719 /// if "pos" is to the left of the trace range function returns -1,
720 /// if "pos" is to the right of the trace range functions returns "n_samples"
721 int CTraceGlyph::x_FindSampleToLeft(double pos) const
722 {
723  int n_samples = m_Data->GetSamplesCount();
724  if (pos < m_Data->GetSeqFrom() || n_samples == 0) {
725  return -1;
726  } else if (pos > m_Data->GetSeqTo()) {
727  return n_samples;
728  } else {
729  const CSGTraceData::TPositions& positions = m_Data->GetPositions();
730  double scale = ((double)n_samples) / m_Data->GetSeqLength();
731 
732  // calculate approximate sample index
733  int i = (int)(scale * (pos - m_Data->GetSeqFrom()));
734  i = min(i, n_samples - 1);
735  i = max(i, 0);
736 
737  if (positions[i] > pos) {
738  for (; i > 0 && positions[i] > pos; i--) {
739  }
740  } else {
741  for (; ++i < n_samples && positions[i] < pos;) {
742  }
743  i--;
744  }
745  return i;
746  }
747 }
748 
749 
750 /// returns index of the leftmost sample having m_SeqPos greater than "pos"
751 /// if "pos" is to the left of the trace range function returns -1,
752 /// if "pos" is to the right of the trace range functions returns "n_samples"
753 int CTraceGlyph::x_FindSampleToRight(double pos) const
754 {
755  int n_samples = m_Data->GetSamplesCount();
756  if (pos < m_Data->GetSeqFrom() || n_samples == 0) {
757  return -1;
758  } else if (pos > m_Data->GetSeqTo()) {
759  return n_samples;
760  } else {
761  const CSGTraceData::TPositions& positions = m_Data->GetPositions();
762  double scale = ((double)n_samples) / m_Data->GetSeqLength();
763 
764  // calculate approximate sample index
765  int i = (int)(scale * (pos - m_Data->GetSeqFrom()));
766  i = min(i, n_samples - 1);
767  i = max(i, 0);
768 
769  if (positions[i] > pos) {
770  for (; i > 0 && positions[i] > pos; i--) {
771  }
772  i++;
773  } else {
774  for (; ++i < n_samples && positions[i] < pos;) {
775  }
776  }
777  return i;
778  }
779 }
780 
781 
782 
783 
CGlAttrGuard - guard class for restoring OpenGL attributes.
Definition: glutils.hpp:130
class CGlPane
Definition: glpane.hpp:62
CGlPane * GetGlPane()
inline method implementations
const TModelRange & GetVisibleRange() const
bool IsFlippedStrand() const
class CRgbaColor provides a simple abstraction for managing colors.
Definition: rgba_color.hpp:58
TValues & GetValues(EChannel signal)
int GetSamplesCount() const
vector< TSignalValue > TValues
vector< TFloatSeqPos > TPositions
TConfidence GetMaxConfidence() const
TSignedSeqPos GetSeqTo() const
TSignedSeqPos GetSeqFrom() const
Sequence related information.
TPositions & GetPositions()
TSignalValue GetMax(EChannel signal) const
TConfidence GetConfidence(TSignedSeqPos pos) const
TSignedSeqPos GetSeqLength() const
CRenderingContext * m_Context
the rendering context
Definition: seq_glyph.hpp:346
virtual void SetHeight(TModelUnit h)
Definition: seq_glyph.hpp:650
virtual void SetWidth(TModelUnit w)
Definition: seq_glyph.hpp:646
virtual void SetLeft(TModelUnit l)
Definition: seq_glyph.hpp:654
virtual TModelUnit GetHeight() const
Definition: seq_glyph.hpp:587
TModelRect GetModelRect() const
get the bounding box.
Definition: seq_glyph.hpp:562
vector< CHTMLActiveArea > TAreaVector
Definition: seq_glyph.hpp:84
int x_GetConfGraphH() const
virtual bool OnLeftDblClick(const TModelPoint &)
vector< CRgbaColor > m_vSignalColors
void x_RenderConfGraph(CGlPane &pane, int y, int h) const
void x_RenderSignalGraph(CGlPane &pane, int y, int h) const
int x_FindSampleToLeft(double pos) const
returns index of rightmost sample having m_SeqPos less then "pos".
CTraceGlyph(const CRef< CSGTraceData > &data, const CRef< CTraceGraphConfig > &config)
Definition: trace_glyph.cpp:75
virtual bool IsClickable() const
Query if this glyph is clickable.
CRef< CTraceGraphConfig > m_Config
void x_InitColors() const
Definition: trace_glyph.cpp:93
virtual void GetTooltip(const TModelPoint &, ITooltipFormatter &tt, string &t_title) const
Get the tooltip if available.
virtual void GetHTMLActiveAreas(TAreaVector *p_areas) const
Get html active areas.
CRef< CSGTraceData > m_Data
void x_RenderCurveSegment(CGlPane &pane, const CSGTraceData::TPositions &positions, const CSGTraceData::TValues &values, int bottom_y, int, int amp) const
const CRgbaColor & GetColorByValue(double value, int signal) const
void x_RenderIntensityGraphs(CGlPane &pane, int y, int h) const
Render signals for all channels as gradient-color bands with color intensity proprotional to signal s...
int x_FindSampleToRight(double pos) const
returns index of the leftmost sample having m_SeqPos greater than "pos" if "pos" is to the left of th...
void x_RenderContour(CGlPane &pane, int y, int top_h, int total_h) const
virtual void x_Draw() const
The default renderer for this layout object.
virtual bool NeedTooltip(const TModelPoint &p, ITooltipFormatter &tt, string &t_title) const
Check if need to show tooltip.
int x_GetSignalGraphH() const
virtual void x_UpdateBoundingBox()
Update the bounding box assuming children's sizes are fixed if any.
ESingnalStyle m_SignalStyle
Definition: trace_glyph.hpp:80
CRgbaColor m_colorConfMax
Definition: trace_glyph.hpp:89
EGraphState m_ConfGraphState
Definition: trace_glyph.hpp:82
EGraphState m_SignalGraphState
Definition: trace_glyph.hpp:83
array< CRgbaColor, 4 > m_colors
Definition: trace_glyph.hpp:87
CRgbaColor m_colorConfMin
Definition: trace_glyph.hpp:88
primitive interface to arrange tabular data in the tooltips
Definition: tooltip.hpp:55
#define false
Definition: bool.h:36
char data[12]
Definition: iconv.c:80
int TSignedSeqPos
Type for signed sequence position.
Definition: ncbimisc.hpp:887
void swap(NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair1, NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair2)
Definition: ncbimisc.hpp:1508
#define NULL
Definition: ncbistd.hpp:225
const CVect2< U > & v2
Definition: globals.hpp:440
GLdouble TModelUnit
Definition: gltypes.hpp:48
void SetViewport(const TVPRect &R)
Definition: glpane.cpp:96
virtual void Enable(GLenum glstate)=0
bool OpenOrtho()
Definition: glpane.hpp:427
virtual void Begin(GLenum mode)=0
Start rendering.
T Top() const
Definition: glrect.hpp:84
virtual void BlendFunc(GLenum sfactor, GLenum dfactor)=0
Options to be used when GL_BLEND is enabled.
T Bottom() const
Definition: glrect.hpp:82
bool OpenPixels()
Definition: glpane.hpp:432
void Color3d(GLdouble r, GLdouble g, GLdouble b)
Definition: irender.hpp:100
IRender & GetGl()
convenience function for getting current render manager
void Vertex2d(GLdouble x, GLdouble y)
Definition: irender.hpp:185
T Right() const
Definition: glrect.hpp:83
TVPRect & GetViewport(void)
Definition: glpane.hpp:332
T Left() const
Definition: glrect.hpp:81
virtual void End()=0
Finish rendering (create buffer and send to renderer)
void Close(void)
Definition: glpane.cpp:178
virtual void PolygonMode(GLenum face, GLenum mode)=0
Set the polygon rasterization mode.
int TVPUnit
Definition: gltypes.hpp:47
EProjectionMode GetProjMode(void) const
Definition: glpane.hpp:437
TModelRect & GetVisibleRect(void)
Definition: glpane.hpp:357
virtual void Disable(GLenum glstate)=0
glDisable()
virtual void LineWidth(GLfloat w)=0
Set line width for drawing: glLineWidth()
TModelUnit GetScaleX(void) const
Definition: glpane.cpp:118
TModelUnit GetOffsetX() const
Definition: glpane.hpp:410
virtual void ColorC(const CRgbaColor &c)=0
Set current color (glColor{3,4}{f,d}{v,})
void Rectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)
Definition: irender.hpp:193
@ eOrtho
Definition: glpane.hpp:66
virtual void AddRow(const string &sContents="", unsigned colspan=2)=0
add a row with a cell, spanning across all columns
void SetAlpha(float r)
Definition: rgba_color.cpp:287
static void RgbToHsv(const CRgbaColor &rgb, float &h, float &s, float &v)
convert RGB to HSV.
static CRgbaColor HsvToRgb(float h, float s, float v)
position_type GetLength(void) const
Definition: range.hpp:158
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
TFrom GetFrom(void) const
Get the From member data.
Definition: Range_.hpp:222
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
int i
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1227
#define abs(a)
Definition: ncbi_heapmgr.c:130
T max(T x_, T y_)
T min(T x_, T y_)
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
#define _ASSERT
USING_SCOPE(objects)
static const double kSignalGraphPrefHR
CRgbaColor s_GradientToWhite(const CRgbaColor &rgb, float degree)
Definition: trace_glyph.cpp:58
static const int kGradColors
Definition: trace_glyph.cpp:55
static const double kConfGraphPrefHR
static const int kGraphOffsetY
static const int kCollapsedGraphH
Modified on Sat May 18 11:41:46 2024 by modify_doxy.py rev. 669887