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

Go to the SVN repository for this file.

1 /* $Id: alignment_glyph.cpp 47780 2024-08-19 02:13:10Z asztalos $
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: Vlad Lebedev, Liangshou Wu
27  *
28  * File Description:
29  * CAlignGlyph -- utility class to layout alignments
30  */
31 
32 #include <ncbi_pch.hpp>
33 #include <corelib/ncbistd.hpp>
34 #include <objmgr/util/sequence.hpp>
36 #include <objects/seq/MolInfo.hpp>
42 
48 #include <gui/objutils/tooltip.hpp>
49 #include <gui/objutils/utils.hpp>
50 
51 #include <gui/opengl/irender.hpp>
52 #include <gui/opengl/glutils.hpp>
56 
58 
60 #include <math.h>
61 
64 
65 
66 // How closely pack align. sequence when showing DNA alignments for proteins
67 // (pack 3 alignment bases into 1 sequence base)
68 static const TModelUnit kPWAlignPackLevel = 0.333;
69 static const TSeqPos kTailGlyphLen = 12;
70 static const TSeqPos kCompactTailGlyphLen = 2;
71 
72 static const int kAlignRowSpace = 3;
73 static const int kLabelSpace_v = 2;
74 
75 static const int kLabelSpace_h = 5;
76 static const int kCompactLabelSpace_h = 1;
77 
79  const CSeq_align_Handle& orig_align,
80  const CSeq_align& mapped_align,
81  int orig_anchor)
82  : m_AlnMgr(aln_mgr)
83  , m_SeqAlign(&mapped_align)
84  , m_OrigSeqAlign(orig_align)
85  , m_OrigAnchor(orig_anchor)
86  , m_ShowScore(false)
87  , m_DisableTooltipsCaching(false)
88  , m_FadeFactor(1.0f)
89 {
91  TSeqPos base_width_anchor = m_AlnMgr->GetBaseWidth(anchor);
92 
93  TSignedSeqPos start = m_AlnMgr->GetSeqStart(anchor) / base_width_anchor;
94  TSignedSeqPos stop = m_AlnMgr->GetSeqStop (anchor) / base_width_anchor;
95 
96  m_Location.Reset(new CSeq_loc());
97  m_Location->SetInt().SetFrom(start);
98  m_Location->SetInt().SetTo (stop);
99  if (x_IsPWAlign()) {
101  m_Location->SetStrand(eNa_strand_plus);
102  } else {
103  m_Location->SetStrand(eNa_strand_minus);
104  }
105  }
106 
107  CConstRef<CSeq_id> id(&m_AlnMgr->GetSeqId(anchor));
108  m_Location->SetId(*id);
109 }
110 
111 
112 bool CAlignGlyph::NeedTooltip(const TModelPoint& /*p*/, ITooltipFormatter& /*tt*/, string& /*t_title*/) const
113 {
114  return true;
115 }
116 
117 
118 void CAlignGlyph::GetTooltip(const TModelPoint& p, ITooltipFormatter& tt, string& t_title) const
119 {
120  if (!GetVisible())
121  return;
122  CScope& scope = m_Context->GetScope();
123  SConstScopedObject scoped_obj(&GetAlignment(), &scope);
124  CIRef<IGuiObjectInfo> gui_info(
125  CreateObjectInterface<IGuiObjectInfo>(scoped_obj, NULL));
126 
127  if ( !gui_info ) return;
128 
129  CGuiObjectInfoSeq_align* gui_info_aln =
130  dynamic_cast<CGuiObjectInfoSeq_align*>(gui_info.GetPointer());
131  if (gui_info_aln) {
132  gui_info_aln->SetAnchorRow(m_OrigAnchor);
133  gui_info_aln->SetFlippedStrands(m_Context->IsFlippedStrand());
134  gui_info_aln->SetScale(m_Context->GetScale());
135  gui_info_aln->SetDataSource(m_AlnMgr);
136  }
137 
138  TSeqPos at_p = (TSeqPos)-1;
139  if (p.X() >= 0) {
140  at_p = (TSeqPos)p.X();
141  }
142 
143  gui_info->GetToolTip(tt, t_title, at_p);
144  gui_info->GetLinks(tt, false);
145 
146  if (IsLastRow()) {
147  tt.AddRow("");
148  tt.AddRow("Last displayed alignment");
149  tt.AddRow("Alignment rows truncated for 'Adaptive' display");
150  tt.AddRow("To see all alignments select 'Show All'");
151  }
152 }
153 
154 
156 {
157  if (!GetVisible())
158  return;
159  CHTMLActiveArea area;
161  if (m_AlnMgr->GetNumRows() == 2) {
162  area.m_PositiveStrand =
164  }
165  area.m_Signature = GetSignature();
168  p_areas->push_back(area);
169 }
170 
171 
173 {
174  if (m_Intervals.size() == 1) {
175  return m_Intervals.front();
176  }
177 
178  return m_Location->GetTotalRange();
179 }
180 
181 
183 {
184  return true;
185 }
186 
187 
189 {
190  return CConstRef<CObject>(m_OrigSeqAlign.GetSeq_align());
191 }
192 
193 
194 void CAlignGlyph::GetObjects(vector<CConstRef<CObject> >& objs) const
195 {
196  objs.emplace_back(m_OrigSeqAlign.GetSeq_align());
197 }
198 
199 
201 {
202  return m_OrigSeqAlign.GetSeq_align() == obj.GetPointer();
203 }
204 
205 
206 const objects::CSeq_loc& CAlignGlyph::GetLocation(void) const
207 {
208  return *m_Location;
209 }
210 
211 
213 {
214  if (x_IsSRA()) {
215  int aligned_seq = m_AlnMgr->GetAnchor() == 0 ? 1 : 0;
216  CSeq_loc csra_loc;
217  csra_loc.Assign(*m_Location);
218  csra_loc.SetId(m_AlnMgr->GetSeqId(aligned_seq));
220  GetOrigAlignment().GetSeq_align().GetObject(),
221  csra_loc, &m_Context->GetScope(), m_OrigSeqAlign.GetAnnot());
222  }
223  else {
225  GetOrigAlignment().GetSeq_align().GetObject(),
226  GetLocation(), &m_Context->GetScope(), m_OrigSeqAlign.GetAnnot());
227  }
228 }
229 
230 
232 {
233  return m_Intervals;
234 }
235 
236 
237 inline double CompressLength(double len)
238 {
239  if(len <= 10.0) {
240  return len;
241  } else {
242  double log = log10(len) * 10;
243  return log;
244  }
245 }
246 
247 
249 {
250  if (ctx.seq_range.Empty())
251  return;
252 
253  IRender& gl = GetGl();
254  int anchor = m_AlnMgr->GetAnchor();
255  int row_num = m_AlnMgr->GetNumRows();
256 
257  // color the gap differently
258  //CGlAttrGuard AttrGuard(GL_LINE_BIT);
259  gl.Disable(GL_LINE_SMOOTH);
260 
261  const TModelUnit y_center = ctx.yy + ctx.half;
262  CRgbaColor gap_color_min(0.78f, 0.5f, 0.5f, m_FadeFactor);
263  CRgbaColor gap_color_max(0.6f, 0.0f, 0.0f, m_FadeFactor);
264 
265  for (int row = 0; row < row_num; ++row) {
266  if (row == anchor) {
267  continue; // skip master seq
268  }
269  unique_ptr<IAlnSegmentIterator> p_it(
272 
273  for (IAlnSegmentIterator& it = *p_it; it; ++it) {
274  const IAlnSegment& seg = *it;
275  if ( !(seg.GetType() & IAlnSegment::fIndel) ||
276  !seg.GetRange().Empty() ) {
277  continue;
278  }
279 
280  const IAlnSegment::TSignedRange& curr_aln_r = seg.GetAlnRange();
281  TModelUnit curr_seq_from =
282  m_AlnMgr->GetSeqPosFromAlnPos(anchor, curr_aln_r.GetFrom()) /
283  ctx.base_width_anchor;
284  TModelUnit curr_seq_to =
285  m_AlnMgr->GetSeqPosFromAlnPos(anchor, curr_aln_r.GetTo()) /
286  ctx.base_width_anchor;
287  if (curr_seq_from > curr_seq_to) {
288  swap (curr_seq_from, curr_seq_to);
289  }
290  curr_seq_to += 1.0 / ctx.base_width_anchor;
291  TModelUnit gap_size = m_Context->SeqToScreen(curr_seq_to - curr_seq_from);
292  if (gap_size > 1.5) {
293  gl.LineWidth(2.0);
296  if ((nullptr != cigar) && (IAlnGraphicDataSource::eCigar_N == (*cigar).first)) {
298  }
299  m_Context->DrawLine(curr_seq_from, y_center, curr_seq_to, y_center);
300  } else {
301  /*
302  if (gap_size > 1.0) {
303  gap_size = 1.0;
304  } else if (gap_size < 0.1) {
305  gap_size = 0.1;
306  }
307  if (gap_size > 1.0) {
308  CRgbaColor gap_color_ins(CRgbaColor::Interpolate(gap_color_max,
309  gap_color_min, gap_size));
310  gl.ColorC(gap_color_ins);
311  gl.LineWidth(1.0);
312  TModelUnit c_x = (curr_seq_from + curr_seq_to) * 0.5;
313  m_Context->DrawLine_NoAA(c_x, ctx.yy, c_x, ctx.yy + ctx.bar_h);
314  }
315  */
316  }
317  }
318  }
319  gl.LineWidth(1.0f);
320 }
321 
323 {
324  if (ctx.seq_range.Empty())
325  return;
326 
327  IRender& gl = GetGl();
328  TModelUnit over = 2.0;
329  TModelUnit down = 3.0;
330  const TModelUnit y1 = ctx.yy + down;
331  const TModelUnit y2 = ctx.yy + ctx.bar_h - down;
332 
334  CRgbaColor color_min = color_max;
335  color_min.Lighten(0.6f);
336  int anchor = m_AlnMgr->GetAnchor();
337  int row_num = m_AlnMgr->GetNumRows();
338  CGlAttrGuard AttrGuard(GL_LINE_BIT);
339  gl.Disable(GL_LINE_SMOOTH);
340 
341  for (int row = 0; row < row_num; ++row) {
342  if (row == anchor) {
343  continue; // skip master seq
344  }
345  unique_ptr<IAlnSegmentIterator> p_it(
348 
349  int last_aligned_seg_to_anchor = -2;
350  int last_aligned_seg_to_curr = -2;
351  int last_aligned_seg_from_anchor = -2;
352  int last_aligned_seg_from_curr = -2;
353 
354  int last_large_ins = -100000; // >= 5 bases
355 
356  int seg_iter_dir = 0; // 0: unknown, 1: forward (anchor), -1: reverse (anchor)
357  for (IAlnSegmentIterator& it = *p_it; it; ++it) {
358  const IAlnSegment& seg = *it;
359  TSeqPos start = 0;
360  int ins_len = 0;
361  if ( !(seg.GetType() & IAlnSegment::fIndel) ||
362  seg.GetRange().Empty() ) {
363  // it is not marked as insertion
364  // check if it is intron
365  if (seg.GetType() & IAlnSegment::fAligned) {
366  if (seg_iter_dir == 0) {
367  int anchor_to =
369  int anchor_from =
371  if (last_aligned_seg_to_anchor < 0) {
372  // It must be the first segment (unknow iterator direction)
373  last_aligned_seg_to_anchor = anchor_to;
374  last_aligned_seg_from_anchor = anchor_from;
375  last_aligned_seg_to_curr = seg.GetRange().GetTo();
376  last_aligned_seg_from_curr = seg.GetRange().GetFrom();
377  } else {
378  if (anchor_to < last_aligned_seg_to_anchor || anchor_from < last_aligned_seg_to_anchor) {
379  seg_iter_dir = -1;
380  } else {
381  seg_iter_dir = 1;
382  }
383  }
384  }
385 
386  if (seg_iter_dir == -1) {
387  TSeqPos t_pos = m_AlnMgr->GetSeqPosFromAlnPos(anchor,
389  if ((int)t_pos == last_aligned_seg_from_anchor - 1) {
390  start = t_pos / ctx.base_width_anchor;
391  if (ctx.reverse_strand) {
392  ins_len = seg.GetRange().GetFrom() - last_aligned_seg_to_curr;
393  } else {
394  ins_len = last_aligned_seg_from_curr - seg.GetRange().GetTo();
395  }
396  ins_len -= 1;
397  }
398  last_aligned_seg_to_anchor = t_pos;
399  last_aligned_seg_from_anchor = m_AlnMgr->GetSeqPosFromAlnPos(anchor,
401  } else if (seg_iter_dir == 1) {
402  TSeqPos f_pos = m_AlnMgr->GetSeqPosFromAlnPos(anchor,
404  if ((int)f_pos == last_aligned_seg_to_anchor + 1) {
405  start = f_pos / ctx.base_width_anchor;
406  if (ctx.reverse_strand) {
407  ins_len = last_aligned_seg_from_curr - seg.GetRange().GetTo();
408  } else {
409  ins_len = seg.GetRange().GetFrom() - last_aligned_seg_to_curr;
410  }
411  ins_len -= 1;
412  }
413  last_aligned_seg_from_anchor = f_pos;
414  last_aligned_seg_to_anchor = m_AlnMgr->GetSeqPosFromAlnPos(anchor,
416  }
417  last_aligned_seg_from_curr = seg.GetRange().GetFrom();
418  last_aligned_seg_to_curr = seg.GetRange().GetTo();
419  }
420  } else {
421  // The left/right/backward/forward flag works very strangely.
422  // We need to hack it by looking at the strand flag.
423  start = m_AlnMgr->GetSeqPosFromAlnPos(anchor,
424  seg.GetAlnRange().GetFrom(),
426 
427  start /= ctx.base_width_anchor;
428  ins_len = seg.GetRange().GetLength();
429  // reset to avoid drawing insertion twice
430  last_aligned_seg_to_anchor = -2;
431  last_aligned_seg_from_anchor = -2;
432  }
433  if (ins_len <= 0) continue;
434 
436 
437  TModelUnit ins_len_pix = m_Context->SeqToScreen(ins_len);
438  // adjust it to the anchor sequence base length
439  ins_len_pix /= ctx.base_width_anchor;
440 
441  if (ins_len < 5) {
442  if (((int)start - last_large_ins) < m_Context->ScreenToSeq(1.0)) {
443  // skip the minor ones that overlap with the last major one
444  continue;
445  }
446  } else if (ins_len_pix > 2.0) {
447  // store the last major insert ( > 5 bases) location
448  last_large_ins = (int)start;
449  }
450  if (ins_len_pix < 0.1f)
451  continue;
452 
453  if (ins_len_pix > 1.5 && m_Config->m_CompactMode == CAlignmentConfig::eNormal) {
454  TModelUnit scale = min(10.0 * ins_len/ m_Context->GetScale(), 1.0);
455  CRgbaColor color_ins(CRgbaColor::Interpolate(color_max, color_min, scale));
456  gl.ColorC(color_ins);
457  m_Context->DrawLine(start, ctx.yy, start, ctx.yy + ctx.bar_h);
458  TModelUnit size_in_model
459  = min(m_Context->ScreenToSeq(4), (TModelUnit)ins_len);
460  m_Context->DrawTriangle(start, y1,
461  start + size_in_model, ctx.yy - over,
462  start - size_in_model, ctx.yy - over);
463  m_Context->DrawTriangle(start, y2,
464  start - size_in_model, ctx.yy + ctx.bar_h + over,
465  start + size_in_model, ctx.yy + ctx.bar_h + over);
466  TModelUnit len = max(CompressLength(ins_len), size_in_model * 2.0);
467  TModelUnit x1 = start - len * 0.5;
468  TModelUnit x2 = x1 + len;
469  m_Context->DrawLine(x1, ctx.yy - over, x2, ctx.yy - over);
470  m_Context->DrawLine(x1, ctx.yy + ctx.bar_h + over, x2, ctx.yy + ctx.bar_h + over);
471  }
472  }
473  }
474 }
475 
477 {
478 
479  TMUnitRanges unaligned_regions;
480  x_DrawInternalUnalignedRegions(ctx, unaligned_regions);
481  sort(unaligned_regions.begin(), unaligned_regions.end(),
482  [](TModelRange const& a, TModelRange const& b) -> bool
483  {
484  return a.GetFrom() < b.GetFrom();
485  });
486  TModelUnit y = ctx.yy + ctx.half;
487  double barh = abs(m_Context->GetGlPane()->GetScaleY() * ctx.bar_h);
488  // if bar height i sless than 2pix
489  // set y to top so that the following alignment bar covers it
490  // (blue band issue)
491  if (barh < 2.)
492  y = ctx.yy;
493  if (unaligned_regions.empty()) {
494  m_Context->DrawLine_NoAA(from, y, to, y);
495  } else {
496  TModelUnit ln_start = from;
497  for (const auto& unaligned_rng : unaligned_regions) {
498  m_Context->DrawLine_NoAA(ln_start, y, unaligned_rng.GetFrom() - 1, y);
499  ln_start = unaligned_rng.GetToOpen();
500  }
501  m_Context->DrawLine_NoAA(ln_start, y, to, y);
502  }
503 }
504 
506 {
507  if (ctx.seq_range.Empty())
508  return;
509 
510  TModelUnit seg_width(m_Context->GetGlPane()->GetViewport().Width());
511  if (m_Context->GetViewWidth() && (m_Context->GetViewWidth() != seg_width))
512  seg_width /= 5.0;
513  seg_width = m_Context->ScreenToSeq(seg_width);
514 
515  IRender& gl = GetGl();
516  // Don't draw the labels, if they are taller than the bar
517  const CGlTextureFont& l_font = m_Config->m_LabelFont;
518  TModelUnit h_text = gl.TextHeight(&l_font);
519 
520  int anchor = m_AlnMgr->GetAnchor();
521  int row_num = m_AlnMgr->GetNumRows();
522 
524 
525  TSignedSeqRange aln_range = ctx.aln_range;
526  if (aln_range.GetFrom() > 0) {
527  aln_range.SetFrom(aln_range.GetFrom() - 1);
528  }
529 
530  for (int row = 0; row < row_num; ++row) {
531  if (row == anchor) {
532  continue; // skip master seq
533  }
534 
535  unique_ptr<IAlnSegmentIterator> p_it(
538 
539  for (IAlnSegmentIterator& it = *p_it; it; ++it) {
540  const IAlnSegment& seg = *it;
541 
542  if (!(seg.GetType() & IAlnSegment::fUnaligned)) {
543  continue;
544  }
545  if (seg.GetRange().GetLength() <= 0)
546  continue;
547 
548  const IAlnSegment::TSignedRange& curr_aln_r = seg.GetAlnRange();
549 
550  TSignedSeqPos curr_seq_from =
551  m_AlnMgr->GetSeqPosFromAlnPos(anchor, curr_aln_r.GetFrom(), IAlnExplorer::eLeft) /
552  ctx.base_width_anchor;
553  TSignedSeqPos curr_seq_to =
554  m_AlnMgr->GetSeqPosFromAlnPos(anchor, curr_aln_r.GetTo(), IAlnExplorer::eRight) /
555  ctx.base_width_anchor;
556  if (curr_seq_from > curr_seq_to) {
557  swap(curr_seq_from, curr_seq_to);
558  }
559  TSeqRange curr_seq(curr_seq_from, curr_seq_to - 1);
560  if (curr_seq.GetLength() <= 1)
561  continue;
562 
563  TModelRange inrc = m_Context->IntersectVisible(curr_seq);
564  TSeqRange visible_range((TSeqPos)inrc.GetFrom(), (TSeqPos)inrc.GetTo());
565  if (visible_range.Empty())
566  continue;
567 
568  unaligned_regions.emplace_back(visible_range.GetFrom() + 1, visible_range.GetTo() + 1);
570 
571  TModelUnit y = ctx.yy + ctx.half;
572 
573  if (h_text > ctx.bar_h) {
574  m_Context->DrawStippledLine(visible_range.GetFrom() + 1, y, visible_range.GetTo() + 1, y);
575  continue;
576  }
577 
578  // label text that will be shown
579  string sLabelTextOut = NStr::IntToString(seg.GetRange().GetLength(), NStr::fWithCommas);
580  sLabelTextOut += " bp unaligned";
581 
582  TModelUnit label_width = m_Context->ScreenToSeq(gl.TextWidth(&l_font, sLabelTextOut.c_str()));
583  TModelUnit half_label = label_width / 2.0;
584 
585  int labelsCount = round(visible_range.GetLength() / seg_width);
586  if (!labelsCount) {
587  if ((label_width + label_width*0.5) >= visible_range.GetLength()) {
588  m_Context->DrawStippledLine(visible_range.GetFrom() + 1, y, visible_range.GetTo() + 1, y);
589  continue;
590  }
591  labelsCount = 1;
592  }
593 
594  TModelUnit yM = ctx.yy + ctx.bar_h - (ctx.bar_h - h_text) / 2;
595 
596 
597  TModelUnit part_size = visible_range.GetLength() / labelsCount;
598  TModelUnit xM;
599  TModelUnit xLF, xLT;
600  xLF = visible_range.GetFrom();
601  for (int i = 0; i < labelsCount; ++i) {
602  xM = visible_range.GetFrom() + part_size / 2.0 + i*part_size;
603  xLT = visible_range.GetFrom() + part_size / 2.0 + i*part_size - half_label;
604  m_Context->DrawStippledLine(xLF, y, xLT, y);
605  m_Context->TextOut(&l_font, sLabelTextOut.c_str(), xM, yM, true, true);
606  xLF = visible_range.GetFrom() + part_size / 2.0 + i*part_size + half_label;
607  }
608  m_Context->DrawStippledLine(xLF, y, visible_range.GetToOpen(), y);
609  }
610  }
611 }
612 
613 
614 
615 void CAlignGlyph::x_DrawTailGlyphs(const SDrawContext& ctx, bool show_label, const CRgbaColor& c_fg) const
616 {
617  IRender& gl = GetGl();
618  if (ctx.bar_h <= 2)
619  show_label = false;
620 
621  int aligned_seq = m_AlnMgr->GetAnchor() == 0 ? 1 : 0;
624  TModelUnit y_base = ctx.yy;
625 
626  TSignedSeqPos tail_5(0);
627  TSignedSeqPos tail_3(0);
628  TSignedSeqPos from(ctx.f);
629  TSignedSeqPos to(ctx.t);
630  m_AlnMgr->GetUnalignedTails(tail_5, tail_3, false);
631 
635  if (tail_5 > ctx.tail_5)
636  tail_5 -= ctx.tail_5;
637  else
638  tail_5 = 0;
639  if (tail_3 > ctx.tail_3)
640  tail_3 -= ctx.tail_3;
641  else
642  tail_3 = 0;
643  }
644 
645  // starting tail
646  if (tail_5 > 0) {
647  TModelUnit x_base = from - gap;
648  gl.ColorC(c_fg);
650  bool is_polya = CGuiObjectInfoSeq_align::IsPolyA(m_AlnMgr->GetBioseqHandle(aligned_seq), tail_5_rng.GetFrom(), tail_5_rng.GetToOpen());
651  m_Context->DrawUnalignedTail(x_base - size, x_base, y_base,
652  y_base + ctx.bar_h, is_polya, CRgbaColor(m_Config->m_TailColor, m_FadeFactor));
653  if (show_label) {
654  const CGlTextureFont& l_font = m_Config->m_LabelFont;
655  string len_str = NStr::IntToString(tail_5, NStr::fWithCommas);
656  TModelUnit num_len = gl.TextWidth(&l_font, len_str.c_str());
657 
658  TModelUnit xM = x_base - size - gap - m_Context->ScreenToSeq(num_len);
659  TModelUnit yM = y_base + ctx.bar_h - 2.0;
660 
661  TModelUnit h_text = gl.TextHeight(&l_font);
662 
663  if (h_text < ctx.bar_h) {
665  m_Context->TextOut(&l_font, len_str.c_str(), xM, yM, false);
666  }
667  }
668  }
669 
670  // ending tail
671  if (tail_3 > 0) {
672  TModelUnit x_base = to + gap + 1;
673  gl.ColorC(c_fg);
675  bool is_polya = CGuiObjectInfoSeq_align::IsPolyA(m_AlnMgr->GetBioseqHandle(aligned_seq), tail_3_rng.GetFrom(), tail_3_rng.GetToOpen());
676  m_Context->DrawUnalignedTail(x_base, x_base + size, y_base,
677  y_base + ctx.bar_h, is_polya, CRgbaColor(m_Config->m_TailColor, m_FadeFactor));
678  if (show_label) {
679  const CGlTextureFont& l_font = m_Config->m_LabelFont;
680  string len_str = NStr::IntToString(tail_3, NStr::fWithCommas);
681 
682  TModelUnit xM = x_base + size + gap;
683  TModelUnit yM = y_base + ctx.bar_h - 2.0;;
684 
685  TModelUnit h_text = gl.TextHeight(&l_font);
686 
687  if (h_text < ctx.bar_h) {
689  m_Context->TextOut(&l_font, len_str.c_str(), xM, yM, false);
690  }
691  }
692  }
693 }
694 
696 {
697  if (ctx.tail_5 > 0) {
699  }
700  if (ctx.tail_3 > 0) {
702  }
703  TSignedSeqPos tail_5 = 0;
704  TSignedSeqPos tail_3 = 0;
705  m_AlnMgr->GetUnalignedTails(tail_5, tail_3, false);
706  if ((tail_5 > ctx.tail_5) || (tail_3 > ctx.tail_3))
707  x_DrawTailGlyphs(ctx, true, c_fg);
708 }
709 
710 void CAlignGlyph::x_DrawUnalignedBar(const ETail tail, const SDrawContext& ctx, const CRgbaColor& c_fg) const
711 {
712  IRender& gl = GetGl();
713 
715 
716  gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
717 
718  gl.PushMatrix();
719  gl.Scalef(m_Context->GetScale(), 1.0f, 1.0f);
720 
722  TSeqRange visible_range((TSeqPos)inrc.GetFrom(), (TSeqPos)inrc.GetTo());
723  if (!visible_range.Empty()) {
724  gl.Color4d(c_fg.GetRed(), c_fg.GetGreen(), c_fg.GetBlue(), m_FadeFactor);
725  TVPUnit start = m_Context->SeqToScreenX(visible_range.GetFrom());
726  TVPUnit stop = m_Context->SeqToScreenX(visible_range.GetToOpen());
727  gl.Rectd(start, ctx.yy, stop, ctx.yy + ctx.bar_h);
728  }
729 
730  gl.PopMatrix();
731 }
732 
733 void CAlignGlyph::x_DrawUnalignedRowSequence(const ETail tail, const SDrawContext& ctx, const CRgbaColor& c_fg) const
734 {
735  IRender& gl = GetGl();
736 
737  int anchor = m_AlnMgr->GetAnchor();
738  int aligned_seq = anchor == 0 ? 1 : 0;
739 
741 
742  TSeqRange visible_unaligned_range(range);
743  TModelRange inrc = m_Context->IntersectVisible(visible_unaligned_range);
744 
745  if (inrc.Empty()) {
746  return;
747  }
748 
749  visible_unaligned_range.SetFrom((TSeqPos)inrc.GetFrom());
750  visible_unaligned_range.SetTo((TSeqPos)inrc.GetTo());
751 
752  TSeqRange visible_sequence_range(x_ConvertAlnTaillRngToSeqRng(tail, ctx, visible_unaligned_range));
753 
754  gl.ColorC(c_fg);
755 
756  const CBioseq_Handle& mhndl = m_AlnMgr->GetBioseqHandle(anchor);
757  const CBioseq_Handle& hndl = m_AlnMgr->GetBioseqHandle(aligned_seq);
758  if (!hndl || !mhndl)
759  return;
760 
761  bool ab = mhndl.IsAa();
762  bool rb = hndl.IsAa();
763 
764  EAlignSpacing spacing(eOne2One);
765  if (!ab && rb) spacing = eOne2Three;
766  if (ab && !rb) spacing = eThree2One;
767 
768  try {
769 
771 
772  string seq, tmp_seq;
773  s_vec.GetSeqData(visible_sequence_range.GetFrom(), visible_sequence_range.GetTo(), tmp_seq);
774 
775  if (ctx.reverse_strand) {
776  if (rb) {
777  // protein sequence, just reverse it
778  CSeqManip::Reverse(tmp_seq, CSeqUtil::e_Iupacaa, 0, static_cast<TSeqPos>(tmp_seq.length()), seq);
779  }
780  else {
781  // nucleotide sequence, get reverse and complement
782  if (m_Context->IsFlippedStrand()) {
783  CSeqManip::Reverse(tmp_seq, CSeqUtil::e_Iupacna, 0, static_cast<TSeqPos>(tmp_seq.length()), seq);
784  }
785  else {
786  CSeqManip::ReverseComplement(tmp_seq, CSeqUtil::e_Iupacna, 0, static_cast<TSeqPos>(tmp_seq.length()), seq);
787  }
788  }
789  }
790  else {
791  if (!rb && m_Context->IsFlippedStrand()) {
792  CSeqManip::Complement(tmp_seq, CSeqUtil::e_Iupacna, 0, static_cast<TSeqPos>(tmp_seq.length()), seq);
793  }
794  else {
795  swap(seq, tmp_seq);
796  }
797  }
798 
799  string translated_seq;
800  switch (spacing) {
801  case eOne2Three:
802  translated_seq = seq;
803  break;
804  case eThree2One: {
805  CGenetic_code gcode;
806  gcode.SetId(m_AlnMgr->GetGenCode(aligned_seq));
807  CSeqTranslator::Translate(seq, translated_seq, CSeqTranslator::fDefault, &gcode);
808  break;
809  }
810  default:
811  break;
812  }
813 
814  char bases[2];
815  bases[1] = '\0';
816  TVPUnit font_w = (TVPUnit)(gl.TextWidth(&(m_Config->m_SeqFont), "G") * 0.5f);
817  TModelUnit addon = 0.5 - m_Context->ScreenToSeq(font_w);
818 
819  TSeqPos sStart = visible_unaligned_range.GetFrom();
820 
822  // Draw characters (actg)
823  for (TSeqPos bp = 0; bp < seq.size(); bp++) {
824  TModelUnit pos = 0;
825  switch (spacing) {
826  case eOne2One:
827  pos = sStart + bp + addon;
828  break;
829  case eOne2Three:
830  pos = sStart + bp * 3 + addon + 1;
831  break;
832  case eThree2One:
833  pos = sStart + bp * kPWAlignPackLevel + addon - kPWAlignPackLevel;
834  break;
835  default:
836  break;
837  }
838 
839 
840  bases[0] = seq[bp];
841 
842  m_Context->TextOut(&m_Config->m_SeqFont, bases, pos, ctx.center_y + fs * 0.5, false);
843  } // for TSeqPos
844  }
845  catch (CException&) {
846  /// ignore exceptions - these are all objmgr related
847  }
848 }
849 
851 {
852  if (ctx.seq_range.Empty())
853  return;
854 
855  if (!(m_SeqAlign->GetSegs().Which() == CSeq_align::TSegs::e_Spliced && m_OrigAnchor == 1))
856  return;
857  IRender& gl = GetGl();
858  const CSpliced_seg& spliced_seg = m_SeqAlign->GetSegs().GetSpliced();
859  string splice5;
860  TSeqPos pre_stop = 0;
861  bool neg_genomic = (spliced_seg.GetSeqStrand(1) == eNa_strand_minus);
862  ITERATE (CSpliced_seg::TExons, exon_it, spliced_seg.GetExons()) {
863  const CSpliced_exon& exon = **exon_it;
864  string splice3;
865  if (exon.IsSetAcceptor_before_exon()) {
866  splice3 = exon.GetAcceptor_before_exon().GetBases();
867  }
868 
869  // render a bold red bar for non-consensus splice site
870  if ( !splice5.empty() && !splice3.empty() &&
871  !IsConsensusSplice(splice5, splice3) ) {
872  gl.LineWidth(4.0f);
874  m_Context->DrawLine(pre_stop, ctx.center_y,
875  neg_genomic ? exon.GetGenomic_end() + 1 :
876  exon.GetGenomic_start(), ctx.center_y);
877  gl.LineWidth(1.0f);
878  }
879  if (exon.IsSetDonor_after_exon()) {
880  splice5 = exon.GetDonor_after_exon().GetBases();
881  } else {
882  splice5 = kEmptyStr;
883  }
884  pre_stop = neg_genomic ?
885  exon.GetGenomic_start() : exon.GetGenomic_end() + 1;
886  }
887 }
888 
890 {
891  if (ctx.seq_range.Empty())
892  return;
893  CRgbaColor c;
894  if (ctx.override_color)
895  c = ctx.read_status_color;
896  else
897  c = c_fg;
898 
899  // Don't use blending here - just overwrite but take any alpha into account
900  if (m_FadeFactor < 1.0) {
901  c.Lighten(1.0f - m_FadeFactor);
902  }
903 
904  // m_Intervals - are calculated in UpdateBoundingBox
905  ITERATE(vector<TSeqRange>, it, m_Intervals) {
906  if (ctx.override_color)
907  m_Context->Draw3DQuad(it->GetFrom(), ctx.yy, it->GetTo(), ctx.yy + ctx.bar_h, c, true);
908  else
909  m_Context->Draw3DQuad(it->GetFrom(), ctx.yy, it->GetTo(), ctx.yy + ctx.bar_h, c, true);
910  }
911 }
912 
914 {
915  IRender& gl = GetGl();
916  // draw strand indicators
918  m_Context->SeqToScreen(ctx.whole_range.GetLength()) > 8.0) {
919  TModelUnit xM = (ctx.whole_range.GetFrom() + ctx.whole_range.GetTo()) * 0.5;
920  if (m_Context->WillSeqLetterFit()) {
921  // make sure we don't step on the sequence letter
922  // when sequence is shown
923  xM = ceil(xM);
924  }
925 
926  TModelUnit yM = ctx.yy + ctx.half;
927  gl.Color4f(0.0f, 0.0f, 0.0f, m_FadeFactor); // Black
928  m_Context->DrawGreaterLessSign(xM, yM, ctx.bar_h, ctx.reverse_strand);
929  }
930 }
931 
933 {
934  IRender& gl = GetGl();
935  if (m_ShowScore && m_AlnMgr->IsRegular()) {
936  double identity = 100.0;
937  if ( !m_SeqAlign->GetNamedScore(CSeq_align::eScore_PercentIdentity, identity) ) {
938  TSeqPos align_length = m_SeqAlign->GetAlignLength();
939  int identities = (int)align_length;
940  if ( !m_SeqAlign->GetNamedScore(CSeq_align::eScore_IdentityCount, identities) ) {
941  // CScoreBuilder builder;
942  // identities = builder.GetIdentityCount(*scope, align);
943  }
944  identity = identities * 100 / align_length;
945  }
946  identity *= 0.01;
947  if (identity > 0.6) {
948  identity = 1.75 * identity - 0.75;
949  } else {
950  identity /= 2.0;
951  }
952  CRgbaColor color_max(0.78f, 0.78f, 0.78f, m_FadeFactor);
953  CRgbaColor color_min(1.0f, 0.0f, 0.0f, m_FadeFactor);
954  CRgbaColor color(CRgbaColor::Interpolate(color_max, color_min, identity));
955  if (ctx.override_color)
956  color = ctx.read_status_color;
957 
958  gl.ColorC(color);
959  m_Context->DrawQuad(ctx.seq_range.GetFrom(), ctx.yy, ctx.seq_range.GetTo(), ctx.yy + ctx.bar_h, false);
960  } else {
961  m_Context->Draw3DQuad(ctx.seq_range.GetFrom(), ctx.yy, ctx.seq_range.GetTo(), ctx.yy + ctx.bar_h, c_fg, true);
962  }
964 }
965 
966 
968  bool selected,
969  bool show_label,
970  const CRgbaColor& c_fg,
971  const CRgbaColor& c_seq,
972  const CRgbaColor& c_mis) const
973 {
974  IRender& gl = GetGl();
975 
976  int anchor = m_AlnMgr->GetAnchor();
977  int aligned_seq = m_AlnMgr->GetQuery();
978  if (aligned_seq < 0) {
979  aligned_seq = 0;
980  }
982  ctx.base_width_anchor = m_AlnMgr->GetBaseWidth(anchor);
983  ctx.base_width_curr = m_AlnMgr->GetBaseWidth(aligned_seq);
984  ctx.f = m_AlnMgr->GetSeqStart(anchor);
985  ctx.f /= ctx.base_width_anchor;
986  ctx.t = m_AlnMgr->GetSeqStop(anchor);
987  ctx.t /= ctx.base_width_anchor;
988  ctx.reverse_strand = m_AlnMgr->IsNegativeStrand(aligned_seq) != m_AlnMgr->IsNegativeStrand(anchor);
989 
990  ctx.seq_range.Set(ctx.f, ctx.t);
992  ctx.whole_range = m_AlnMgr->GetAlnRangeWithTails();
993  else
994  ctx.whole_range = ctx.seq_range;
995 
996  if (ctx.seq_range.Empty()) {
997  LOG_POST(Error
998  << "CAlignGlyph::DrawPWAlignElem: zero alignment range!");
999  return;
1000  }
1001  {
1002  TModelRange inrc = m_Context->IntersectVisible(ctx.whole_range);
1003  if (inrc.Empty())
1004  return;
1005  ctx.whole_range.SetOpen((TSeqPos)inrc.GetFrom(), (TSeqPos)inrc.GetToOpen());
1006  inrc = m_Context->IntersectVisible(ctx.seq_range);
1007  ctx.seq_range.SetOpen((TSeqPos)inrc.GetFrom(), (TSeqPos)inrc.GetToOpen());
1008  }
1009 
1010  // Special colors for sra reads with errors: failed reads red,
1011  // pcr duplicates pale gray. SV-2153
1012  ctx.override_color = false;
1013  x_GetOverrideColor(ctx.override_color, ctx.read_status_color);
1014 
1015  ctx.bar_h = GetBarHeight();
1016  ctx.half = ctx.bar_h * 0.5;
1017  ctx.center_y = rcm.Bottom() - ctx.half - 1.0;
1018  ctx.yy = ctx.center_y - ctx.half;
1019 
1020  m_DisableTooltipsCaching = false;
1021 
1022  if (IsSimplified()) {
1023  x_DrawSimplified(ctx, c_fg);
1024  // Draw selection
1025  if (selected)
1026  m_Context->DrawSelection(rcm);
1027  return;
1028  }
1029 
1031  anchor, ctx.seq_range.GetFrom() * ctx.base_width_anchor, IAlnExplorer::eRight);
1033  anchor, ctx.seq_range.GetTo() * ctx.base_width_anchor, IAlnExplorer::eLeft);
1034  if (aln_r_s > aln_r_e) {
1035  swap(aln_r_s, aln_r_e);
1036  }
1037  ctx.aln_range = TSignedSeqRange(aln_r_s, aln_r_e);
1038 
1039  //cout << "seq_range:" << ctx.seq_range << ", aln_range:" << ctx.aln_range << endl;
1040 
1041  bool show_score = x_ShowScore();
1042  gl.ColorC(c_fg);
1043 
1044  TModelUnit align_len = m_Context->SeqToScreen(ctx.whole_range.GetLength());
1045  bool show_unaligned_tails = x_ShowUnalignedTails(align_len);
1046 
1047  // get tail sizes
1048  if (show_unaligned_tails) {
1049  auto aln_partial_flags = m_AlnMgr->GetPartialFlags();
1051  show_unaligned_tails = false;
1052  } else {
1053  m_AlnMgr->GetUnalignedTails(ctx.tail_5, ctx.tail_3);
1054  }
1055  }
1056  double barh = abs(m_Context->GetGlPane()->GetScaleY() * ctx.bar_h);
1057  if ((m_Context->GetScale() < 1 && !show_score) ||
1058  (show_score && m_Context->WillSeqLetterFit() && ctx.tail_3)) {
1059  TModelUnit over7 = m_Context->ScreenToSeq(7);
1060  TModelUnit over2 = m_Context->ScreenToSeq(2);
1061  TModelUnit y = ctx.yy + ctx.half;
1062  if (ctx.reverse_strand) {
1064  }
1065  else {
1067  }
1068 
1069  // ignore strand signs if bar is less that 2 pix
1070  if (barh >= 2.) {
1071 
1072  if (show_score) {
1073  // make the color for the strand indicator matches well with
1074  // the alignment bar color
1075  gl.Color4f(0.5f, 0.5f, 0.5f, m_FadeFactor);
1076  }
1077  if (ctx.reverse_strand && !(show_unaligned_tails && ctx.tail_5)) {
1078  m_Context->DrawTriangle(ctx.f - over7, y,
1079  ctx.f - over2, ctx.yy - 1, ctx.f - over2, ctx.yy + ctx.bar_h + 1);
1080  }
1081  else if (!(show_unaligned_tails && ctx.tail_3)) {
1082  m_Context->DrawTriangle(ctx.t + 1 + over7, y,
1083  ctx.t + 1 + over2, ctx.yy - 1, ctx.t + 1 + over2, ctx.yy + ctx.bar_h + 1);
1084  }
1085  }
1086  } else {
1088  } // arrows
1089 
1090  // Draw Sequence and quads for segments
1091  if (show_score) {
1092  // Disable blending for scores since they overwrite the alignment bar
1093  if (m_FadeFactor != 1.0f)
1094  gl.Disable(GL_BLEND);
1095 
1096  // do score coloration
1097  int row_num = m_AlnMgr->GetNumRows();
1098  for (int row = 0; row < row_num; ++row) {
1099  if (row == anchor) {
1100  continue; // skip master seq
1101  }
1102  if (m_Score->IsAverageable()) {
1103  x_RenderAveragableScores(ctx.yy, ctx.aln_range, ctx.seq_range, ctx.bar_h, row,
1104  ctx.override_color, ctx.read_status_color);
1105  } else {
1106  x_RenderNonAveragableScores(ctx.yy, ctx.aln_range, ctx.seq_range, ctx.bar_h, row,
1107  ctx.override_color, ctx.read_status_color);
1108  }
1109  }
1110 
1111  if (m_FadeFactor != 1.0f)
1112  gl.Enable(GL_BLEND);
1113 
1114  // if (m_Config->m_CompactMode == CAlignmentConfig::eNormal)
1115  x_DrawGaps(ctx);
1116  x_DrawInserts(ctx);
1117 
1118  // draw unaligned tails
1119  if (show_unaligned_tails) {
1120  switch (m_Config->m_UnalignedTailsMode)
1121  {
1123  break;
1125  x_DrawTailGlyphs(ctx, true, c_fg);
1126  break;
1128  x_DrawTailSequences(ctx, c_fg);
1129  break;
1130  }
1131  }
1132 
1133  } else {
1134  // Disable blending since we want overwrite here for the fading effect,
1135  // (if any) not blending with other elements
1136  if (m_FadeFactor != 1.0f)
1137  gl.Disable(GL_BLEND);
1138 
1139  x_DrawNoScoreAlign(ctx, c_fg);
1140 
1141  if (m_FadeFactor != 1.0f)
1142  gl.Enable(GL_BLEND);
1143  }
1144 
1145 
1146  // special case
1147  // reflect non-consensus splice sites for spliced-seg alignment
1148  // we only show non-consensus site when showing in genomic sequence
1149  // context, not product sequence context.
1151 
1152  if ((m_Context->WillSeqLetterFit() && ctx.base_width_anchor <= ctx.base_width_curr)
1153  || (m_Context->GetScale() <= 0.05 && ctx.base_width_anchor > ctx.base_width_curr)) {
1154  try {
1155  x_DrawAlignRowSequence(ctx.center_y, 1 - anchor, c_fg, c_seq, c_mis);
1156  } catch (const CException& e) {
1157  LOG_POST(Warning << "Can't show alignment sequence due to an error: " << e.GetMsg());
1158  }
1161  if (ctx.tail_5 > 0) {
1162  try {
1164  }
1165  catch (const CException& e) {
1166  LOG_POST(Warning << "Can't show 5' tail sequence due to an error: " << e.GetMsg());
1167  }
1168  }
1169  if (ctx.tail_3 > 0) {
1170  try {
1172  }
1173  catch (const CException& e) {
1174  LOG_POST(Warning << "Can't show 3' tail sequence due to an error: " << e.GetMsg());
1175  }
1176  }
1177  }
1178  }
1179 
1181 
1182  // Draw selection
1183  if (selected) {
1184  m_Context->DrawSelection(rcm);
1185  }
1186 }
1187 
1188 
1190 {
1191  title->erase();
1192 
1193  if ( !x_IsPWAlign()) {
1194  *title = "[Alignment] " +
1195  NStr::UIntToString(m_AlnMgr->GetNumRows()) + " sequences";
1196  return;
1197  }
1198 
1199  // pairwise align
1200  switch (type) {
1201  case CLabel::eType:
1202  case CLabel::eContent:
1204  {
1205  // display the name of the aligned sequence.
1206  int row = 1 - m_OrigAnchor;
1207  CLabel::GetLabel(m_OrigSeqAlign.GetSeq_align()->GetSeq_id(row),
1208  title, type, &m_Context->GetScope());
1209 
1210  // make title/label shorter incase it is a cSRA alignment on panfs
1211  if (title->length() > 20 && title->find("\\panfs\\") != string::npos) {
1212  size_t pos = title->find_last_of("\\");
1213  if (pos != string::npos) {
1214  *title = title->substr(pos + 1);
1215  if (title->length() > 20) {
1216  pos = title->rfind('.');
1217  if (pos != string::npos && pos > 0) {
1218  pos = title->rfind('.', pos - 1);
1219  if (pos != string::npos) {
1220  *title = title->substr(pos + 1);
1221  }
1222  }
1223  }
1224  }
1225  }
1226  };
1227  break;
1229  case CLabel::eDescription:
1230  CLabel::GetLabel(*GetOrigAlignment().GetSeq_align(),
1231  title, type, &m_Context->GetScope());
1232  break;
1233  default:
1234  break;
1235  }
1236 }
1237 
1238 
1240 {
1242  if (m_FadeFactor != 1.) {
1243  IRender& gl = GetGl();
1244  gl.Enable(GL_BLEND);
1245  gl.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
1246  }
1247 }
1248 
1250 {
1251  if (!GetVisible())
1252  return;
1253  auto vis_rect = m_Context->GetGlPane()->GetVisibleRect();
1254  if (GetTop() > vis_rect.Bottom() && GetBottom() < vis_rect.Top())
1255  return;
1256 
1257  if (x_IsPWAlign()) {
1258  ApplyFading();
1259  x_DrawPWAlign();
1260  } else {
1261  // No fade out for multiple align drawing for now. Since all the rows in
1262  // this case are inside this one glyph and drawn in a loop, we would need
1263  // to handle things a bit differently.
1264  m_FadeFactor = 1.f;
1265  x_DrawMultiAlign();
1266  }
1267 }
1268 
1269 
1271 {
1272  IRender& gl = GetGl();
1273 
1274  if (m_Intervals.empty() && x_IsPWAlign()) {
1276  }
1277 
1278  TSeqRange range = GetRange();
1279  SetWidth(range.GetLength());
1280  SetLeft(range.GetFrom());
1281 
1282  TModelUnit bar_h = GetBarHeight();
1283  if (x_IsPWAlign()) {
1285  } else {
1286  SetHeight((bar_h + kAlignRowSpace) * (m_AlnMgr->GetNumRows() - 1));
1287  }
1288 
1289  bool show_label = x_ShowLabel();
1290  // don't show labels and unaligned tails for simplified rendering
1291  if (IsSimplified() && !show_label) {
1292  return;
1293  }
1294 
1295  bool top_label = m_Config->m_LabelPos == CAlignmentConfig::ePos_Above;
1296  const CGlTextureFont& font = m_Config->m_LabelFont;
1297  int anchor = m_AlnMgr->GetAnchor();
1298  bool reverse_strand = m_AlnMgr->IsNegativeStrand(0) != m_AlnMgr->IsNegativeStrand(1);
1299  TSignedSeqPos visible_tail_5 = 0;
1300  TSignedSeqPos visible_tail_3 = 0;
1301  TSignedSeqPos tail_5 = 0;
1302  TSignedSeqPos tail_3 = 0;
1303  TSignedSeqPos base_width_curr = m_AlnMgr->GetBaseWidth(anchor == 0 ? 1 : 0);
1305 
1306  // get tail sizes
1307  if (x_ShowUnalignedTails(align_len)) {
1308 
1309  m_AlnMgr->GetUnalignedTails(tail_5, tail_3, false);
1310  m_AlnMgr->GetUnalignedTails(visible_tail_5, visible_tail_3);
1311 
1312  TModelUnit tail_len = 0;
1313  if (tail_5 > 0) {
1314  tail_len = x_GetTailWidth(tail_5, visible_tail_5, base_width_curr);
1315 
1316  SetWidth(GetWidth() + tail_len);
1317  SetLeft(GetLeft() - tail_len);
1318  }
1319  if (tail_3 > 0) {
1320  tail_len = x_GetTailWidth(tail_3, visible_tail_3, base_width_curr);
1321 
1322  SetWidth(GetWidth() + tail_len);
1323  }
1324  }
1325 
1326  if (show_label) {
1327  if (top_label) {
1328  if (x_IsPWAlign()) {
1329  // vertical space for alignment label
1330  SetHeight(GetHeight() + gl.TextHeight(&font) + 3);
1331  } else {
1332  SetHeight(GetHeight() + (gl.TextHeight(&font) + kLabelSpace_v) *
1333  (m_AlnMgr->GetNumRows() - 1));
1334  }
1335  } else { // not top label (side label)
1336  if (x_IsPWAlign()) {
1337  // horizontal space for alignment label
1338  string label;
1340  TModelUnit label_w = gl.TextWidth(&font, label.c_str());
1341  label_w = m_Context->ScreenToSeq(label_w + kLabelSpace_h);
1342  SetWidth(GetWidth() + label_w);
1343  if ( !reverse_strand ) {
1344  SetLeft(GetLeft() - label_w);
1345  }
1346  } else {
1347  TModelUnit max_label_w = 0.0;
1348  for (int row = 0; row < m_AlnMgr->GetNumRows(); ++row) {
1349  if (row == anchor) {
1350  continue; // skip master seq
1351  }
1352  string label;
1355  if (m_AlnMgr->IsNegativeStrand(anchor) !=
1357  label += " (Neg)";
1358  }
1359  TModelUnit label_w = gl.TextWidth(&font, label.c_str());
1360  max_label_w = max(max_label_w, label_w);
1361  }
1362  max_label_w += kLabelSpace_h;
1363  max_label_w = m_Context->ScreenToSeq(max_label_w);
1364  SetWidth(GetWidth() + max_label_w);
1365  SetLeft(GetLeft() - max_label_w);
1366  }
1367  }
1368  }
1369 }
1370 
1371 
1373 {
1374  IRender& gl = GetGl();
1375 
1376  TModelRect rcm = GetModelRect();
1377  bool show_label = x_ShowLabel();
1378 
1379  DrawPWAlignElem(rcm, IsSelected(), show_label,
1383 
1384  if (show_label) {
1385  string label;
1387  const CGlTextureFont& l_font = m_Config->m_LabelFont;
1388  bool top_label = m_Config->m_LabelPos == CAlignmentConfig::ePos_Above;
1389  TModelUnit label_h = gl.TextHeight(&l_font);
1390  TModelRange inrc = m_Context->IntersectVisible(this);
1391  TModelUnit xM = inrc.GetFrom() + inrc.GetLength() * 0.5;
1392  TModelUnit yM = rcm.Top() + label_h + 1.0;
1393  TModelUnit max_label_width_px = m_Context->SeqToScreen(inrc.GetLength() - 1);
1394  if (max_label_width_px > 0.0) {
1395  //if (max_label_width_px > 2.0) max_label_width_px -= 2.0;
1396  TModelUnit label_width_px = gl.TextWidth(&l_font, label.c_str());
1397  if (label_width_px > max_label_width_px) {
1398  label_width_px = max_label_width_px;
1399  label = l_font.Truncate(label.c_str(), label_width_px);
1400  if ((string::npos != label.find("...")) && (label.length() <= 5))
1401  return;
1402  }
1403 
1404  if ( !top_label ) {
1405  TModelUnit t_w = m_Context->ScreenToSeq(label_width_px);
1406  bool reverse_strand = m_AlnMgr->IsNegativeStrand(0) !=
1408  yM = GetBottom() - 2.0;
1409  if (reverse_strand) {
1410  xM = inrc.GetTo() - t_w;
1411  if (inrc.GetTo() < GetRight()) {
1413  m_Context->DrawBackground( TModelRect(xM, yM + 1.0,
1414  inrc.GetTo(), yM - label_h - 1.0), 0);
1415  }
1416  } else {
1417  xM = inrc.GetFrom();
1418  if (inrc.GetFrom() > GetLeft()) {
1420  m_Context->DrawBackground( TModelRect(xM, yM + 1.0,
1421  xM + t_w, yM - label_h - 1.0), 0);
1422  }
1423  }
1424  }
1425 
1426  if (IsSelected()) {
1428  } else {
1430  }
1431  m_Context->TextOut(&l_font, label.c_str(), xM, yM, top_label);
1432  }
1433  }
1434 }
1435 
1437 {
1438  IRender& gl = GetGl();
1439 
1440  int anchor = m_AlnMgr->GetAnchor();
1441 
1442  TSeqPos base_width_anchor = m_AlnMgr->GetBaseWidth(anchor);
1443  TSeqRange anchor_range(
1444  m_AlnMgr->GetSeqStart(anchor) / base_width_anchor,
1445  m_AlnMgr->GetSeqStop(anchor) / base_width_anchor);
1446  if (anchor_range.Empty()) {
1447  LOG_POST(Error
1448  << "CAlignGlyph::x_DrawMultiAlign: zero alignment range!");
1449  return;
1450  }
1451 
1452  TModelRange inrc = m_Context->IntersectVisible(anchor_range);
1453  anchor_range.Set((TSeqPos)inrc.GetFrom(), (TSeqPos)inrc.GetTo());
1454  if (anchor_range.Empty()) {
1455  return;
1456  }
1457 
1458  // Special colors for sra reads with errors: failed reads red,
1459  // pcr duplicates pale gray. SV-2153
1460  bool override_color = false;
1461  CRgbaColor read_status_color;
1462  x_GetOverrideColor(override_color, read_status_color);
1463 
1464  TSignedSeqPos aln_r_s = m_AlnMgr->GetAlnPosFromSeqPos(anchor,
1465  anchor_range.GetFrom() * base_width_anchor, IAlnExplorer::eRight);
1466  TSignedSeqPos aln_r_e = m_AlnMgr->GetAlnPosFromSeqPos(anchor,
1467  anchor_range.GetTo() * base_width_anchor, IAlnExplorer::eLeft);
1468  if (aln_r_s > aln_r_e) {
1469  swap(aln_r_s, aln_r_e);
1470  }
1471  TSignedSeqRange aln_total_range(aln_r_s, aln_r_e);
1472 
1473 
1474  TModelRect rcm = GetModelRect();
1475  TModelUnit base = rcm.Top();
1476  TModelUnit bar_h = GetBarHeight();
1477 
1478  bool show_label = x_ShowLabel();
1479  TModelUnit yy = base + 1;
1480  for (int row = 0; row < m_AlnMgr->GetNumRows(); ++row) {
1481  if (row == anchor) {
1482  continue; // skip master seq
1483  }
1484 
1485  TSignedSeqRange aln_range = aln_total_range.IntersectionWith(m_AlnMgr->GetSeqAlnRange(row));
1486  TModelUnit xM = (inrc.GetFrom() + inrc.GetTo()) * 0.5;
1487  bool reverse_strand =
1489  m_AlnMgr->IsNegativeStrand(anchor);
1490 
1491  // Draw label
1492  if (show_label && m_Config->m_LabelPos == CAlignmentConfig::ePos_Above) {
1493  const CGlTextureFont& l_font = m_Config->m_LabelFont;
1494  yy += gl.TextHeight(&l_font);
1496  yy += kLabelSpace_v;
1497  }
1498 
1499  TModelUnit mid = yy + bar_h * 0.5;
1500  if (x_ShowScore()) {
1501  // do score coloration
1502  if (m_Score->IsAverageable()) {
1503  x_RenderAveragableScores(yy, aln_range, anchor_range, bar_h, row,
1504  override_color, read_status_color);
1505  } else {
1506  x_RenderNonAveragableScores(yy, aln_range, anchor_range, bar_h, row,
1507  override_color, read_status_color);
1508  }
1509 
1510  // color the gap differently
1511  gl.Color4f(1.0f, 0.0f, 0.0f, 1.0f);
1512  CGlAttrGuard AttrGuard(GL_LINE_BIT);
1513  gl.Disable(GL_LINE_SMOOTH);
1514 
1515  unique_ptr<IAlnSegmentIterator> p_it(m_AlnMgr->CreateSegmentIterator(row, aln_range, IAlnSegmentIterator::eAllSegments));
1516 
1517  gl.LineWidth(2.0f);
1518  for (IAlnSegmentIterator& it = *p_it; it; ++it) {
1519  const IAlnSegment& seg = *it;
1520  if ( !(seg.GetType() & IAlnSegment::fIndel) ||
1521  !seg.GetRange().Empty() ) {
1522  continue;
1523  }
1524 
1525  TSeqPos start = m_AlnMgr->GetSeqPosFromAlnPos(anchor, seg.GetAlnRange().GetFrom());
1526  start /= base_width_anchor;
1527  TSeqPos stop = start + seg.GetAlnRange().GetLength() / base_width_anchor;
1528  m_Context->DrawLine(start, mid, stop, mid);
1529  }
1530  gl.LineWidth(1.0f);
1531 
1532  // draw inserts
1534  const TModelUnit barOff =
1535  m_AlnMgr->IsNegativeStrand(anchor) ? 1.0 : 0.0;
1536  const TModelUnit kMinLen = m_Context->ScreenToSeq(4); // 4 pixels in model units
1537 
1538  TModelUnit y1 = yy;
1539  TModelUnit y2 = yy + bar_h;
1540  p_it.reset(m_AlnMgr->CreateSegmentIterator(
1541  row, aln_range, IAlnSegmentIterator::eAllSegments));
1542 
1543  for (IAlnSegmentIterator& it = *p_it; it; ++it) {
1544  const IAlnSegment& seg = *it;
1545 
1546  if ( !(seg.GetType() & IAlnSegment::fIndel) ||
1547  seg.GetRange().Empty() ) {
1548  continue;
1549  }
1550 
1551  TSeqPos start = m_AlnMgr->GetSeqPosFromAlnPos(anchor,
1552  seg.GetAlnRange().GetTo(),
1554  start /= base_width_anchor;
1556  len = max(len, kMinLen);
1557  TModelUnit x1 = start + barOff - len * 0.5;
1558  TModelUnit x2 = x1 + len;
1559 
1560  m_Context->DrawLine_NoAA(start + barOff, y1, start + barOff, y2);
1561  m_Context->DrawLine_NoAA(x1, y1, x2, y1);
1562  m_Context->DrawLine_NoAA(x1, y2, x2, y2);
1563  }
1564  } else { // use default scheme
1566  // draw connection line in the middle
1567  m_Context->DrawLine_NoAA(anchor_range.GetFrom(), mid, anchor_range.GetTo(), mid);
1568  TIntervals intervals;
1569  x_CalcIntervals(intervals, row);
1570  ITERATE(TIntervals, it, intervals) {
1571  m_Context->Draw3DQuad(it->GetFrom(), yy, it->GetTo(), yy + bar_h, CRgbaColor(m_Config->m_FG, m_FadeFactor), true);
1572  }
1573  }
1574 
1575  if (m_Context->WillSeqLetterFit()) {
1576  try {
1581  } catch (CException& e) {
1582  LOG_POST(Warning << "Can't show alignment sequence due to an error: "
1583  << e.GetMsg());
1584  }
1585 
1586  } else if (m_Context->WillLabelFit(inrc)) {
1587  // draw strand indicators
1588  // do not draw strand when sequence is shown
1589 
1590  gl.Color4f(0.0f, 0.0f, 0.0f, m_FadeFactor); // Black
1591  gl.Color4f(0.0f, 0.0f, 0.0f, m_FadeFactor); // Black
1592  TModelUnit fs = gl.TextHeight(&(m_Config->m_SeqFont)) - 1;
1593  TModelUnit yM = yy + fs + 1;
1594  char strandLabel[2] = { '>', '\0' };
1595  if (m_Context->IsHorizontal()) {
1596  if (m_Context->IsFlippedStrand()) {
1597  strandLabel[0] = reverse_strand ? '>' : '<';
1598  }
1599  else {
1600  strandLabel[0] = reverse_strand ? '<' : '>';
1601  }
1602  }
1603  else {
1604  if (m_Context->IsFlippedStrand()) {
1605  strandLabel[0] = reverse_strand ? '<' : '>';
1606  }
1607  else {
1608  strandLabel[0] = reverse_strand ? '>' : '<';
1609  }
1610  }
1611 
1612  m_Context->TextOut(&m_Config->m_SeqFont, strandLabel, xM, yM, true);
1613  }
1614 
1615  if (show_label &&
1617  const CGlTextureFont& l_font = m_Config->m_LabelFont;
1618  TModelUnit yM = yy + gl.TextHeight(&l_font);
1620  }
1621  // advance to next row: 1 pixel between
1622  yy += bar_h + kAlignRowSpace;
1623  }
1624 
1625  // Draw selection
1626  if (IsSelected()) {
1627  m_Context->DrawSelection(rcm);
1628  }
1629 }
1630 
1631 
1633 {
1634  IRender& gl = GetGl();
1635 
1636  string label;
1641  label += " (Neg)";
1642  }
1643  const CGlTextureFont& l_font = m_Config->m_LabelFont;
1644 
1645  TModelRange inrc = m_Context->IntersectVisible(this);
1646  TModelUnit max_label_width_px = m_Context->SeqToScreen(inrc.GetLength());
1647  TModelUnit label_w = gl.TextWidth(&l_font, label.c_str());
1648  if (label_w > max_label_width_px) {
1649  label_w = max_label_width_px;
1650  label = l_font.Truncate(label.c_str(), max_label_width_px);
1651  }
1652  bool top_label = m_Config->m_LabelPos == CAlignmentConfig::ePos_Above;
1653  TModelUnit xM = (inrc.GetFrom() + inrc.GetTo()) * 0.5;
1654  if ( !top_label ) {
1655  xM = inrc.GetFrom();
1656  if (inrc.GetFrom() > GetLeft()) {
1658  label_w = m_Context->ScreenToSeq(label_w);
1659  m_Context->DrawBackground( TModelRect(xM, y + 1.0,
1660  xM + label_w, y - gl.TextHeight(&l_font) - 1.0), 0);
1661  }
1662  }
1663 
1664  if (IsSelected()) {
1666  } else {
1668  }
1669  m_Context->TextOut(&l_font, label.c_str(), xM, y, top_label);
1670 }
1671 
1672 
1674  int row,
1675  const CRgbaColor& c_fg,
1676  const CRgbaColor& c_seq,
1677  const CRgbaColor& c_mis) const
1678 {
1679  IRender& gl = GetGl();
1681 
1682  int anchor = m_AlnMgr->GetAnchor();
1683  TSeqPos base_width_anchor = m_AlnMgr->GetBaseWidth(anchor);
1684  TSeqPos base_width_curr = m_AlnMgr->GetBaseWidth(row);
1685  TSeqRange anchor_range(
1686  m_AlnMgr->GetSeqStart(anchor) / base_width_anchor,
1687  m_AlnMgr->GetSeqStop(anchor) / base_width_anchor);
1688  TModelRange inrc = m_Context->IntersectVisible(anchor_range);
1689  anchor_range.Set((TSeqPos)inrc.GetFrom(), (TSeqPos)inrc.GetTo());
1690  if (anchor_range.Empty()) {
1691  return;
1692  }
1693  const CBioseq_Handle& mhndl = m_AlnMgr->GetBioseqHandle(anchor);
1694  if (!mhndl)
1695  return;
1696  const CBioseq_Handle& hndl = m_AlnMgr->GetBioseqHandle(row);
1697  if (!hndl)
1698  return;
1699 
1700  TSignedSeqPos aln_r_s = m_AlnMgr->GetAlnPosFromSeqPos(anchor,
1701  anchor_range.GetFrom() * base_width_anchor, IAlnExplorer::eRight);
1702  TSignedSeqPos aln_r_e = m_AlnMgr->GetAlnPosFromSeqPos(anchor,
1703  anchor_range.GetTo() * base_width_anchor, IAlnExplorer::eLeft);
1704  if (aln_r_s > aln_r_e) {
1705  swap(aln_r_s, aln_r_e);
1706  }
1707  TSignedSeqRange aln_range(aln_r_s, aln_r_e);
1708 
1709  if (aln_range.GetFrom() > 2) {
1710  aln_range.SetFrom(aln_range.GetFrom() - 3);
1711  }
1712 
1713  gl.ColorC(c_fg);
1714 
1715  bool reverse_strand = m_AlnMgr->IsNegativeStrand(row) !=
1716  m_AlnMgr->IsNegativeStrand(anchor);
1717 
1718  unique_ptr<IAlnSegmentIterator> p_it(
1720  aln_range, IAlnSegmentIterator::eSkipGaps));
1721 
1722  bool ab = mhndl.IsAa();
1723  bool rb = hndl.IsAa();
1724  CSeqVector ms_vec =
1726  CSeqVector s_vec =
1728 
1729  EAlignSpacing spacing(eOne2One);
1730  if (!ab && rb) spacing = eOne2Three;
1731  if (ab && !rb) spacing = eThree2One;
1732 
1733  for ( IAlnSegmentIterator& it(*p_it); it; ++it ) {
1734  const IAlnSegment& seg = *it;
1735 
1736  // We need to deal with some tricky genomic-to-protein alignments
1737  // described in both GB-2336 and GB-2324. Sometimes, the insertions
1738  // on the protein sequence row are one-(nucleotide)-base insertions.
1739  // That means two nucleiotide bases on genomic sewquence correspond
1740  // to one residue on the protein sequence at that insertion postion.
1741  // Normally, it one-to-three or three-to-one relation. That introduces
1742  // all sort of troubles including:
1743  // - showing correct sequence
1744  // - positioning the sequence correctly,
1745  // - retrieving the correct chunk of sequences for both protein
1746  // translation and protein-to-genomic comparison
1747 
1748  TSeqPos start = seg.GetRange().GetFrom();
1749  TSeqPos stop = seg.GetRange().GetTo();
1750  TSeqPos sStart = (TModelUnit)m_AlnMgr->GetSeqPosFromAlnPos(anchor, seg.GetAlnRange().GetFrom());
1751  TSeqPos sStop = (TModelUnit)m_AlnMgr->GetSeqPosFromAlnPos(anchor, seg.GetAlnRange().GetTo());
1752 
1753 
1754  TSeqPos frame_shift_f = start % base_width_curr;
1755  TSeqPos frame_shift_t = 2 - stop % base_width_curr;
1756  if (base_width_anchor == 3) {
1757  frame_shift_f = sStart % base_width_anchor;
1758  frame_shift_t = 2 - sStop % base_width_anchor;
1759  }
1760  if (sStart > sStop) {
1761  swap(sStart, sStop);
1762  swap(frame_shift_f, frame_shift_t);
1763  }
1764  stop /= base_width_curr;
1765  start /= base_width_curr;
1766  sStart /= base_width_anchor;
1767  sStop /= base_width_anchor;
1768 
1769  TSeqPos seg_start = sStart;
1770  TSeqPos seg_stop = sStop;
1771 
1772  // Make sure nucleotide coordinate aligns protein codon's
1773  // starting/ending base. We need to do protein
1774  if (spacing == eOne2Three) {
1775  // top/anchor sequence is nucleotide, and and aligned sequence
1776  // is protein.
1777  sStop += frame_shift_t;
1778  sStart -= frame_shift_f;
1779  } else if (spacing == eThree2One) {
1780  // make sure it aligns codon's starting base
1781  stop += frame_shift_t;
1782  start -= frame_shift_f;
1783  }
1784 
1785  // check if sStop is larger than the sequence lenght
1786  sStop = min(sStop, mhndl.GetBioseqLength());
1787 
1788  try {
1789 
1790  string seq, mseq, tmp_seq, visible_seq;
1791  s_vec.GetSeqData (start, stop + 1, tmp_seq);
1792  ms_vec.GetSeqData(sStart, sStop + 1, mseq);
1793  visible_seq = tmp_seq;
1794 
1795  if (reverse_strand) {
1796 
1797  if (rb) {
1798  // protein sequence, just reverse it
1799  CSeqManip::Reverse(tmp_seq, CSeqUtil::e_Iupacaa, 0, static_cast<TSeqPos>(tmp_seq.length()), seq);
1800  visible_seq = seq;
1801  } else {
1802  // nucleotide sequence, get reverse and complement
1803  CSeqManip::ReverseComplement(tmp_seq, CSeqUtil::e_Iupacna, 0, static_cast<TSeqPos>(tmp_seq.length()), seq);
1804 
1805  if (m_Context->IsFlippedStrand()) {
1806  CSeqManip::Reverse(tmp_seq, CSeqUtil::e_Iupacna, 0, static_cast<TSeqPos>(tmp_seq.length()), visible_seq);
1807  } else {
1808  visible_seq = seq;
1809  }
1810 
1811  }
1812 
1813  } else {
1814  if (!rb && m_Context->IsFlippedStrand()) {
1815  CSeqManip::Complement(tmp_seq, CSeqUtil::e_Iupacna, 0, static_cast<TSeqPos>(tmp_seq.length()), visible_seq);
1816  }
1817  swap(seq, tmp_seq);
1818  }
1819  string translated_seq;
1820  switch (spacing) {
1821  case eOne2Three:
1822  {
1823  string seq_candidate = mseq;
1824  if (reverse_strand) {
1825  CSeqManip::ReverseComplement(mseq, CSeqUtil::e_Iupacna, 0, static_cast<TSeqPos>(mseq.length()), seq_candidate);
1826  }
1827  CGenetic_code gcode;
1828  gcode.SetId(m_AlnMgr->GetGenCode(anchor));
1829  CSeqTranslator::Translate(seq_candidate, translated_seq, CSeqTranslator::fIs5PrimePartial, &gcode);
1830  if (reverse_strand) {
1831  // don't use the same string as the input and output string.
1832  CSeqManip::Reverse(translated_seq, CSeqUtil::e_Iupacaa, 0, static_cast<TSeqPos>(translated_seq.length()), tmp_seq);
1833  translated_seq = tmp_seq;
1834  }
1835  }
1836  break;
1837  case eThree2One:
1838  {
1839  auto r = seg.GetAlnRange();
1840  r.SetFrom(r.GetFrom() - frame_shift_f);
1841  r.SetTo(r.GetTo() + frame_shift_t);
1842  m_AlnMgr->GetAlnSeqString(row, seq, r);
1843  CGenetic_code gcode;
1844  gcode.SetId(m_AlnMgr->GetGenCode(row));
1845  CSeqTranslator::Translate(seq, translated_seq, CSeqTranslator::fIs5PrimePartial, &gcode);
1846  }
1847  break;
1848  default:
1849  break;
1850  }
1851 
1852  char bases[2];
1853  bases[1] = '\0';
1854  TVPUnit font_w =
1855  (TVPUnit)(gl.TextWidth(&(m_Config->m_SeqFont),"G") * 0.5f);
1856  TModelUnit addon = 0.5 - m_Context->ScreenToSeq(font_w);
1857 
1858  TSeqPos start_base = frame_shift_f % base_width_anchor;
1859  TSeqPos stop_base = min(stop - start + 1 - frame_shift_t % base_width_anchor,
1860  (TSeqPos)seq.length());
1861 
1862  // Draw characters (actg)
1863  for (TSeqPos bp = start_base; bp < stop_base; bp++) {
1864  TModelUnit pos = 0;
1865  bool match = true;
1866  switch (spacing) {
1867  case eOne2One:
1868  pos = sStart + bp + addon;
1869  match = bp < seq.size() && bp < mseq.size()
1870  && seq[bp] == mseq[bp];
1871  break;
1872  case eOne2Three:
1873  pos = sStart + bp * 3 + addon + 1;
1874  match = bp < seq.size() && bp < translated_seq.size()
1875  && seq[bp] == translated_seq[bp];
1876  break;
1877  case eThree2One: {
1878  pos = sStart + bp * kPWAlignPackLevel + addon - kPWAlignPackLevel;
1879  int bp_pos = bp / 3;
1880  match = bp_pos < seq.size() && bp_pos < translated_seq.size()
1881  && mseq[bp_pos] == translated_seq[bp_pos];
1882  break;
1883  }
1884  default:
1885  break;
1886  }
1887  if (pos < (seg_start - 0.5))
1888  continue;
1889  if (pos > (seg_stop + 1))
1890  continue;
1891 
1892  // Highlight mismatch?
1893  match ? gl.ColorC(c_seq) : gl.ColorC(c_mis);
1894  if (match && !m_Config->m_ShowIdenticalBases) {
1895  CRgbaColor c = c_seq;
1896  c.Lighten(0.65f);
1897  gl.ColorC(c);
1898  TModelUnit bh = GetBarHeight();
1899  m_Context->DrawDisk2(TModelPoint(pos, center_y), (bh / 2.0) + 0.5, c);
1900  }
1901  else {
1902  // set scoring if avaliable
1903  if (m_Score && m_Score->HasScores()) {
1904  if (m_Score->GetSupportedColorTypes() & IScoringMethod::fForeground) {
1905  unique_ptr<IAlnScoreIterator> score_iter(m_Score->GetScoreIterator(row));
1906  score_iter->MoveTo(bp);
1907  IScoringMethod::TScore score = score_iter->GetAttr();
1908  CRgbaColor cl = m_Score->GetColorForScore(score,
1910  cl.SetAlpha(m_FadeFactor);
1911  gl.ColorC(cl); // use scoreing color
1912  }
1913  else {
1914  gl.ColorC(c_seq); // use default color
1915  }
1916  }
1917 
1918  bases[0] = visible_seq[bp];
1919 
1920  m_Context->TextOut(&m_Config->m_SeqFont, bases,
1921  pos, center_y + fs * 0.5, false);
1922  }
1923  } // for TSeqPos
1924  }
1925  catch (CException&) {
1926  /// ignore exceptions - these are all objmgr related
1927  }
1928  } // for i = 0
1929 
1930  if (IsLastRow()) {
1931  gl.ColorC(CRgbaColor(c_seq, 1.0f));
1932  const char* long_msg = (GetTearline() < eMaxRowLimit) ?
1933  "Alignment rows truncated for 'Adaptive' display - select 'Show All' to see more"
1934  : "The number of alignment rows exceeds the supported limit";
1935  const char* short_msg = (GetTearline() < eMaxRowLimit) ?
1936  "Select 'Show All' to see all alignments"
1937  : "Number of rows exceeds limit";
1938  const char* char_msg = "X";
1939  TModelUnit long_msg_width = gl.TextWidth(&m_Config->m_LabelFont, long_msg);
1940  TModelUnit short_msg_width = gl.TextWidth(&m_Config->m_LabelFont, short_msg);
1941  TModelUnit char_msg_width = gl.TextWidth(&m_Config->m_LabelFont, char_msg);
1942 
1944  TModelUnit seq_char_width = m_Context->ScreenToSeq(char_msg_width);
1945 
1946  const char* msg = NULL;
1947  TModelUnit msg_width = 0.0;
1948 
1949  if (width > long_msg_width) {
1950  msg = long_msg;
1951  msg_width = long_msg_width;
1952  }
1953  else if (width > short_msg_width) {
1954  msg = short_msg;
1955  msg_width = short_msg_width;
1956  }
1957  else if (width > char_msg_width) {
1958  msg = char_msg;
1959  msg_width = char_msg_width;
1960  }
1961  else {
1962  }
1963 
1964  TModelUnit msg_spacing = char_msg_width * 4.0;
1965 
1966  if (msg != NULL) {
1967  // Only room for the message - no filler on the sides
1968  if (width < msg_width + msg_spacing*2.0) {
1969  TModelUnit w = (width - msg_width)*0.5;
1971  GetLeft() + m_Context->ScreenToSeq(w), center_y + fs * 0.5, false);
1972  }
1973  // Room for message + filler:
1974  else {
1975  TModelUnit w = (width - msg_width)*0.5;
1976  TModelUnit seq_w = m_Context->ScreenToSeq(w);
1977 
1979  GetLeft() + m_Context->ScreenToSeq(w), center_y + fs * 0.5, false);
1980 
1981  // Draw jagged lines on either side of the message
1982  gl.Color3f(0.5, 0.5, 0.5f);
1983  vector<TModelPoint> pts;
1984  bool bottom_y = true;
1985  TModelUnit pos = GetLeft();
1986  while (pos < GetLeft() + seq_w - seq_char_width) {
1987  if (bottom_y)
1988  pts.push_back(TModelPoint(pos, center_y + fs * 0.5));
1989  else
1990  pts.push_back(TModelPoint(pos, center_y - fs * 0.5));
1991 
1992  bottom_y = !bottom_y;
1993  pos += seq_char_width;
1994  }
1995  m_Context->DrawLineStrip(pts);
1996  pts.clear();
1997 
1998  bottom_y = true;
1999  pos = GetRight();
2000  while (pos > GetRight() - (seq_w - seq_char_width)) {
2001  if (bottom_y)
2002  pts.push_back(TModelPoint(pos, center_y + fs * 0.5));
2003  else
2004  pts.push_back(TModelPoint(pos, center_y - fs * 0.5));
2005 
2006  bottom_y = !bottom_y;
2007  pos -= seq_char_width;
2008  }
2009  m_Context->DrawLineStrip(pts);
2010  }
2011  }
2012  }
2013 }
2014 
2015 // Scoring structures/functions start
2016 /// represents a pixel with a score, if several intervals cover a pixel, the interval
2017 /// with the maximum coverage will "own" the pixel (i.e. the pixel will be colored
2018 /// according to the score of this interval)
2019 /// This is used for non-averageable scores.
2020 struct SScPix {
2021  float m_Score; /// score assigned to the pixel
2022  float m_MaxCoverage; /// fraction of the pixel corresponding to the m_Score
2023  bool m_Gap; /// true if this is a gap interval
2024 
2025  bool operator==(const SScPix& other) const
2026  {
2027  return m_Score == other.m_Score &&
2028  m_MaxCoverage == other.m_MaxCoverage &&
2029  m_Gap == other.m_Gap;
2030  }
2031 };
2032 
2033 
2034 /// a pixel with the Max coverage (fraction) overrides all attributes
2035 static void FSetPixMaxCoverage(SScPix& dst, const SScPix& src,
2036  float fraction, bool)
2037 {
2038  if(fraction > dst.m_MaxCoverage) {
2039  dst.m_Score = src.m_Score;
2040  dst.m_Gap = src.m_Gap;
2041  dst.m_MaxCoverage = fraction;
2042  }
2043 }
2044 
2045 
2047  TSignedSeqRange aln_range,
2048  TSeqRange seq_range,
2049  TModelUnit height,
2050  int row,
2051  bool override_color,
2052  const CRgbaColor& read_status_color) const
2053 {
2054  IRender& gl = GetGl();
2055 
2056  TModelUnit fromM = (TModelUnit)seq_range.GetFrom();
2057  TModelUnit toM = (TModelUnit)seq_range.GetToOpen();
2058  int anchor = m_AlnMgr->GetAnchor();
2059  TSeqPos base_width_anchor = m_AlnMgr->GetBaseWidth(anchor);
2060 
2061  // coloration range in the viewport coordinate system
2062  TVPUnit scoreStart = m_Context->SeqToScreenX(fromM);
2063  TVPUnit scoreEnd = m_Context->SeqToScreenX(toM);
2064 
2065  typedef CRasterizer<SScPix> TR;
2066  TR rasterizer(scoreStart, scoreEnd, fromM, toM);
2067  SScPix pix = { 0.0f, 0.0f, false };
2068 
2069  unique_ptr<IAlnScoreIterator> score_iter(m_Score->GetScoreIterator(row));
2070  IAlnScoreIterator& it = *score_iter;
2071  unique_ptr<IAlnSegmentIterator> p_it(m_AlnMgr->CreateSegmentIterator(row,
2072  aln_range, IAlnSegmentIterator::eSkipGaps));
2073 
2074  IAlnSegmentIterator& aln_seg_it(*p_it);
2075  while (aln_seg_it && it) {
2076  const IAlnSegment& seg = *aln_seg_it;
2077  const TSignedSeqRange& r = seg.GetAlnRange();
2078 
2079  TSignedSeqPos start1 = r.GetFrom();
2080  TSignedSeqPos stop1 = r.GetTo();
2081  TSignedSeqPos start2 = it.GetFrom();
2082  TSignedSeqPos stop2 = it.GetTo();
2083 
2084  while (it && start1 > stop2) {
2085  ++it;
2086  start2 = it.GetFrom();
2087  stop2 = it.GetTo();
2088  }
2089 
2090  if (start1 > stop2) {
2091  break;
2092  }
2093 
2094  int from, to;
2095  from = std::max<int>(start1, start2);
2096  to = std::min<int>(stop1, stop2);
2097 
2098  TModelUnit act_from = m_AlnMgr->GetSeqPosFromAlnPos(anchor, from);
2099  act_from /= base_width_anchor;
2100  TModelUnit act_to = m_AlnMgr->GetSeqPosFromAlnPos(anchor, to);
2101  act_to /= base_width_anchor;
2102  if (act_from > act_to) {
2103  swap(act_from, act_to);
2104  }
2105 
2106  if (act_from <= act_to) {//! seg.IsGap()) {
2107  pix.m_Score = it.GetAttr();
2108  pix.m_Gap = seg.IsGap();
2109  rasterizer.AddInterval(act_from, act_to + 1.0 / base_width_anchor, pix, FSetPixMaxCoverage);
2110  }
2111 
2112  /// advance iterators
2113  if (to == stop1) {
2114  ++aln_seg_it;
2115  }
2116  if (to == stop2) {
2117  ++it;
2118  }
2119  }
2120 
2121  // Rendering
2122  const TR::TRaster& raster = rasterizer.GetRaster();
2123  static float eps = 0.0001f;
2124  double shift_x = scoreStart;
2125 
2126  gl.PushMatrix();
2127  gl.Scalef(m_Context->GetScale(), 1.0f, 1.0f);
2128  for (size_t i = 0; i < raster.size(); ) {
2129  double start = i + shift_x;
2130  const SScPix& sc_pix = raster[i];
2131  while (++i < raster.size() && raster[i] == sc_pix);
2132 
2133  if (sc_pix.m_MaxCoverage > eps) {
2134  CRgbaColor color = m_Score->GetColorForScore(
2136  if (override_color)
2137  color = read_status_color;
2138 
2139  // Lighten color if we are fading out (instead of using
2140  // blending which we don't want for the rectanges which should
2141  // overwrite (not blend with) what is behind them.
2142  if (m_FadeFactor < 1.0f)
2143  color.Lighten(1.0 - m_FadeFactor);
2144  gl.ColorC(color);
2145 
2146  // vertical offset from the border of the alignment band
2147  // to the border of gap band
2148  int GapOffset = 2;
2149  int off_y = sc_pix.m_Gap ? GapOffset : 0;
2150 
2151  double x2 = i + shift_x;
2152  if (start == x2) {
2153  gl.Begin(GL_LINES);
2154  gl.Vertex2d(start, yy + off_y);
2155  gl.Vertex2d(start, yy + height - off_y);
2156  gl.End();
2157  } else {
2158  gl.Rectd(start, yy + off_y, x2, yy + height - off_y);
2159  }
2160  }
2161  }
2162  gl.PopMatrix();
2163 }
2164 
2165 
2166 struct SScPix2 {
2167  float m_IntScore;
2168  float m_IntLen;
2169  float m_GapScore;
2170  float m_GapLen;
2171  float m_MinScore;
2172  bool m_Init;
2173 
2174  bool operator==(const SScPix2& other) const
2175  {
2176  return m_IntScore == other.m_IntScore && m_IntLen == other.m_IntLen &&
2177  m_GapScore == other.m_GapScore && m_GapLen == other.m_GapLen &&
2178  m_MinScore == other.m_MinScore;
2179  }
2180 };
2181 
2182 
2183 /// accumulate weighted scores
2184 static void FSetPix2(SScPix2& dst, const SScPix2& src, float fraction, bool long_seg)
2185 {
2186  dst.m_IntScore += src.m_IntScore * fraction;
2187  dst.m_IntLen += src.m_IntLen * fraction;
2188  dst.m_GapScore += src.m_GapScore * fraction;
2189  dst.m_GapLen += src.m_GapLen * fraction;
2190 
2191  if( ! long_seg) {
2192  // only for small segments
2193  static const float eps = 0.00001f;
2194  if( ! dst.m_Init) {
2195  if(src.m_IntLen > eps) {
2196  dst.m_MinScore = src.m_IntScore;
2197  dst.m_Init = true;
2198  } else if(src.m_GapLen > eps) {
2199  dst.m_MinScore = src.m_GapScore;
2200  dst.m_Init = true;
2201  }
2202  } else {
2203  if(src.m_IntLen > eps) {
2204  dst.m_MinScore = min(dst.m_MinScore, src.m_IntScore);
2205  }
2206  if(src.m_GapLen > eps) {
2207  dst.m_MinScore = min(dst.m_MinScore, src.m_GapScore);
2208  }
2209  }
2210  }
2211 }
2212 
2213 
2215  TSignedSeqRange aln_range,
2216  TSeqRange seq_range,
2217  TModelUnit height,
2218  int row,
2219  bool override_color,
2220  const CRgbaColor& read_status_color) const
2221 {
2222  if (seq_range.Empty())
2223  return;
2224 
2225  IRender& gl = GetGl();
2226 
2227  TModelUnit fromM = (TModelUnit)seq_range.GetFrom();
2228  TModelUnit toM = (TModelUnit)seq_range.GetToOpen();
2229  int anchor = m_AlnMgr->GetAnchor();
2230  TSeqPos base_width_anchor = m_AlnMgr->GetBaseWidth(anchor);
2231 
2232  // coloration range in the viewport coordinate system
2233  TVPUnit scoreStart = m_Context->SeqToScreenXInModelUnit(fromM);
2234  TVPUnit scoreEnd = TVPUnit(ceil(m_Context->SeqToScreenXInModelUnit(toM)));
2235 
2236  typedef CRasterizer<SScPix2> TR;
2237  TR rasterizer(scoreStart, scoreEnd, fromM, toM);
2239  unique_ptr<IAlnScoreIterator> score_it(m_Score->GetScoreIterator(row));
2240  IAlnScoreIterator& it = *score_it;
2241  unique_ptr<IAlnSegmentIterator> p_it(m_AlnMgr->CreateSegmentIterator(row,
2242  aln_range, IAlnSegmentIterator::eAllSegments));
2243 
2244  IAlnSegmentIterator& aln_seg_it(*p_it);
2245  while (aln_seg_it && it) {
2246  const IAlnSegment& seg = *aln_seg_it;
2247  const TSignedSeqRange& r = seg.GetAlnRange();
2248 
2249  TSignedSeqPos start1 = r.GetFrom();
2250  TSignedSeqPos stop1 = r.GetTo();
2251  TSignedSeqPos start2 = it.GetFrom();
2252  TSignedSeqPos stop2 = it.GetTo();
2253 
2254  while (it && start1 > stop2) {
2255  ++it;
2256  if (it) {
2257  start2 = it.GetFrom();
2258  stop2 = it.GetTo();
2259  }
2260  }
2261 
2262  if (start1 > stop2) {
2263  break;
2264  }
2265 
2266  TSignedSeqPos from, to;
2267  from = std::max<int>(start1, start2);
2268  to = std::min<int>(stop1, stop2);
2269 
2270  SScPix2 pix = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, false };
2272  act_from /= base_width_anchor;
2274  act_to /= base_width_anchor;
2275  if (act_from > act_to) {
2276  swap(act_from, act_to);
2277  }
2278  if (act_from <= act_to && act_from <=toM) {
2279  if (seg.IsAligned()) {
2280  pix.m_IntLen = 1.;
2281  pix.m_IntScore = it.GetAttr();
2282  if (pix.m_IntScore < value_limits.GetFrom())
2283  value_limits.SetFrom(pix.m_IntScore);
2284  else if (pix.m_IntScore > value_limits.GetTo())
2285  value_limits.SetTo(pix.m_IntScore);
2286  rasterizer.AddInterval(act_from, act_to + 1.0 / base_width_anchor, pix, FSetPix2);
2287  //} else if (seg.IsIndel()) {
2288  //++aln_seg_it;
2289  //continue;
2290  } else if (seg.IsIndel() || seg.IsGap()) {
2291  int len = (act_to - act_from) + 1;// / base_width_anchor;
2292  if (m_Context->SeqToScreen(len) <= 1.5) {
2293  pix.m_GapLen = 1.;
2294  pix.m_GapScore = it.GetAttr();
2295  rasterizer.AddInterval(act_from, act_to + 1.0 / base_width_anchor, pix, FSetPix2);
2296  }
2297  }
2298  }
2299 
2300  /// advance iterators
2301  if (to == stop1) {
2302  ++aln_seg_it;
2303  }
2304  if (to == stop2) {
2305  ++it;
2306  }
2307  }
2308 
2309  // Rendering
2310  gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
2311 
2312  const TR::TRaster& raster = rasterizer.GetRaster();
2313 
2314  double barh = abs(m_Context->GetGlPane()->GetScaleY() * height);
2315 
2316  double shift_x = scoreStart;
2317  static const float eps = 0.001f;
2318  float value_scale = value_limits.GetTo() - value_limits.GetFrom();
2319  if (value_scale <= 0)
2320  value_scale = 1;
2321  gl.PushMatrix();
2322  gl.Scalef(m_Context->GetScale(), 1.0f, 1.0f);
2323  for (size_t i = 0; i < raster.size(); ) {
2324  double start = i + shift_x;
2325  const SScPix2& sc_pix = raster[i];
2326  while (++i < raster.size() && raster[i] == sc_pix);
2327  CRgbaColor color = m_Score->GetColorForScore(sc_pix.m_MinScore, IScoringMethod::fBackground);
2328  bool draw = false;
2329  if (sc_pix.m_IntLen > eps) {
2330  draw = true;
2331  float sc = sc_pix.m_IntScore / sc_pix.m_IntLen;
2332  //float sc = min(1.0f, float(sc_pix.m_IntScore / sc_pix.m_IntLen));
2333  color = override_color ?
2334  read_status_color : m_Score->GetColorForScore(sc, IScoringMethod::fBackground);
2335  if (sc_pix.m_Init) {
2336  sc = min(1.0f, ((sc - value_limits.GetFrom()) / value_scale));
2337  CRgbaColor color2 = m_Score->GetColorForScore(sc_pix.m_MinScore,
2339  float alpha = 1.0f - sc * 0.75f;
2340  color = CRgbaColor::Interpolate(color2, color, alpha);
2341  }
2342  // m_GapLen is and insertion length
2343  if (sc_pix.m_GapLen > eps) {
2344  //float sc = min(1.0f, sc_pix.m_GapScore / sc_pix.m_GapLen);
2345  // make lower score more prominent
2346  float alpha = min(1.0f, 0.25f + sc_pix.m_GapLen * 0.75f);
2348  }
2349  }
2350  if (draw) {
2351  color.Lighten(1.0 - color.GetAlpha() * m_FadeFactor);
2352  gl.Color4d(color.GetRed(), color.GetGreen(), color.GetBlue(), color.GetAlpha()*m_FadeFactor);
2353  double x2 = i + shift_x;
2354  if (start == x2) {
2355  gl.Begin(GL_LINES);
2356  gl.Vertex2d(start, yy);
2357  gl.Vertex2d(start, yy + height);
2358  gl.End();
2359  } else {
2360 
2361  if (barh >= 2.) {
2362  gl.Rectd(start, yy, x2, yy + height);
2363  } else {
2364  // if bar height is less than 2px
2365  // blue thin line that goes through the whole
2366  // alignment glyph occasianally gets visible
2367  // when rendered by MESA (blue band issue).
2368  // Setting linewidth to 2 fixes that
2369 
2370  gl.LineWidth(2);
2371  gl.Begin(GL_LINES);
2372  gl.Vertex2d(start, yy);
2373  gl.Vertex2d(x2, yy);
2374  gl.End();
2375  gl.LineWidth(1.);
2376  }
2377  }
2378  }
2379 
2380  }
2381  gl.PopMatrix();
2382 }
2383 
2384 static float kMinSegDistance = 1.5f;
2385 
2386 void CAlignGlyph::x_CalcIntervals(TIntervals& intervals, int target_row) const
2387 {
2388  intervals.clear();
2389 
2390  int anchor = m_AlnMgr->GetAnchor();
2391  TSeqPos base_width_anchor = m_AlnMgr->GetBaseWidth(anchor);
2392  TSeqRange r(
2393  m_AlnMgr->GetSeqStart(anchor) / base_width_anchor,
2394  m_AlnMgr->GetSeqStop(anchor) / base_width_anchor);
2395 
2396  if (r.Empty()) {
2397  LOG_POST(Error
2398  << "CAlignGlyph::x_CalcIntervals: zero alignment range!");
2399  return;
2400  }
2401 
2402  {
2404  if (inrc.Empty())
2405  return;
2406  //r.SetOpen((TSeqPos)inrc.GetFrom(), (TSeqPos)inrc.GetToOpen());
2407  //if (r.Empty())
2408  // return;
2409  }
2410  // optimization
2411  // Only use the total range if the size is small
2412  if (IsSimplified()) {
2413  intervals.push_back(r);
2414  return;
2415  }
2417  anchor, r.GetFrom() * base_width_anchor, IAlnExplorer::eRight);
2419  anchor, r.GetTo() * base_width_anchor, IAlnExplorer::eLeft);
2420  if (aln_r_s > aln_r_e) {
2421  swap(aln_r_s, aln_r_e);
2422  }
2423  CRange<TSignedSeqPos> aln_range(aln_r_s, aln_r_e);
2424 
2425  int row = target_row;
2426  if (row < 0)
2427  row = max(0, 1 - anchor);
2428 
2429  unique_ptr<IAlnSegmentIterator> p_it(m_AlnMgr->CreateSegmentIterator(row,
2430  aln_range,
2432  TSeqRange rrr;
2433  for ( IAlnSegmentIterator& it(*p_it); it; ++it ) {
2434  const IAlnSegment& seg = *it;
2435  if (seg.GetRange().Empty())
2436  continue;
2437  if (!seg.IsAligned() || seg.IsIndel())
2438  continue;
2439  const TSignedSeqRange& aln_r = seg.GetAlnRange();
2440  if (aln_r.Empty())
2441  continue;
2442  TSeqPos start = m_AlnMgr->GetSeqPosFromAlnPos(anchor, aln_r.GetFrom());
2443  start /= base_width_anchor;
2444  TSeqPos stop = m_AlnMgr->GetSeqPosFromAlnPos(anchor, aln_r.GetTo());
2445  stop /= base_width_anchor;
2446  if (start > stop)
2447  swap(start, stop);
2448  bool add = true;
2449  if (!intervals.empty()) {
2450  TModelUnit dist = m_Context->SeqToScreen(start - intervals.back().GetTo());
2451  if (dist < kMinSegDistance) {
2452  intervals.back().SetTo(stop);
2453  add = false;
2454  }
2455  }
2456  if (add)
2457  intervals.push_back( TSeqRange(start, stop) );
2458  }
2459 }
2460 
2462 {
2463  bool shown = false;
2464  if (m_Config->m_ShowLabel &&
2468  if (m_Context->WillLabelFit(r)) {
2469  shown = true;
2470  }
2471  } else {
2472  shown = true;
2473  }
2474  }
2475  return shown;
2476 }
2477 
2478 
2480 {
2481  return !m_Context->IsOverviewMode() && m_Score && m_Score->HasScores();
2482 }
2483 
2484 
2486 {
2487  // Only for pairwise alignments with a minimal screen size
2489  !m_Context->IsOverviewMode() &&
2490  align_len > kTailGlyphLen &&
2492  (m_Config->m_ShowUnalignedTailsForTrans2GenomicAln && m_SeqAlign->GetSegs().IsSpliced())) &&
2493  x_IsPWAlign();
2494 }
2495 
2497 {
2498  if (e5_Prime == tail)
2499  return TSeqRange(ctx.f - ctx.tail_5*ctx.base_width_curr, ctx.f - 1);
2500  else
2501  return TSeqRange(ctx.t + 1, ctx.t + ctx.tail_3*ctx.base_width_curr);
2502 }
2503 
2505 {
2506  int aligned_seq = m_AlnMgr->GetQuery();
2507  TSignedSeqPos aln_start = m_AlnMgr->GetSeqStart(aligned_seq) / ctx.base_width_curr;
2508  TSignedSeqPos aln_stop = m_AlnMgr->GetSeqStop(aligned_seq) / ctx.base_width_curr;
2509 
2510  if (ctx.reverse_strand) {
2511  if (e5_Prime == tail) {
2512  TSignedSeqPos start = (ctx.f - aln_range.GetToOpen()) / ctx.base_width_curr;
2513  start *= ctx.base_width_anchor;
2514  start += aln_stop + 1;
2515  TSignedSeqPos end = (ctx.f - aln_range.GetFrom()) / ctx.base_width_curr;
2516  end *= ctx.base_width_anchor;
2517  end += aln_stop + 1;
2518  return TSeqRange(start, end);
2519  }
2520  else { // e3_Prime
2521  TSignedSeqPos start = (aln_range.GetToOpen() - ctx.t - 1) / ctx.base_width_curr;
2522  start *= ctx.base_width_anchor;
2523  start = aln_start - start;
2524  TSignedSeqPos end = (aln_range.GetFrom() - ctx.t - 1) / ctx.base_width_curr;
2525  end *= ctx.base_width_anchor;
2526  end = aln_start - end;
2527  return TSeqRange(start, end);
2528  }
2529  }
2530  else {
2531  if (e5_Prime == tail) {
2532  TSignedSeqPos start = (aln_range.GetFrom() - ctx.f) / ctx.base_width_curr;
2533  start *= ctx.base_width_anchor;
2534  start += aln_start;
2535  TSignedSeqPos end = (aln_range.GetToOpen() - ctx.f) / ctx.base_width_curr;
2536  end *= ctx.base_width_anchor;
2537  end += aln_start;
2538  return TSeqRange(start, end);
2539  }
2540  else { // e3_Prime
2541  TSignedSeqPos start = (aln_range.GetFrom() - ctx.t) / ctx.base_width_curr;
2542  start *= ctx.base_width_anchor;
2543  start += aln_stop;
2544  TSignedSeqPos end = (aln_range.GetToOpen() - ctx.t) / ctx.base_width_curr;
2545  end *= ctx.base_width_anchor;
2546  end += aln_stop;
2547  return TSeqRange(start, end);
2548  }
2549  }
2550 }
2551 
2553 {
2554  IRender& gl = GetGl();
2555 
2556  TModelUnit h_text = gl.TextHeight(&m_Config->m_LabelFont);
2557  if (h_text >= GetBarHeight())
2558  return 0.0;
2559 
2560  string len_str = NStr::IntToString(tail, NStr::fWithCommas);
2561  return m_Context->ScreenToSeq(gl.TextWidth(&m_Config->m_LabelFont, len_str.c_str()));
2562 }
2563 
2564 TModelUnit CAlignGlyph::x_GetTailWidth(const TSignedSeqPos tail, const TSignedSeqPos visible_tail, const TSignedSeqPos base_width_curr) const
2565 {
2566  TModelUnit tail_len = 0;
2567  TModelUnit tail_label_len = 0;
2568  TModelUnit bar_h = GetBarHeight();
2569  bool compact = (GetBarHeight() <= 2); // tiny bars, compact mode
2570 
2571  int label_space_pix = compact ? kCompactLabelSpace_h : kLabelSpace_h;
2572  int tail_len_pix = compact ? kCompactTailGlyphLen : kTailGlyphLen;
2573  tail_len_pix += label_space_pix;
2574 
2575  switch (m_Config->m_UnalignedTailsMode) {
2577  // Preserve horizontal space for the unaligned tail glyph
2578  tail_len = m_Context->ScreenToSeq(tail_len_pix);
2579  tail_label_len = x_GetTailLabelWidth(tail);
2580  if (tail_label_len > 0) {
2581  // Preserve horizontal space for the unaligned tail length label
2582  tail_len += tail_label_len + m_Context->ScreenToSeq(label_space_pix);
2583  }
2584  break;
2586  // Preserve space for the unaligned sequence
2587  tail_len = visible_tail*base_width_curr;
2588  if (visible_tail < tail) { // The visible unaligned sequence is truncated
2589  // Preserve horizontal space for the unaligned tail glyph
2590  tail_len += m_Context->ScreenToSeq(tail_len_pix);
2591  tail_label_len = x_GetTailLabelWidth(tail - visible_tail);
2592  if (tail_label_len > 0) {
2593  // Preserve horizontal space for the unaligned tail length label
2594  tail_len += tail_label_len + m_Context->ScreenToSeq(label_space_pix);
2595  }
2596  }
2597  break;
2598  default:
2599  break;
2600  }
2601  return tail_len;
2602 }
2603 
2605 {
2606  try {
2607  int aligned_seq = m_AlnMgr->GetAnchor() == 0 ? 1 : 0;
2609  string id_str = shdl.GetSeqId()->AsFastaString();
2610  return ((id_str.find("gnl|SRA") != string::npos) && (CSeqUtils::IsVDBAccession(m_OrigSeqAlign.GetAnnot().GetName())));
2611  }
2612  catch (const CException&) {
2613 
2614  }
2615  return false;
2616 }
2617 
2618 void CAlignGlyph::x_GetOverrideColor(bool& override_color,
2619  CRgbaColor& read_status_color) const
2620 {
2621  // Special colors for sra reads with errors: failed reads red,
2622  // pcr duplicates pale gray. SV-2153
2623  override_color = false;
2624 
2625  if (m_SeqAlign->IsSetExt()) {
2626  const CSeq_align_Base::TExt& exts = m_SeqAlign->GetExt();
2627  ITERATE (CSeq_align_Base::TExt, iter, exts) {
2628  if ((*iter)->GetType().IsStr() &&
2629  (*iter)->GetType().GetStr() == "PCR duplicate") {
2630  override_color = true;
2631  read_status_color.Set(0.9f, 0.67f, 0.9f, m_FadeFactor);
2632  }
2633  if ((*iter)->GetType().IsStr() &&
2634  (*iter)->GetType().GetStr() == "Poor sequence quality") {
2635  override_color = true;
2636  read_status_color.Set(1.0f, 0.17f, 0.0f, m_FadeFactor);
2637  }
2638  }
2639  }
2640 }
2641 
2642 bool CAlignGlyph::LessBySeqPos(const CSeqGlyph& obj) const
2643 {
2644  const CAlignGlyph* align = dynamic_cast<const CAlignGlyph*>(&obj);
2645  if (align) try {
2646  int anchor1 = align->GetAlignMgr().GetAnchor();
2647  int from1 = align->GetAlignMgr().GetSeqStart(anchor1);
2648 
2649  int anchor0 = m_AlnMgr->GetAnchor();
2650  int from0 = m_AlnMgr->GetSeqStart(anchor0);
2651  if (from0 < from1)
2652  return true;
2653  if (from0 > from1)
2654  return false;
2655  int to1 = align->GetAlignMgr().GetSeqStop(anchor1);
2656  int to0 = m_AlnMgr->GetSeqStop(anchor0);
2657  return to0 < to1;
2658  } catch (CException&) {
2659  }
2660  // otherwise, using default, compare by SeqRanges
2661  return CSeqGlyph::LessBySeqPos(obj);
2662 }
2663 
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
T round(const T &v)
USING_SCOPE(objects)
double CompressLength(double len)
static void FSetPixMaxCoverage(SScPix &dst, const SScPix &src, float fraction, bool)
a pixel with the Max coverage (fraction) overrides all attributes
static const int kCompactLabelSpace_h
static const TSeqPos kTailGlyphLen
static float kMinSegDistance
static const int kLabelSpace_v
static const int kAlignRowSpace
static void FSetPix2(SScPix2 &dst, const SScPix2 &src, float fraction, bool long_seg)
accumulate weighted scores
static const TSeqPos kCompactTailGlyphLen
static const int kLabelSpace_h
static const TModelUnit kPWAlignPackLevel
ELabelPosition m_LabelPos
@ eNormal
no compact mode
@ eExtremeCompact
extreme compact mode
CRgbaColor m_SeqMismatch
CRgbaColor m_TailColor
CGlTextureFont m_LabelFont
CRgbaColor m_Sequence
CRgbaColor m_Insertion
CGlTextureFont m_SeqFont
ECompactMode m_CompactMode
Alignment layout compact mode.
CRgbaColor m_UnalignedSequence
bool m_ShowUnalignedTailsForTrans2GenomicAln
CRgbaColor m_UnalignedFG
CRgbaColor m_NonConsensus
EUnalignedTailsMode m_UnalignedTailsMode
@ ePos_Above
above the rendered bar
@ ePos_Side
always on 5' side
@ ePos_NoLabel
no label
CBioseq_Handle –.
void SetId(int)
CGlAttrGuard - guard class for restoring OpenGL attributes.
Definition: glutils.hpp:130
@ fNoCaching
The tooltip for this feature should not be cached.
int m_Flags
area flags, will need to replace m_Type
bool m_PositiveStrand
the default is true
static string GetAlignSignature(const objects::CSeq_align &align, const objects::CSeq_loc &on_loc, objects::CScope *scope, const objects::CSeq_annot_Handle &annot_handle)
bool IsHorizontal() const
void TextOut(const CGlTextureFont *font, const char *text, TModelUnit x, TModelUnit y, bool center, bool adjust_flip=true) const
void DrawTriangle(TModelUnit x1, TModelUnit y1, TModelUnit x2, TModelUnit y2, TModelUnit x3, TModelUnit y3, bool border=false) const
CGlPane * GetGlPane()
inline method implementations
TModelRange IntersectVisible(const CSeqGlyph *obj) const
TVPUnit SeqToScreenX(const TModelUnit &size) const
void DrawLineStrip(const vector< TModelPoint > &points) const
void DrawUnalignedTail(TModelUnit x1, TModelUnit x2, TModelUnit y1, TModelUnit y2, bool is_polya, const CRgbaColor &color) const
void DrawLine(TModelUnit x1, TModelUnit y1, TModelUnit x2, TModelUnit y2) const
void DrawStippledLine(TModelUnit x1, TModelUnit y1, TModelUnit x2, TModelUnit y2, int factor=2, unsigned short pattern=0xAAAA) const
objects::CScope & GetScope()
void DrawQuad(const TModelRect &rc, bool border=false) const
const TModelUnit & GetScale() const
void DrawSelection(const TModelRect &rc) const
TModelUnit SeqToScreen(const TModelUnit &size) const
convert from sequence positions to screen pixels
TModelUnit SeqToScreenXInModelUnit(const TModelUnit &size) const
TModelUnit ScreenToSeq(const TModelUnit &size) const
convert from screen pixels to sequence positions
bool IsOverviewMode() const
bool IsFlippedStrand() const
bool WillSeqLetterFit() const
is it enougth space to sequence letters.
void DrawDisk2(const TModelPoint &p, TModelUnit size, CRgbaColor color)
const CRgbaColor & GetSelLabelColor() const
void DrawLine_NoAA(TModelUnit x1, TModelUnit y1, TModelUnit x2, TModelUnit y2) const
TSeqPos GetViewWidth() const
bool WillLabelFit(const TModelRect &rc) const
void Draw3DQuad(TModelUnit x1, TModelUnit y1, TModelUnit x2, TModelUnit y2, const CRgbaColor &color, bool border=false) const
void DrawBackground(const TModelRect &rcm, TModelUnit border) const
void DrawGreaterLessSign(TModelUnit x1, TModelUnit x2, TModelUnit bar_h, bool negative) const
class CRgbaColor provides a simple abstraction for managing colors.
Definition: rgba_color.hpp:58
CScope –.
Definition: scope.hpp:92
class CSeqGlyph defines an interface that wraps a rectilinear abstract object.
Definition: seq_glyph.hpp:82
void x_InitHTMLActiveArea(CHTMLActiveArea &area) const
initialize the basic information for a given active area.
Definition: seq_glyph.cpp:380
CRenderingContext * m_Context
the rendering context
Definition: seq_glyph.hpp:346
virtual void SetHeight(TModelUnit h)
Definition: seq_glyph.hpp:650
virtual TModelUnit GetRight() const
Definition: seq_glyph.hpp:603
virtual void SetWidth(TModelUnit w)
Definition: seq_glyph.hpp:646
bool IsSelected() const
Definition: seq_glyph.hpp:573
virtual void SetLeft(TModelUnit l)
Definition: seq_glyph.hpp:654
virtual TModelUnit GetTop() const
Definition: seq_glyph.hpp:599
virtual TModelUnit GetHeight() const
Definition: seq_glyph.hpp:587
virtual bool LessBySeqPos(const CSeqGlyph &obj) const
compare this object to another based on glyph sequence position.
Definition: seq_glyph.hpp:534
float GetFadeFactor() const
Definition: seq_glyph.hpp:742
size_t GetTearline() const
Definition: seq_glyph.hpp:736
size_t GetVisible() const
Definition: seq_glyph.hpp:284
virtual TModelUnit GetWidth() const
Definition: seq_glyph.hpp:591
virtual TModelUnit GetLeft() const
Definition: seq_glyph.hpp:595
TModelRect GetModelRect() const
get the bounding box.
Definition: seq_glyph.hpp:562
vector< CHTMLActiveArea > TAreaVector
Definition: seq_glyph.hpp:84
virtual TModelUnit GetBottom() const
Definition: seq_glyph.hpp:607
static SIZE_TYPE Reverse(const string &src, TCoding src_coding, TSeqPos pos, TSeqPos length, string &dst)
static SIZE_TYPE ReverseComplement(const string &src, TCoding src_coding, TSeqPos pos, TSeqPos length, string &dst)
static SIZE_TYPE Complement(const string &src, TCoding src_coding, TSeqPos pos, TSeqPos length, string &dst)
@ e_Iupacna
Definition: sequtil.hpp:47
@ e_Iupacaa
Definition: sequtil.hpp:55
CSeqVector –.
Definition: seq_vector.hpp:65
@ eScore_IdentityCount
Definition: Seq_align.hpp:145
@ eScore_PercentIdentity
Definition: Seq_align.hpp:189
ENa_strand GetSeqStrand(TDim row) const
Get strand (the first one if segments have different strands).
Definition: Spliced_seg.cpp:56
@ eRight
Towards higher aln coord (always to the right)
@ eLeft
Towards lower aln coord (always to the left)
@ eBackwards
Towards lower seq coord (to the left if plus strand, right if minus)
@ eForward
Towards higher seq coord (to the right if plus strand, left if minus)
virtual EPolyATail HasPolyATail() const =0
Check if there is any unaligned polyA tail.
pair< ECigarOp, size_t > TCigarPair
virtual void GetUnalignedTails(TSignedSeqPos &start_tail, TSignedSeqPos &end_tail, bool clipped=true) const
virtual const TCigarPair * GetCigarAtAlnPos(int row, TSignedSeqPos pos) const
virtual bool IsRegular() const
virtual bool IsNegativeStrand(TNumrow row) const =0
virtual const objects::CBioseq_Handle & GetBioseqHandle(IAlnExplorer::TNumrow row) const =0
virtual TSeqRange GetAlnRangeWithTails() const
IAlnExplorer::TNumrow TNumrow
virtual TSeqPos GetSeqStart(TNumrow row) const =0
virtual const objects::CSeq_id & GetSeqId(TNumrow row) const =0
int GetGenCode(IAlnExplorer::TNumrow row) const
virtual TSignedRange GetSeqAlnRange(TNumrow row) const =0
virtual IAlnExplorer::TNumrow GetQuery() const
virtual TSeqPos GetSeqStop(TNumrow row) const =0
virtual TSignedSeqPos GetAlnPosFromSeqPos(TNumrow row, TSeqPos seq_pos, IAlnExplorer::ESearchDirection dir=IAlnExplorer::eNone, bool try_reverse_dir=true) const =0
virtual TSeqPos GetFrom() const =0
virtual float GetAttr() const =0
virtual TSeqPos GetTo() const =0
Alignment segment iterator interface.
@ eAllSegments
Iterate all segments.
@ eSkipGaps
Skip gap segments (show only aligned ranges)
Alignment segment interface.
virtual const TSignedRange & GetRange(void) const =0
Get the selected row range.
@ fAligned
Aligned segment.
@ fIndel
Either anchor or the selected row is not present in the segment.
@ fUnaligned
The range on the selected sequence does not participate in the alignment (the alignment range of the ...
virtual TSegTypeFlags GetType(void) const =0
Get current segment type.
bool IsIndel(void) const
bool IsAligned(void) const
bool IsGap(void) const
Check if there's a gap on the selected row.
virtual const TSignedRange & GetAlnRange(void) const =0
Get alignment range for the segment.
vector< TSeqRange > TIntervals
virtual TSeqPos GetBaseWidth(IAlnExplorer::TNumrow) const =0
virtual string & GetAlnSeqString(IAlnExplorer::TNumrow row, string &buffer, const IAlnExplorer::TSignedRange &aln_range) const =0
virtual IAlnExplorer::TNumrow GetNumRows() const =0
virtual IAlnExplorer::TNumrow GetAnchor() const =0
virtual IAlnSegmentIterator * CreateSegmentIterator(IAlnExplorer::TNumrow, const IAlnExplorer::TSignedRange &, IAlnSegmentIterator::EFlags) const =0
virtual TSignedSeqPos GetSeqPosFromAlnPos(IAlnExplorer::TNumrow for_row, TSeqPos aln_pos, IAlnExplorer::ESearchDirection dir=IAlnExplorer::eNone, bool try_reverse_dir=true) const =0
primitive interface to arrange tabular data in the tooltips
Definition: tooltip.hpp:55
bool IsConsensusSplice(const string &splice5, const string &splice3)
Consensus splice is GY..AG or AT..AC.
Include a standard set of the NCBI C++ Toolkit most basic headers.
CS_CONTEXT * ctx
Definition: t0006.c:12
#define false
Definition: bool.h:36
unsigned int TSeqPos
Type for sequence locations and lengths.
Definition: ncbimisc.hpp:875
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
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
#define LOG_POST(message)
This macro is deprecated and it's strongly recomended to move in all projects (except tests) to macro...
Definition: ncbidiag.hpp:226
void Error(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1197
const string & GetMsg(void) const
Get message string.
Definition: ncbiexpt.cpp:461
void Warning(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1191
bool IsSimplified() const
void x_DrawInserts(const SDrawContext &ctx) const
virtual void x_Draw() const
The default renderer for this layout object.
bool x_IsSRA() const
virtual bool NeedTooltip(const TModelPoint &p, ITooltipFormatter &tt, string &t_title) const
Check if need to show tooltip.
void x_CalcIntervals(TIntervals &intervals, int target_row=-1) const
void x_DrawStrandIndicators(const SDrawContext &ctx) const
virtual void GetHTMLActiveAreas(TAreaVector *p_areas) const
Get html active areas.
virtual bool HasObject(CConstRef< CObject > obj) const
check if the wrapped object(s) is the one.
virtual bool LessBySeqPos(const CSeqGlyph &obj) const
compare this object to another based on glyph sequence position.
vector< TModelRange > TMUnitRanges
void x_RenderAveragableScores(TModelUnit yy, TSignedSeqRange aln_range, TSeqRange seq_range, TModelUnit height, int row, bool override_color, const CRgbaColor &read_status_color) const
void x_DrawMultiAlignLabel(int row, TModelUnit y) const
void x_DrawUnalignedBar(const ETail tail, const SDrawContext &ctx, const CRgbaColor &c_fg) const
CAlignGlyph(CConstRef< IAlnGraphicDataSource > aln_mgr, const objects::CSeq_align_Handle &orig_align, const objects::CSeq_align &mapped_align, int orig_anchor)
virtual CConstRef< CObject > GetObject(TSeqPos pos) const
access our core component - we wrap an object(s) of some sort.
TSeqRange x_ConvertAlnTaillRngToSeqRng(const ETail tail, const SDrawContext &ctx, const TSeqRange &aln_range) const
virtual void GetObjects(vector< CConstRef< CObject > > &objs) const
retrieve CObjects corresponding to this CSeqGlyph.
void x_DrawMultiAlign() const
void x_GetOverrideColor(bool &override_color, CRgbaColor &read_status_color) const
TModelUnit x_GetTailLabelWidth(const TSignedSeqPos tail) const
TIntervals m_Intervals
intervals.
virtual string GetSignature() const
return signature for this glyph.
void GetTitle(string *title, CLabel::ELabelType type) const
bool x_ShowLabel() const
void x_DrawNonConsensusSpliceSites(const SDrawContext &ctx) const
void x_RenderNonAveragableScores(TModelUnit yy, TSignedSeqRange aln_range, TSeqRange seq_range, TModelUnit height, int row, bool override_color, const CRgbaColor &read_status_color) const
void x_DrawNoScoreAlign(const SDrawContext &ctx, const CRgbaColor &c_fg) const
void DrawPWAlignElem(const TModelRect &rcm, bool selected, bool show_label, const CRgbaColor &c_fg, const CRgbaColor &c_seq, const CRgbaColor &c_mis) const
virtual TSeqRange GetRange(void) const
get the total range of this object.
const IAlnGraphicDataSource & GetAlignMgr(void) const
Inline methods.
void x_DrawIntronsAndInternalUnalignedRegions(const SDrawContext &ctx, TSignedSeqPos from, TSignedSeqPos to) const
void x_DrawGaps(const SDrawContext &ctx) const
virtual void GetTooltip(const TModelPoint &p, ITooltipFormatter &tt, string &t_title) const
Get the tooltip if available.
CConstRef< CAlignmentConfig > m_Config
const objects::CSeq_align_Handle & GetOrigAlignment(void) const
void ApplyFading() const
virtual bool IsClickable() const
Query if this glyph is clickable.
bool x_ShowScore() const
void x_DrawUnalignedRowSequence(const ETail tail, const SDrawContext &ctx, const CRgbaColor &c_fg) const
virtual const objects::CSeq_loc & GetLocation(void) const
access the position of this object.
void x_DrawInternalUnalignedRegions(const SDrawContext &ctx, TMUnitRanges &unaligned_regions) const
CRef< objects::CSeq_loc > m_Location
static bool IsVDBAccession(const string &acc)
Check if string starts with ("SRA", "SRR", "DRR", "ERR")
Definition: utils.cpp:888
TModelUnit GetBarHeight() const
TModelUnit x_GetTailWidth(const TSignedSeqPos tail, const TSignedSeqPos visible_tail, const TSignedSeqPos base_width_curr) const
virtual const TIntervals & GetIntervals(void) const
access sub-intervals (if any).
bool IsLastRow() const
void x_DrawAlignRowSequence(TModelUnit center_y, int row, const CRgbaColor &c_fg, const CRgbaColor &c_seq, const CRgbaColor &c_mis) const
TSeqRange x_GetAlnTailRange(const ETail tail, const SDrawContext &ctx) const
void x_DrawSimplified(const SDrawContext &ctx, const CRgbaColor &c_fg) const
virtual void x_UpdateBoundingBox()
Update the bounding box assuming children's sizes are fixed if any.
CConstRef< IAlnGraphicDataSource > m_AlnMgr
pointer to the actual alignment information.
bool x_ShowUnalignedTails(TModelUnit align_len) const
bool m_DisableTooltipsCaching
Indicates whether the front-end can cache the tooltips.
bool x_IsPWAlign() const
void x_DrawTailSequences(const SDrawContext &ctx, const CRgbaColor &c_fg) const
void x_DrawPWAlign() const
const objects::CSeq_align & GetAlignment(void) const
CConstRef< objects::CSeq_align > m_SeqAlign
CConstIRef< ISGAlnScore > m_Score
objects::CSeq_align_Handle m_OrigSeqAlign
int m_OrigAnchor
The anchor row number in original Seq-algin, not alnmgr.
void x_DrawTailGlyphs(const SDrawContext &ctx, bool show_label, const CRgbaColor &c_fg) const
@ eMaxRowLimit
GLdouble TModelUnit
Definition: gltypes.hpp:48
virtual void Scalef(GLfloat x, GLfloat y, GLfloat z)=0
T X() const
Definition: glpoint.hpp:59
virtual void Enable(GLenum glstate)=0
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.
void Color3f(GLfloat r, GLfloat g, GLfloat b)
Definition: irender.hpp:95
T Bottom() const
Definition: glrect.hpp:82
T Width() const
Definition: glrect.hpp:86
IRender & GetGl()
convenience function for getting current render manager
void Vertex2d(GLdouble x, GLdouble y)
Definition: irender.hpp:185
TVPRect & GetViewport(void)
Definition: glpane.hpp:332
virtual TModelUnit TextHeight(const CGlTextureFont *font) const =0
virtual TModelUnit TextWidth(const CGlTextureFont *font, const char *text) const =0
void Color4d(GLdouble r, GLdouble g, GLdouble b, GLdouble a)
Definition: irender.hpp:102
virtual void PopMatrix()=0
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.
int TVPUnit
Definition: gltypes.hpp:47
void Color4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
Definition: irender.hpp:97
TModelRect & GetVisibleRect(void)
Definition: glpane.hpp:357
CGlRect< TModelUnit > TModelRect
Definition: gltypes.hpp:54
virtual void Disable(GLenum glstate)=0
glDisable()
virtual void LineWidth(GLfloat w)=0
Set line width for drawing: glLineWidth()
TModelUnit GetScaleY(void) const
Definition: glpane.cpp:123
CGlPoint< TModelUnit > TModelPoint
Definition: gltypes.hpp:51
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
virtual void PushMatrix()=0
string Truncate(const char *text, TModelUnit w, ETruncate trunc=eTruncate_Ellipsis) const
Truncate text to the secified width.
void SetDataSource(const CConstRef< IAlnGraphicDataSource > &data_source)
static void GetLabel(const CObject &obj, string *label, ELabelType type=eDefault)
Definition: label.cpp:140
void SetFlippedStrands(bool flipped=true)
virtual void AddRow(const string &sContents="", unsigned colspan=2)=0
add a row with a cell, spanning across all columns
void Set(float r, float g, float b)
set the color from an Fl_Color
Definition: rgba_color.cpp:226
float GetBlue(void) const
Definition: rgba_color.hpp:333
float GetGreen(void) const
Definition: rgba_color.hpp:327
void SetAlpha(float r)
Definition: rgba_color.cpp:287
void Lighten(float scale)
Definition: rgba_color.cpp:463
static CRgbaColor Interpolate(const CRgbaColor &color1, const CRgbaColor &color2, float alpha)
Interpolate two colors.
Definition: rgba_color.cpp:444
static bool IsPolyA(const objects::CBioseq_Handle &bsh, TSeqPos start, TSeqPos stop)
ELabelType
Definition: label.hpp:60
float GetRed(void) const
Get specific channels in floating point values.
Definition: rgba_color.hpp:321
@ eType
Definition: label.hpp:65
@ eDefault
Definition: label.hpp:73
@ eUserTypeAndContent
Definition: label.hpp:66
@ eContent
Definition: label.hpp:62
@ eDescription
Definition: label.hpp:68
@ eDescriptionBrief
Definition: label.hpp:67
const string AsFastaString(void) const
Definition: Seq_id.cpp:2266
CConstRef< CSeq_id > GetSeqId(void) const
virtual void Assign(const CSerialObject &source, ESerialRecursionMode how=eRecursive)
Override Assign() to incorporate cache invalidation.
Definition: Seq_loc.cpp:337
void SetId(CSeq_id &id)
set the 'id' field in all parts of this location
Definition: Seq_loc.cpp:3474
const CSeq_id & GetId(const CSeq_loc &loc, CScope *scope)
If all CSeq_ids embedded in CSeq_loc refer to the same CBioseq, returns the first CSeq_id found,...
TSeqPos GetLength(const CSeq_id &id, CScope *scope)
Get sequence length if scope not null, else return max possible TSeqPos.
static void Translate(const string &seq, string &prot, const CGenetic_code *code, bool include_stop=true, bool remove_trailing_X=false, bool *alt_start=NULL, bool is_5prime_complete=true, bool is_3prime_complete=true)
Translate a string using a specified genetic code.
Definition: sequence.cpp:4095
@ fIs5PrimePartial
= 0x4 Translate first codon even if not start codon (because sequence is 5' partial)
Definition: sequence.hpp:984
@ eGetId_Canonical
Definition: sequence.hpp:114
TSeqPos GetBioseqLength(void) const
bool IsAa(void) const
CSeqVector GetSeqVector(EVectorCoding coding, ENa_strand strand=eNa_strand_plus) const
Get sequence: Iupacna or Iupacaa if use_iupac_coding is true.
@ eCoding_Iupac
Set coding to printable coding (Iupacna or Iupacaa)
void GetSeqData(TSeqPos start, TSeqPos stop, string &buffer) const
Fill the buffer string with the sequence data for the interval [start, stop).
Definition: seq_vector.cpp:304
TObjectType * GetPointer(void) const THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:1684
TObjectType * GetPointer(void) THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:998
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
position_type GetLength(void) const
Definition: range.hpp:158
TThisType IntersectionWith(const TThisType &r) const
Definition: range.hpp:312
position_type GetToOpen(void) const
Definition: range.hpp:138
TThisType & Set(position_type from, position_type to)
Definition: range.hpp:188
bool Empty(void) const
Definition: range.hpp:148
CRange< TSeqPos > TSeqRange
typedefs for sequence ranges
Definition: range.hpp:419
CRange< TSignedSeqPos > TSignedSeqRange
Definition: range.hpp:420
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define kEmptyStr
Definition: ncbistr.hpp:123
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5078
static string UIntToString(unsigned int value, TNumToStringFlags flags=0, int base=10)
Convert UInt to string.
Definition: ncbistr.hpp:5103
@ fWithCommas
Use commas as thousands separator.
Definition: ncbistr.hpp:254
static const char label[]
void SetFrom(TFrom value)
Assign a value to From data member.
Definition: Range_.hpp:231
TTo GetTo(void) const
Get the To member data.
Definition: Range_.hpp:269
TFrom GetFrom(void) const
Get the From member data.
Definition: Range_.hpp:222
void SetTo(TTo value)
Assign a value to To data member.
Definition: Range_.hpp:278
const TDonor_after_exon & GetDonor_after_exon(void) const
Get the Donor_after_exon member data.
TGenomic_start GetGenomic_start(void) const
Get the Genomic_start member data.
const TAcceptor_before_exon & GetAcceptor_before_exon(void) const
Get the Acceptor_before_exon member data.
bool IsSetAcceptor_before_exon(void) const
splice sites Check if a value has been assigned to Acceptor_before_exon data member.
list< CRef< CUser_object > > TExt
Definition: Seq_align_.hpp:402
list< CRef< CSpliced_exon > > TExons
const TExons & GetExons(void) const
Get the Exons member data.
const TBases & GetBases(void) const
Get the Bases member data.
TGenomic_end GetGenomic_end(void) const
Get the Genomic_end member data.
bool IsSetDonor_after_exon(void) const
Check if a value has been assigned to Donor_after_exon data member.
@ eNa_strand_plus
Definition: Na_strand_.hpp:66
@ eNa_strand_minus
Definition: Na_strand_.hpp:67
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
n background color
int i
int len
range(_Ty, _Ty) -> range< _Ty >
constexpr auto sort(_Init &&init)
const struct ncbi::grid::netcache::search::fields::SIZE size
#define abs(a)
Definition: ncbi_heapmgr.c:130
unsigned int a
Definition: ncbi_localip.c:102
T max(T x_, T y_)
T log10(T x_)
T min(T x_, T y_)
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
static int match(PCRE2_SPTR start_eptr, PCRE2_SPTR start_ecode, uint16_t top_bracket, PCRE2_SIZE frame_size, pcre2_match_data *match_data, match_block *mb)
Definition: pcre2_match.c:594
static SLJIT_INLINE sljit_ins msg(sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b)
#define row(bind, expected)
Definition: string_bind.c:73
represents a pixel with two scores, one corresponds to a gap interval, another - to an aligned segmen...
Definition: align_row.cpp:1708
float m_MinScore
Definition: align_row.cpp:1713
float m_IntScore
Definition: align_row.cpp:1709
bool operator==(const SScPix2 &other) const
bool m_Init
Definition: align_row.cpp:1714
float m_IntLen
Definition: align_row.cpp:1710
float m_GapScore
Definition: align_row.cpp:1711
float m_GapLen
Definition: align_row.cpp:1712
represents a pixel with a score, if several intervals cover a pixel, the interval with the maximum co...
Definition: align_row.cpp:1637
float m_MaxCoverage
score assigned to the pixel
Definition: align_row.cpp:1639
bool m_Gap
fraction of the pixel corresponding to the m_Score
Definition: align_row.cpp:1640
float m_Score
Definition: align_row.cpp:1638
bool operator==(const SScPix &other) const
true if this is a gap interval
Definition: type.c:6
Modified on Fri Sep 20 14:58:19 2024 by modify_doxy.py rev. 669887