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

Go to the SVN repository for this file.

1 /* $Id: feature_glyph.cpp 47479 2023-05-02 13:24:02Z ucko $
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: Mike DiCuccio, Liangshou Wu
27  *
28  * File Description:
29  * CFeatGlyph -- utility class to arrange CSeq_feat objects in hierarchical
30  * (tree) order.
31  */
32 
33 #include <ncbi_pch.hpp>
41 
42 #include <gui/widgets/gl/ruler.hpp>
44 #include <gui/objutils/utils.hpp>
46 #include <gui/objutils/tooltip.hpp>
47 #include <gui/objutils/snp_gui.hpp>
49 #include <gui/opengl/irender.hpp>
50 
61 
62 #include <objmgr/util/sequence.hpp>
66 
68 #include <corelib/ncbi_stack.hpp>
69 #include <math.h>
70 
73 
74 /// feature ruler height.
75 static const int kRulerHeight = 16;
76 
77 /// vertical space between elements.
78 static const int kVertSpace = 2;
79 
80 /// Restriction sites marker height (relative to the height of the bar)
81 static const TModelUnit kRSiteMarkerHeight = 0.5;
82 
83 /// Restriction sites marker width (absolute)
84 static const TModelUnit kRSiteMarkerWidth = 0.4;
85 
86 /// Restriction sites marker visibility threshold (ie if the marker's width is smaller then the threshold, markers are not drawn)
88 
89 /// Shoudl match feature_ds.cpp::kMinScaleForMapping
90 /// i.e. what mapping is not created then do not show ruler labels
91 static const float kMinScaleForRulerLabels = 16.;
92 
93 
94 // #define DEBUG_INFO_ON_SCREEN 1
95 
96 //
97 // simple functor for sorting CRange<> objects
98 //
99 template <class T>
100 struct SRangeSorter
101 {
102  bool operator() (const CRange<T>& r0, const CRange<T>& r1) const
103  {
104  if (r0.GetFrom() < r1.GetFrom()) {
105  return true;
106  }
107  if (r0.GetFrom() > r1.GetFrom()) {
108  return false;
109  }
110  if (r0.GetTo() < r1.GetTo()) {
111  return true;
112  }
113  return false;
114  }
115 };
116 
117 
118 /* not used currently
119 static bool s_IsSV(const CVariation_ref& var)
120 {
121  if (var.IsSetId() && var.GetId().GetTag().IsStr()) {
122  const string& id = var.GetId().GetTag().GetStr();
123  if (id.length() > 3 && id[1] == 's' && id[2] == 'v') {
124  return true;
125  }
126  }
127  return false;
128 }
129 
130 
131 
132 static bool s_IsSSV(const CVariation_ref& var)
133 {
134  if (var.IsSetId() && var.GetId().GetTag().IsStr()) {
135  const string& id = var.GetId().GetTag().GetStr();
136  if (id.length() > 4 && id[1] == 's' &&
137  id[2] == 's' && id[3] == 'v') {
138  return true;
139  }
140  }
141  return false;
142 }
143 */
144 
145 //
146 // CFeatGlyph::CFeatGlyph()
147 //
148 CFeatGlyph::CFeatGlyph(const CMappedFeat& f, ELinkedFeatDisplay LinkedFeatDisplay)
149  : m_Feature(f)
150  , m_Location(&f.GetLocation())
151  , m_HideLabel(false)
152  , m_ProjectedFeat(false)
153  , m_RSite(false)
154  , m_RulerType(eNoRuler)
155  , m_LinkedFeat(LinkedFeatDisplay)
156 {
157  if (m_Feature.IsSetData() && (CSeqFeatData::eSubtype_rsite == m_Feature.GetData().GetSubtype()))
158  m_RSite = true;
159 }
160 
161 CFeatGlyph::CFeatGlyph(const CMappedFeat& f, const CSeq_loc& loc, ELinkedFeatDisplay LinkedFeatDisplay)
162  : m_Feature(f)
163  , m_Location(&loc)
164  , m_HideLabel(false)
165  , m_ProjectedFeat(false)
166  , m_RSite(false)
167  , m_RulerType(eNoRuler)
168  , m_LinkedFeat(LinkedFeatDisplay)
169 {
170  if (m_Feature.IsSetData() && (CSeqFeatData::eSubtype_rsite == m_Feature.GetData().GetSubtype()))
171  m_RSite = true;
172 }
173 
174 
175 bool CFeatGlyph::LessBySeqPos(const CSeqGlyph& obj) const
176 {
177  const CFeatGlyph* feat = dynamic_cast<const CFeatGlyph*>(&obj);
178  if (feat) {
179  // two features - we sort in feature order
180  try {
181  SFeatByPos comp;
182  return (comp(*this, *feat));
183  } catch (CException&) {
184  // guard against the case that two features have
185  // differnt forms of seq-id.
186  }
187  }
188 
189  // otherwise, using default, compare by SeqRanges
190  return CSeqGlyph::LessBySeqPos(obj);
191 }
192 
193 
194 bool CFeatGlyph::NeedTooltip(const TModelPoint& /*p*/, ITooltipFormatter& /*tt*/, string& t_title) const
195 {
196  return true;
197 }
198 
199 
200 void CFeatGlyph::GetTooltip(const TModelPoint& p, ITooltipFormatter& tt, string& t_title) const
201 {
202  CScope& scope = GetMappedFeature().GetAnnot().GetScope();
203  SConstScopedObject scoped_obj(&GetFeature(), &scope);
204  CIRef<IGuiObjectInfo> gui_info(
205  CreateObjectInterface<IGuiObjectInfo>(scoped_obj, NULL));
206 
207  if ( !gui_info ) return;
208 
209  TSeqPos at_p = (TSeqPos)-1;
210  if (p.X() >= 0) {
211  at_p = (TSeqPos)p.X();
212  }
213 
214  CGuiObjectInfoSeq_feat* gui_info_feat =
215  dynamic_cast<CGuiObjectInfoSeq_feat*>(gui_info.GetPointer());
216  if (gui_info_feat) {
217  if (x_IsProjected()) {
218  auto loc = Ref(new CSeq_loc);
220  gui_info_feat->SetLocation(*loc);
221  if (loc->GetId()) {
222  CBioseq_Handle bsh = scope.GetBioseqHandle(*loc->GetId());
223  if (bsh)
224  gui_info_feat->SetTaxId(sequence::GetTaxId(bsh));
225  }
226  if ((int)at_p != -1) {
228  int anchor = aln_mgr->GetAnchor();
229  int aligned = aln_mgr->GetQuery();
230  TSeqPos pos = at_p;
231  if (aln_mgr->GetBaseWidth(anchor) == 3) {
232  pos *= aln_mgr->GetBaseWidth(anchor);
233  int fract_part = (p.X() - floor(p.X())) * 100.;
234  int off = min(2, fract_part / 33);
235  at_p = aln_mgr->GetSeqPosFromSeqPos(aligned, anchor, pos);
236  if (aln_mgr->IsNegativeStrand(aligned))
237  at_p -= off;
238  else
239  at_p += off;
240  } else {
241  at_p = aln_mgr->GetSeqPosFromSeqPos(aligned, anchor, pos);
242  }
243 
244  CSeq_id_Handle prod_id = GetMappedFeature().GetProductId();
245  if (prod_id) {
246  CSeqUtils::TMappingInfo mapping_info;
247  CRef<CSeq_id> product_id(new CSeq_id);
248  product_id->Assign(*prod_id.GetSeqId());
249  for (const auto& mi : m_ProjectedMappingInfo) {
250  auto& prod_range = mi.m_MappedProdRange;
251  CRef<CSeq_interval> prod_int(new CSeq_interval(*product_id, prod_range.GetFrom(), prod_range.GetTo(), eNa_strand_plus));
252  mapping_info.emplace_back(prod_int, mi.m_MappedInt);
253  }
254  gui_info_feat->SetMappingInfo(mapping_info);
255 
256  }
257  }
258  } else {
259  gui_info_feat->SetLocation(*m_Location);
261  if (ctx && ctx->GetSeqDS()) {
262  CBioseq_Handle bsh = ctx->GetSeqDS()->GetBioseqHandle();
263  if (bsh)
264  gui_info_feat->SetTaxId(sequence::GetTaxId(bsh));
265  }
266  gui_info_feat->SetMappingInfo(GetMappingInfo());
267  }
268  }
269  gui_info_feat->SetMappedFeat(GetMappedFeature());
270 
271  bool isTooltipGeneratedBySvc(false);
272  gui_info->GetToolTip(tt, t_title, at_p, &isTooltipGeneratedBySvc);
273  if(!isTooltipGeneratedBySvc) {
274  gui_info->GetLinks(tt, false);
275  }
276 }
277 
278 
280 {
281  TSeqRange SeqRange;
282  try { // watch out for mix loc with multiple seq-ids
283  SeqRange = m_Location->GetTotalRange();
284  } catch (CException&) {
285  // get SeqRange from intervals
287  SeqRange.CombineWith(*it);
288  }
289  }
290 
291  if (IsDbVar(GetFeature())) {
292  if (GetLocation().IsInt()) {
293  if (GetLocation().GetInt().IsSetFuzz_from() &&
294  GetLocation().GetInt().GetFuzz_from().IsRange()) {
295  const CInt_fuzz::C_Range& f_SeqRange =
296  GetLocation().GetInt().GetFuzz_from().GetRange();
297  SeqRange.SetFrom(f_SeqRange.GetMin());
298  }
299  if (GetLocation().GetInt().IsSetFuzz_to() &&
300  GetLocation().GetInt().GetFuzz_to().IsRange()) {
301  const CInt_fuzz::C_Range& t_SeqRange =
302  GetLocation().GetInt().GetFuzz_to().GetRange();
303  SeqRange.SetTo(t_SeqRange.GetMax());
304  }
305  }
306  }
307 
308  return SeqRange;
309 }
310 
311 
313 {
315  string clnsig;
316  if (NSnpGui::GetClinSigValue(GetFeature(), clnsig)) {
318  return true;
319  }
321 // string sColorTheme(x_GetGlobalConfig()->GetColorTheme());
322  string sColorTheme("Color");
323  CRegistryReadView ColorView(CSGConfigUtils::GetColorReadView(registry, "GBPlugins.SnpTrack", "Default", sColorTheme));
324  string sColorKey("Default");
325 
326  switch(NSnpGui::GetVcfType(GetFeature())) {
328  sColorKey = "SingleBase";
329  break;
331  sColorKey = "MultiBase";
332  break;
334  sColorKey = "Insertion";
335  break;
337  sColorKey = "Deletion";
338  break;
340  sColorKey = "Dips";
341  break;
342  default:
343  break;
344  }
345  if(sColorKey != "Default") {
346  CSGConfigUtils::GetColor(ColorView, sColorKey, color);
347  return true;
348  } else {
349  return false;
350  }
351  }
352 
353  size_t idx = GetCustomColorIdx(GetFeature());
354 
357  if (idx > 0 && idx < colors.size()) {
358  color = colors[idx];
359  return true;
360  }
361  return false;
362 }
363 
364 
365 
367 {
368 // string sLabel;
369 // GetLabel(sLabel, CLabel::eContent);
370 // LOG_POST(Trace << "<<<< CFeatGlyph::GetHTMLActiveAreas() " << this << " \"" << sLabel << " isDbVar: " << IsDbVar(GetFeature()));
371 
372  if(x_isDrawn()) {
373  CHTMLActiveArea area;
376  bool is_db_xref = GetFeature().IsSetDbxref();
377 
378  switch (GetFeature().GetData().GetSubtype()) {
381  if (GetFeature().IsSetProduct()) {
382  const CSeq_loc& product = GetFeature().GetProduct();
383  CSeq_id_Handle shdl = sequence::GetId(*product.GetId(),
385  if (shdl) {
386  area.m_DB_ID = shdl.AsString();
387  }
388  } else {
389  try {
390  const CSeq_id& id = sequence::GetId(GetLocation(),
391  &m_Context->GetScope());
392  id.GetLabel(&area.m_DB_ID, CSeq_id::eContent);
393  } catch (CException&) {
394  /// ignore it
395  }
396  }
397  if (!m_MappingInfo.empty())
399  break;
400 
402  if (is_db_xref) {
403  CConstRef<CDbtag> tag = GetFeature().GetNamedDbxref("GeneID");
404  if (tag.NotEmpty()) {
405  area.m_DB_Name = "gene";
406  area.m_DB_ID = tag->GetUrl();
407  }
408  }
410  break;
411 
413  if (is_db_xref) {
414  CConstRef<CDbtag> tag = GetFeature().GetNamedDbxref("UniSTS");
415  if (tag.NotEmpty()) {
416  area.m_DB_Name = "UniSTS";
417  area.m_DB_ID = tag->GetUrl();
418  }
419  }
420  break;
421 
423  if (is_db_xref) {
425  if (tag.NotEmpty()) {
426  area.m_DB_Name = "SNP";
427  area.m_DB_ID = tag->GetUrl();
428  }
429  }
430  break;
431 
441  if (!m_MappingInfo.empty())
443  break;
449  break;
450 
451  default:
452  break;
453  }
454 
455 
456  // for features with editable flag set, we also report feature-id
457  if (GetFeature().IsSetExts()) {
458  const CSeq_feat::TExts& exts = GetFeature().GetExts();
459  ITERATE (CSeq_feat::TExts, iter, exts) {
460  if ( (*iter)->GetType().IsStr() &&
461  (*iter)->GetType().GetStr() == "Editing" &&
462  (*iter)->GetFieldRef("Editable") &&
463  (*iter)->GetFieldRef("Editable")->GetData().GetBool() &&
464  ( GetFeature().CanGetId() ||
465  (GetFeature().CanGetIds() &&
466  !GetFeature().GetIds().empty()) ) ) {
468  area.m_ID = x_GetFeatureId();
469  if((*iter)->GetFieldRef("Ignorable") &&
470  (*iter)->GetFieldRef("Ignorable")->GetData().GetBool()) {
472  }
473  }
474  }
475  }
476  area.m_Signature = GetSignature();
477 
478  // a tooltip should be generated for features created by a remote file pipeline to avoid an additional roundtrip
479  if(isRmtBased()) {
480  string s;
481  string title;
483  tooltip->SetTrustedData(false);
484  GetTooltip(TModelPoint(-1, -1), *tooltip, title);
485  s = tooltip->Render();
486  string text = NStr::Replace(s, "\n", "<br/>");
487  area.m_Descr = text;
488  }
489  p_areas->push_back(area);
490 // LOG_POST(Trace << ">>>> CFeatGlyph::GetHTMLActiveAreas() area with signature \"" << area.m_Signature << "\" generated for \"" << sLabel <<
491 // "\", rect: " << area.m_Bounds.Left() << ":" << area.m_Bounds.Right() << ":" << area.m_Bounds.Top() << ":" << area.m_Bounds.Bottom());
492  } else {
493 // LOG_POST(Trace << ">>>> CFeatGlyph::GetHTMLActiveAreas() no area generated for " << sLabel);
494  }
495 }
496 
497 
499 {
500  return true;
501 }
502 
504 {
505  return m_Feature.GetAnnot().IsNamed() && CSeqUtils::isRmtAnnotName(m_Feature.GetAnnot().GetName());
506 }
507 
509 {
510 // LOG_POST(Trace << "==== CFeatGlyph::SetSelected() " << this << " from " << IsSelected() << " to " << f);
511  if (f != IsSelected()) {
513  // The object size may be changed in the following cases:
514  // - For feature with ruler enabled, we always show
515  // feature ruler when it is selected
516  // - For feature with top labeling, but somehow the label
517  // is forced to hide, we will show the label when it is
518  // selected.
519  // - when a selection potentially causes expansion, so that the
523  return true;
524  }
525  if (m_RulerType != eNoRuler ||
526  (m_HideLabel &&
528 // LOG_POST(Trace << "Calling x_OnLayoutChanged()");
530  }
531  }
532  return false;
533 }
534 
536 {
538 }
539 
540 
541 
543 {
544  m_HideLabel = b;
545 }
546 
547 
549 {
551 }
552 
553 
554 const objects::CSeq_loc& CFeatGlyph::GetLocation(void) const
555 {
556  return *m_Location;
557 }
558 
559 
561 {
562  return CConstRef<CObject>(&m_Feature.GetOriginalFeature());
563 }
564 
565 
566 void CFeatGlyph::GetObjects(vector<CConstRef<CObject> >& objs) const
567 {
568  objs.push_back( CConstRef<CObject>(&m_Feature.GetOriginalFeature()) );
569 }
570 
571 
573 {
574  return &m_Feature.GetOriginalFeature() == obj.GetPointer();
575 }
576 
578 {
579  return IsInHor(x) && (&m_Feature.GetOriginalFeature() == obj);
580 }
581 
583 {
584  string sig = kEmptyStr;
585  if (m_ProjectedFeat) {
586  try {
589  &m_Context->GetScope(), m_Feature.GetAnnot(), m_sFilter);
590  } catch (CException& e) {
591  // failed to generated the signature.
592  // it is likely the feature location contains multiple seq-ids.
593  LOG_POST(Warning <<
594  "CFeatGlyph::GetSignature() failed to generate signature: " <<
595  e.GetMsg());
596  }
597  } else {
600  &m_Context->GetScope(), m_Feature.GetAnnot(), m_sFilter);
601  }
602  return sig;
603 }
604 
605 
607 {
608  return m_Intervals;
609 }
610 
611 
613 {
614  IRender& gl = GetGl();
615 
617  m_Context->IsOverviewMode() && m_HideLabel) * 0.5;
619  y += gl.TextHeight(&(m_Config->m_LabelFont)) + kVertSpace + 1;
620  }
621 
622  // Ruler is always above a feature bar
623  if (x_ShowRuler()) {
624  if (m_RulerType & eNtRuler)
625  y += kRulerHeight + kVertSpace;
626  if (m_RulerType & eAaRuler)
627  y += kRulerHeight + kVertSpace;
628  }
629 
630  return y;
631 }
632 
633 
634 string CFeatGlyph::GetPName() const
635 {
636  string sLabel;
637  CScope& scope = GetMappedFeature().GetAnnot().GetScope();
638  CLabel::GetLabel(GetFeature(), &sLabel, CLabel::eContent, &scope);
639 
640  // for debugging
641  // m_sPName = sLabel;
642 
643  return sLabel;
644 }
645 
647 {
648  auto it = m_Labels.find(type);
649  if (it != m_Labels.end()) {
650  label = it->second;
651  return;
652  }
653  CScope& scope = GetMappedFeature().GetAnnot().GetScope();
654  CLabel::GetLabel(GetFeature(), &label, type, &scope);
655  if (type == CLabel::eContent) {
656  NStr::ReplaceInPlace(label, "/standard_name=", "");
657  }
658 
659  size_t nChildren(0);
660  bool isExpandable(x_isExpandable(nChildren));
661 #ifdef DEBUG_INFO_ON_SCREEN
662  label += " CFeatGlyph<" + NStr::NumericToString(GetLevel()) + ">/" + NStr::IntToString(x_isDrawn()) + "/" +
663  (isExpandable ? string() : "[" + NStr:: NumericToString(nChildren) + "]") +
664  " ";
665 #endif
666  label += isExpandable ? " [+" + NStr:: NumericToString(nChildren) + "]" : string();
667  label += x_isCollapsible() ? " [-]" : "";
668  if(!GetTearlineText().empty()) {
669  label += GetTearlineText();
670  }
671  m_Labels.emplace(type, label);
672 }
673 
674 /// some features may have additional info on the right (currently alleles for SNPs)
675 /// that will be shown at the same time as labels
676 void CFeatGlyph::GetAdditionalInfo(string& sAdditionalInfo) const
677 {
678  sAdditionalInfo.clear();
679 
680  NSnp::TAlleles Alleles;
681  NSnp::GetAlleles(GetFeature(), Alleles);
682 
683  sAdditionalInfo = NStr::Join(Alleles, "/");
684 }
685 
686 static int s_GetLiteralLength(const CVariation_ref& var)
687 {
688  int len = -1;
689  if (var.GetData().IsInstance() && var.GetData().GetInstance().IsSetDelta()) {
692  if ((*iter)->IsSetSeq() && (*iter)->GetSeq().IsLiteral()) {
693  len = (*iter)->GetSeq().GetLiteral().GetLength();
694  break;
695  }
696  }
697  }
698  return len;
699 }
700 
701 /*
702 static int s_GetChildNum(const objects::CSeq_feat& feat)
703 {
704  string num_str = feat.GetNamedQual("Child Count");
705  if ( !num_str.empty() ) {
706  try {
707  return NStr::StringToInt(num_str);
708  } catch (CException&) {
709  // ignore it
710  }
711  }
712  return -1;
713 }
714 */
715 
717 {
719  if (IsDbVar(feat)) {
720  const CVariation_ref& var = feat.GetData().GetVariation();
721  if (var.IsComplex()) {
723  } else if (var.IsInsertion()) {
725  } else if (var.IsInversion()) {
727  } else if (var.IsEversion()) {
729  } else if (var.IsTranslocation()) {
731  } else if (var.IsGain()) {
733  } else if (var.IsLoss() || var.IsDeletion()) {
735  } else if (var.IsCNV()) {
737  } else if (var.IsDeletionInsertion()) {
739  } else {
741  }
742  } else if (feat.GetData().Which() == CSeqFeatData::e_Variation) {
743  const string& var_type = feat.GetNamedQual("Var_type");
744  if ( !var_type.empty() ) {
745  if (NStr::EqualNocase(var_type, "Deletion") ||
746  NStr::EqualNocase(var_type, "Loss")) {
748  } else if (NStr::EqualNocase(var_type, "Insertion") ||
749  NStr::EqualNocase(var_type, "Duplication")) {
751  } else if (NStr::EqualNocase(var_type, "Gain")) {
753  } else if (NStr::EqualNocase(var_type, "Inversion")) {
755  }
756  } else {
757  const string& identity = feat.GetNamedQual("identity");
758  if ( !identity.empty() ) {
759  try {
760  double identity_num = NStr::StringToDouble(identity);
761  if (identity_num > 99.0) {
763  } else if (identity_num > 98.0) {
765  } else if (identity_num > 90.0) {
767  }
768  } catch (CException&) {
769  /// ignore
770  }
771  }
772  }
773  }
774  return (size_t)idx;
775 }
776 
777 
778 bool CFeatGlyph::IsDbVar(const objects::CSeq_feat& feat)
779 {
780  if (feat.GetData().Which() == CSeqFeatData::e_Variation) {
781  const CVariation_ref& sv = feat.GetData().GetVariation();
782  if (sv.CanGetId() && sv.GetId().GetDb() == "dbVar") {
783  return true;
784  }
785  }
786  return false;
787 }
788 
789 
791 {
792 // LOG_POST(Trace << "<<<< CFeatGlyph::x_isDrawn() " << this << " <" << GetLevel() << "> \"" << GetPName() << "\"");
794  {
795  // level 0 (topmost) are unconditionally shown
796  // undefined levels are shown too (just in case)
797  if(GetLevel() != -1 && GetLevel() != 0) {
798  bool isRelatedGlyphSelected(GetRelatedGlyphSelected());
799 // LOG_POST(Trace << ">>>> using GetRelatedGlyphSelected(): " << isRelatedGlyphSelected);
800  return isRelatedGlyphSelected;
801  }
802  }
803 // LOG_POST(Trace << ">>>> true");
804  return true;
805 }
806 
807 bool CFeatGlyph::x_isExpandable(size_t& nChildren) const
808 {
810  {
811  const CSeqGlyph* pParent(GetParent());
812 
813  if(pParent) {
814  const CLayoutGroup* pParentLayoutGroup(dynamic_cast<const CLayoutGroup*>(pParent));
815 
816  if(pParentLayoutGroup) {
817  // the presented glyph is a master in the group and the group has other features and none of them are selected
818  if(pParentLayoutGroup->IsMaster(this) && pParentLayoutGroup->GetChildrenNum() > 1) {
819  for(size_t iSeqGlyphs=0; iSeqGlyphs < pParentLayoutGroup->GetChildrenNum(); ++iSeqGlyphs) {
820  if(pParentLayoutGroup->GetChild(static_cast<int>(iSeqGlyphs))->IsSelected()) {
821  return false;
822  }
823  }
824  nChildren = pParentLayoutGroup->GetChildrenNum() - 1;
825  return true;
826  }
827  }
828  }
829  }
830  return false;
831 }
832 
833 
835 {
837  {
838  const CSeqGlyph* pParent(GetParent());
839 
840  if(pParent) {
841  const CLayoutGroup* pParentLayoutGroup(dynamic_cast<const CLayoutGroup*>(pParent));
842 
843  if(pParentLayoutGroup) {
844  // the presented glyph is a master in the group and the group has other features and at least one of them is selected
845  if(pParentLayoutGroup->IsMaster(this) && pParentLayoutGroup->GetChildrenNum() > 1) {
846  for(size_t iSeqGlyphs=0; iSeqGlyphs < pParentLayoutGroup->GetChildrenNum(); ++iSeqGlyphs) {
847  if(pParentLayoutGroup->GetChild(static_cast<int>(iSeqGlyphs))->IsSelected()) {
848  return true;
849  }
850  }
851  return false;
852  }
853  }
854  }
855  }
856  return false;
857 }
858 
859 
860 
861 void CFeatGlyph::x_Draw() const
862 {
864 
865 // LOG_POST(Trace << "<<<<");
866 
867 /*
868 // print drawing info
869  {
870  string sLabel;
871  GetLabel(sLabel, CLabel::eContent);
872  LOG_POST(Trace << "Attempting to draw " << this << " \"" << sLabel << "\" x_isDrawn: " << x_isDrawn() <<
873  ", m_Height: " << GetHeight() << ", m_Width: " << GetWidth() <<
874  ", m_Pos.m_X: " << GetLeft() << ", m_Pos.m_Y: " << GetTop());
875  }
876 */
877  if (GetHeight() == 0 || m_Context->IntersectVisible(GetRange()).Empty() || !x_isDrawn()) {
878 // LOG_POST(Trace << ">>>>");
879  return;
880  }
881  // for debuggingcd
882  /*
883  CScope& scope = GetMappedFeature().GetAnnot().GetScope();
884  string sig = CObjFingerprint::GetFeatSignature(GetFeature(), &scope, m_sFilter);
885  int subtype;
886  CSeq_id_Handle id;
887  TSeqPos f, t;
888  CObjFingerprint::EObjectType type;
889  Uint4 fingerprint;
890  CObjFingerprint::ParseSignature(sig, id, f, t, type, subtype, fingerprint);
891  cout << ", From: " << f
892  << ", To: " << t
893  << ", Subtype: " << subtype << endl;
894  */
895 
896  TModelUnit base = GetTop();
897  // Draw a shading background to indicate exception
899  x_DrawException();
900  }
901 
902  if (x_ShowRuler()) {
903  try {
904  if (m_RulerType & eNtRuler) {
905  x_DrawRuler(base);
906  base += kRulerHeight + kVertSpace;
907  }
908  if (m_RulerType & eAaRuler) {
909  x_DrawRuler(base, true);
910  base += kRulerHeight + kVertSpace;
911  }
912  } catch (CException&) {
913  // we may have problems on setting up the required alignment
914  // mapping for features with mix location (multip seq-ids or
915  // mix strands from one location)
916  }
917  }
918 
919  TModelUnit bar_height = x_GetBarHeight();
920  x_MaybeDrawLabelAbove(base);
921  base += bar_height * 0.5; // bar center
922 
923  if (IsDbVar(GetFeature())) {
924  x_DrawFeatureBar_sv(base);
925  } else {
926  x_DrawFeatureBar(base);
927  }
928  if (m_Context->WillSeqLetterFit()) {
929  if (GetFeature().IsSetProduct()
930  && GetFeature().GetData().IsRna()
931  && !GetMappingInfo().empty()) {
933  }
934  }
935 
937  x_DrawAdditionalInfo(base);
938 
939  if (IsSelected()) {
940  TModelRect model_rect = GetModelRect();
941  TModelUnit left;
942  TModelUnit right;
943  x_IntersectVisible<TModelUnit>(TModelRange(model_rect.Left(), model_rect.Right()), left, right);
944  model_rect.SetLeft(left);
945  model_rect.SetRight(right);
946  m_Context->DrawSelection(model_rect);
947  }
948  // LOG_POST(Trace << ">>>>");
949 }
950 
952 {
953  // base - is center y-line of the feature
954  IRender& gl = GetGl();
955 
957  const CSeqVector& vec = seq_ds->GetSeqVector();
958 
959  string prod_seq;
960  size_t prod_len = 0;
961  try {
962  const CSeq_loc& product = GetFeature().GetProduct();
963  CScope& scope = GetMappedFeature().GetAnnot().GetScope();
965  if (!bsh) // undefined product
966  return;
967  CSeqVector prod_vec(product, scope, CBioseq_Handle::eCoding_Iupac);
968  prod_len = prod_vec.size();
969  prod_vec.GetSeqData(0, static_cast<TSeqPos>(prod_len), prod_seq);
970  } catch (CException&) {
971  // ignore exceptions - these arise if the product doesn't resolve
972  }
973 
974  // Get the mapped genomic sequence based the mapping intervals
975  string gen_seq;
976  gen_seq.reserve(prod_len);
977  {
978  TSeqPos pre_t_to = 0; // previos transcript to + 1 coordinate
979  for (auto&& iter : GetMappingInfo()) {
980  // iter->first interval - transcrit
981  // iter->second interval - genomic
982  auto& prod_int = *iter.first;
983  auto& gen_int = *iter.second;
984  // fill the gap on protein sequence with 'N'
985  TSeqPos t_from = prod_int.GetFrom();
986  if (t_from > pre_t_to)
987  gen_seq.append(t_from - pre_t_to, 'N');
988  string tmp_seq;
989  vec.GetSeqData(gen_int.GetFrom(), gen_int.GetTo() + 1, tmp_seq);
990  bool neg = gen_int.IsSetStrand() && gen_int.GetStrand() == eNa_strand_minus;
991  if (neg) {
992  string seq;
994  0, static_cast<TSeqPos>(tmp_seq.length()), seq);
995  tmp_seq.swap(seq);
996  }
997  pre_t_to = prod_int.GetTo() + 1;
998  gen_seq += tmp_seq;
999  }
1000  }
1001 
1002  char prod_out[2];
1003  prod_out[1] = '\0';
1004 
1005  static const CRgbaColor c_white("white");
1006  gl.ColorC(c_white);
1007 
1008  const CGlTextureFont& font = m_Config->m_LabelFont;
1009  TModelUnit font_height = gl.TextHeight(&font);
1010  font_height *= 0.5;
1011 
1012  TModelUnit y = base + ceil(font_height);
1013 
1014  CConstRef<CSeq_interval> prev_gen(0);
1015  CConstRef<CSeq_interval> prev_prod(0);
1016 
1017  auto current_exon = m_Intervals.begin();
1018  for (auto&& map_it : GetMappingInfo()) {
1019  // iter->first interval - transcrit
1020  // iter->second interval - genomic
1021  auto& prod_int = *map_it.first;
1022  auto& gen_int = *map_it.second;
1023 
1024  bool neg = gen_int.IsSetStrand() && gen_int.GetStrand() == eNa_strand_minus;
1025  int step = neg ? -1 : 1;
1026  TSeqRange gen_range(gen_int.GetFrom(), gen_int.GetTo());
1027  if (neg) {
1028  while (current_exon != m_Intervals.end() && current_exon->GetFrom() > gen_range.GetTo()) {
1029  ++current_exon;
1030  prev_gen = 0;
1031  }
1032  } else {
1033  while (current_exon != m_Intervals.end() && current_exon->GetTo() < gen_range.GetFrom()) {
1034  ++current_exon;
1035  prev_gen = 0;
1036  }
1037  }
1038 
1039  // if this interval is outside of the visible range, skip it
1040  if (m_Context->IntersectVisible(gen_range).Empty())
1041  continue;
1042  if (current_exon == m_Intervals.end())
1043  prev_gen = 0;
1044 
1045  // c_pos - position on genomic sequence
1046  // prod_pos - position on transcript
1047  TSeqRange prod_range(prod_int.GetFrom(), prod_int.GetTo());
1048  TSeqPos c_pos = neg ? gen_range.GetTo() : gen_range.GetFrom();
1049  TSeqPos prod_pos = prod_range.GetFrom();
1050  TSeqPos prod_stop = min(prod_range.GetToOpen(), (TSeqPos)gen_seq.size());
1051 
1052  while (prod_pos < prod_stop) {
1053  bool mismatch = (prod_seq[prod_pos] != gen_seq[prod_pos]);
1054  if (mismatch) {
1055  prod_out[0] = prod_seq[prod_pos];
1056  m_Context->TextOut(&font, prod_out, c_pos + 0.5, y, true);
1057  }
1058  prod_pos += 1;
1059  c_pos += step;
1060  }
1061  if (prev_gen != 0) {
1062 
1063  if (prev_prod->GetTo() + 1 != prod_int.GetFrom()) {
1064  c_pos = neg ? gen_int.GetTo() + 1 : gen_int.GetFrom();
1065  x_DrawInsertion(c_pos, base - font_height, base + font_height, base);
1066  } else {
1067  int gap_length = 0;
1068  if (neg) {
1069  if (prev_gen->GetFrom() - 1 != gen_int.GetTo()) {
1070  c_pos = prev_gen->GetFrom() - 1;
1071  gap_length = c_pos - gen_int.GetTo();
1072  }
1073  } else {
1074  if (prev_gen->GetTo() + 1 != gen_int.GetFrom()) {
1075  c_pos = prev_gen->GetTo() + 1;
1076  gap_length = gen_int.GetFrom() - c_pos;
1077  }
1078  }
1079  while (gap_length > 0) {
1080  m_Context->TextOut(&font, "-", c_pos + 0.5, y, true);
1081  c_pos += step;
1082  --gap_length;
1083  }
1084  }
1085  }
1086  prev_gen.Reset(&gen_int);
1087  prev_prod.Reset(&prod_int);
1088  }
1089 
1090 }
1091 
1092 
1094 {
1095  _ASSERT(m_Context);
1096  // LOG_POST(Trace << "<<<<");
1097 
1098  if(x_isDrawn()) {
1099  TSeqRange SeqRange = GetRange();
1100  TModelUnit bar_height = x_GetBarHeight();
1101  SetHeight(bar_height);
1102  SetWidth(SeqRange.GetLength());
1103  SetLeft(SeqRange.GetFrom());
1104 
1105  bool showLabel = x_ShowLabel();
1106 
1107  // Adjust height, if restrictions markers are present & visible
1109  SetHeight(GetHeight() + bar_height*kRSiteMarkerHeight); // Add the height of the bottom cut marker
1110  if (!showLabel || (m_Config->m_LabelPos == CFeatureParams::ePos_Side))
1111  SetHeight(GetHeight() + bar_height*kRSiteMarkerHeight); // Add the height of the top cut marker
1112  }
1113 
1114  // preserve space for undefined breakpoint indicator
1115  // for structural variants
1116  if (IsDbVar(GetFeature())) {
1117  TModelUnit tri_width = m_Context->ScreenToSeq(GetHeight() * 0.5);
1118  TModelUnit extra = 0.0;
1120  SetLeft(GetLeft() - tri_width);
1121  extra += tri_width;
1122  }
1124  extra += tri_width;
1125  }
1126  SetWidth(GetWidth() + extra);
1127  }
1128 
1129  // we preserve label space if it fits either on side or above
1130  if (showLabel) {
1131  IRender& gl = GetGl();
1132 
1133  const CGlTextureFont& font = m_Config->m_LabelFont;
1135  string label;
1137  TModelUnit text_w_px = min(gl.TextWidth(&font, label.c_str()), m_Context->GetMaxLabelWidth(font));
1139  SetWidth(GetWidth() + text_w_pos);
1140  TModelUnit min_text_w_pos = m_Context->GetMinLabelWidthPos(font);
1141 
1142  if (x_LabelOnLeft()) {
1143  SetLeft(GetLeft() - text_w_pos);
1144  TModelRange visible_range_pos = m_Context->IntersectVisible(this);
1145 
1146  if (GetLeft() < 0) {
1147  if (visible_range_pos.GetLength() < min_text_w_pos) {
1148  // Can't even show the minimal length of label
1149  SetWidth(GetWidth() + GetLeft());
1150  SetLeft(0.0);
1151  }
1152  }
1153  }
1154  // also reserve some space for additional info
1155  string sAdditionalInfo;
1156  GetAdditionalInfo(sAdditionalInfo);
1157  if (!sAdditionalInfo.empty()) {
1158  TModelUnit info_width_px = min(gl.TextWidth(&font, sAdditionalInfo.c_str()), m_Context->GetMaxLabelWidth(font));
1159  TModelUnit info_width_pos = m_Context->ScreenToSeq(info_width_px + CRenderingContext::kLabelSpacePx);
1160  SetWidth(GetWidth() + info_width_pos);
1161  if(!x_LabelOnLeft()) {
1162  SetLeft(GetLeft() - info_width_pos);
1163  if (GetLeft() < 0) {
1164  SetWidth(GetWidth() + GetLeft());
1165  SetLeft(0.0);
1166  }
1167  }
1168  }
1170  SetHeight(GetHeight() + gl.TextHeight(&font) + kVertSpace + 1);
1171  }
1172  }
1173 
1174  // Preserve space for feature ruler
1175  if (x_ShowRuler()) {
1176 
1177  if (GetFeature().IsSetExcept() && GetFeature().HasExceptionText("trans-splicing") && !CSeqUtils::IsSameStrands(GetLocation())) {
1179  } else {
1180  if (m_RulerType & eNtRuler)
1182  if (m_RulerType & eAaRuler)
1184  }
1185  }
1186  } else {
1187  SetHeight(0);
1188  SetWidth(0);
1189  SetLeft(0.0);
1190  SetTop(0.0);
1191  }
1192  // print bounding box info
1193 // {
1194 // string sLabel;
1195 // GetLabel(sLabel, CLabel::eContent);
1196 // LOG_POST(Trace << "Bounding box for " << this << " \"" << sLabel << "\" x_isDrawn: " << x_isDrawn() <<
1197 // ", m_Height: " << GetHeight() << ", m_Width: " << GetWidth() <<
1198 // ", m_Pos.m_X: " << GetLeft() << ", m_Pos.m_Y: " << GetTop());
1199 // LOG_POST(Trace << "Call stack for " << this << ": " << CStackTrace());
1200 
1201 // LOG_POST(Trace << ">>>>");
1202 // }
1203 }
1204 
1205 bool CFeatGlyph::x_RedundantLabelCheck(const string& label) const
1206 {
1207  // If label is redundant with the title (is contained in the title) for the
1208  // track, and all glyphs in the track are the same type, do not display the label.
1209  // This only applies though if the label for the track starts with '[' and ends with ']'
1210  const CSeqGlyph* parent = m_Parent;
1211  bool redundant = false;
1212  int all_same_type = -1;
1213 
1214  if (label.length() > 0 && label[0] == '[' && label[label.size()-1] == ']') {
1215  while (parent != NULL) {
1216  if (all_same_type == -1 ) {
1217  const CLayoutGroup* lg = dynamic_cast<const CLayoutGroup*>(parent);
1218  if (lg != NULL) {
1219  all_same_type = lg->AllChildrenSameType() ? 1 : 0;
1220  }
1221  }
1222  const CLayoutTrack* lt = dynamic_cast<const CLayoutTrack*>(parent);
1223  if (lt != NULL) {
1224  // trim blanks, brackets etc from glyph display string - e.g. [intron] to intron
1225  string track_title = lt->GetFullTitle();
1226  size_t start_idx = label.find_first_not_of(" ()[]'\" <>,.@#$&*");
1227  size_t stop_idx = label.find_last_not_of(" ()[]'\" <>,.@#$&*");
1228  size_t len = stop_idx-start_idx;
1229 
1230  if (len > 0 &&
1231  NStr::FindNoCase(track_title, label.substr(start_idx, len)) != NPOS) {
1232  redundant = true;
1233  }
1234  break;
1235  }
1236  parent = parent->GetParent();
1237  }
1238  }
1239 
1240  return (all_same_type == 1 && redundant);
1241 }
1242 
1243 
1245 {
1247 }
1248 
1250 {
1252  return;
1253  }
1254  x_DrawLabelWithXPinned(base);
1255 }
1256 
1258 {
1259  if ( !x_ShowLabel()) {
1260  return;
1261  }
1263  return;
1264 
1265  x_DrawLabelWithYPinned(base);
1266 }
1267 
1268 
1269 
1271 {
1273  return;
1274  }
1275  IRender& gl = GetGl();
1276 
1277  // visible part of the whole glyph (feature bar + label + additional info)
1278  TModelRange visible_range = m_Context->IntersectVisible(this);
1279 
1280  const CGlTextureFont& font = m_Config->m_LabelFont;
1281  TModelUnit font_height = gl.TextHeight(&font);
1282 
1283  if (m_Context->WillLabelFit(visible_range)) {
1284  // label text that will be shown
1285  string sLabelTextOut;
1286  // label type text (used to estimate whether there is enough space to show both type and content)
1287  string sLabelTypeText;
1288  GetLabel(sLabelTypeText, CLabel::eType);
1289  TModelUnit LabelTypeWidth =
1290  m_Context->ScreenToSeq(gl.TextWidth(&font, sLabelTypeText.c_str()));
1291 
1292  // if visible part is wide enough, show both label type and content
1293  if (visible_range.GetLength() > LabelTypeWidth * 4) { // 4 widths of eType label width
1294  GetLabel(sLabelTextOut, CLabel::eUserTypeAndContent);
1295  if (!m_sTopLabelPrefix.empty()) {
1296  string label(m_sTopLabelPrefix);
1297  label += '/';
1298  label += sLabelTextOut;
1299  sLabelTextOut = label;
1300  }
1301  } else {
1302  // otherwise only content
1303  GetLabel(sLabelTextOut, CLabel::eContent);
1304  }
1305  // shorten the text if it is wider than visible range
1306  sLabelTextOut = font.Truncate(sLabelTextOut.c_str(), m_Context->SeqToScreen(visible_range.GetLength()));
1307 
1308  // both above and inside labels should be centered relatively to feature bar on x axis
1309  TModelUnit LabelX = visible_range.GetFrom() + visible_range.GetLength() * 0.5;
1310  TModelUnit LabelY = base;
1312  // move the base to give space for the text above the feature bar
1313  base += font_height;
1314  LabelY = base;
1315  base += kVertSpace + 1;
1316  }
1317  if (IsSelected()) {
1321  } else {
1323  }
1324  m_Context->TextOut(&font, sLabelTextOut.c_str(), LabelX, LabelY, true, true);
1325  }
1326 }
1327 
1328 
1329 void CFeatGlyph::x_DrawInnerLabels(TModelUnit base, vector<TModelRange> *labels_range, TSeqRange* interval) const
1330 {
1331  if (m_HideLabel)
1332  return;
1334  return;
1335  TSeqRange exon_int;
1336  if (interval) {
1337  exon_int = interval->IntersectionWith(m_Context->GetVisSeqRange());
1338  if (exon_int.Empty())
1339  return;
1340  }
1341 
1342  // visible part of the whole glyph (feature bar + label + additional info)
1343  TModelRange visible_range = m_Context->IntersectVisible(this);
1344 
1345  const CGlTextureFont &font = m_Config->m_LabelFont;
1346 
1347  // location of feature bar, must not be overwritten by the label
1348  TSeqRange FeatureBarRange(GetRange());
1349  TModelUnit FeatureBarLeft(FeatureBarRange.GetFrom());
1350  TModelUnit FeatureBarRight(FeatureBarRange.GetToOpen());
1351 
1352  bool side_lbl{ false };
1354  // how much of the space (in sequence coords) is available for the label
1355  TModelUnit LabelVisibleWidth{ 0 };
1356  if (x_LabelOnLeft()) {
1357  LabelVisibleWidth = (FeatureBarLeft < visible_range.GetFrom() ? 0 : FeatureBarLeft - visible_range.GetFrom());
1358  }
1359  else {
1360  LabelVisibleWidth = (FeatureBarRight > visible_range.GetTo() ? 0 : visible_range.GetTo() - FeatureBarRight);
1361  }
1362  side_lbl = (LabelVisibleWidth >= m_Context->GetMinLabelWidthPos());
1363  }
1364 
1365  string fl_content;
1366  GetLabel(fl_content, CLabel::eContent);
1367 
1368  CRgbaColor inner_color(m_Config->m_fgColor);
1369  GetCustomColor(inner_color);
1370  if ((GetCustomColorIdx(GetFeature()) == CCustomFeatureColor::eLoss) && (s_GetLiteralLength(GetFeature().GetData().GetVariation()) >= 0))
1371  inner_color = m_Config->m_bgColor;
1372  inner_color = inner_color.ContrastingColor();
1373 
1374  bool inside_only = m_Config->m_LabelPos == CFeatureParams::ePos_Inside;
1375  CSeqGlyph::x_DrawInnerLabels(base, fl_content, inner_color, font, side_lbl, inside_only, labels_range, exon_int.Empty() ? nullptr : &exon_int);
1376 }
1377 
1378 
1380 {
1382 
1383  IRender& gl = GetGl();
1384 
1385  // visible part of the whole glyph (feature bar + label + additional info)
1386  TModelRange visible_range_pos = m_Context->IntersectVisible(this);
1387 
1388  const CGlTextureFont &font = m_Config->m_LabelFont;
1389  TModelUnit font_height = gl.TextHeight(&font);
1390 
1391  // location of feature bar, must not be overwritten by the label
1392  TSeqRange FeatureBarRange(GetRange());
1393  TModelUnit FeatureBarLeft(FeatureBarRange.GetFrom());
1394  // this is an open position i.e. +1 of the real end pos
1395  TModelUnit FeatureBarRight(FeatureBarRange.GetToOpen());
1396 
1397  // how much of the space (in sequence position coords) is available for the label
1398  TModelUnit AvailableLabelVisibleWidthPos(x_LabelOnLeft() ?
1399  (FeatureBarLeft < visible_range_pos.GetFrom() ? 0 : FeatureBarLeft - visible_range_pos.GetFrom())
1400  :
1401  (FeatureBarRight > visible_range_pos.GetToOpen() ? 0 : visible_range_pos.GetToOpen() - FeatureBarRight));
1402 
1403  string fl_content;
1404  GetLabel(fl_content, CLabel::eContent);
1405 
1406  CRgbaColor inner_color(m_Config->m_fgColor);
1407  GetCustomColor(inner_color);
1408  if ((GetCustomColorIdx(GetFeature()) == CCustomFeatureColor::eLoss) && (s_GetLiteralLength(GetFeature().GetData().GetVariation()) >= 0))
1409  inner_color = m_Config->m_bgColor;
1410  inner_color = inner_color.ContrastingColor();
1411 
1412 
1413  if (AvailableLabelVisibleWidthPos < m_Context->GetMinLabelWidthPos(font)) {
1414  return;
1415  }
1416 
1417  // these widths are in screen pixels
1418  TModelUnit label_width_px = gl.TextWidth(&font, fl_content.c_str());
1419  TModelUnit max_width_px = min(m_Context->SeqToScreen(AvailableLabelVisibleWidthPos),
1420  m_Context->GetMaxLabelWidth(font));
1421  if (label_width_px > max_width_px) {
1422  label_width_px = max_width_px;
1423  fl_content = font.Truncate(fl_content.c_str(), label_width_px);
1424  if ((string::npos != fl_content.find("...")) && (fl_content.length() <= 5))
1425  return;
1426  }
1427  // convert back to sequence position coords
1428  TModelUnit label_width_pos = m_Context->ScreenToSeq(label_width_px);
1429  TModelUnit label_x_pos = 0.0;
1430  TModelUnit label_base = base;
1431  TModelUnit label_clear_base = base;
1432  TModelUnit label_clear_height = font_height;
1433  label_base += (font_height * 0.5);
1434 
1435  // draw background - larger of font height or
1436  // bar height (if label on same line, e.g. not label first)
1437  TModelUnit bar_height = m_Config->m_BarHeight;
1438  label_clear_base = label_base;
1439  if (bar_height > font_height) {
1440  label_clear_height = bar_height;
1441  label_clear_base = floor(base) + (label_clear_height * 0.5);
1442  }
1443  if (x_LabelOnLeft()) {
1444  label_x_pos = visible_range_pos.GetFrom();
1445  if (label_x_pos > GetLeft()) {
1446  gl.ColorC(m_Config->m_bgColor);
1448  TModelRect(label_x_pos, label_clear_base + 1, label_x_pos + label_width_pos,
1449  label_clear_base - label_clear_height - 1), 0);
1450  }
1451  } else {
1452  label_x_pos = visible_range_pos.GetToOpen() - label_width_pos;
1453  if (visible_range_pos.GetTo() < GetRight()) {
1454  gl.ColorC(m_Config->m_bgColor);
1456  TModelRect(label_x_pos, label_clear_base + 1, visible_range_pos.GetToOpen(),
1457  label_clear_base - label_clear_height - 1), 0);
1458  }
1459  }
1460  gl.ColorC(IsSelected() ?
1462 
1463  m_Context->TextOut(&font, fl_content.c_str(), label_x_pos,
1464  label_base, false, true);
1465 }
1466 
1468 {
1469  if ( !x_ShowLabel() ) {
1470  return;
1471  }
1472 
1473  IRender& gl = GetGl();
1474 
1475  // visible part of the whole glyph (feature bar + label + additional info)
1476  TModelRange visible_range = m_Context->IntersectVisible(this);
1477  const CGlTextureFont& font = m_Config->m_LabelFont;
1478  TModelUnit font_height = gl.TextHeight(&font);
1479 
1481  // location of feature bar, must not be overwritten by the additional info
1482  TSeqRange FeatureBarRange(GetRange());
1483  TModelUnit FeatureBarLeft(FeatureBarRange.GetFrom());
1484  TModelUnit FeatureBarRight(FeatureBarRange.GetToOpen());
1485 
1486  // how much of the space (in sequence coords) is available for the additional info
1487  // left/right location of additional info is complementary to that of the label
1488  TModelUnit AvailableAdditionalInfoVisibleWidthPos(!x_LabelOnLeft() ?
1489  (FeatureBarLeft < visible_range.GetFrom() ? 0 : FeatureBarLeft - visible_range.GetFrom())
1490  :
1491  (FeatureBarRight > visible_range.GetToOpen() ? 0 : visible_range.GetToOpen() - FeatureBarRight));
1492 
1493  string sAdditionalInfo;
1494  GetAdditionalInfo(sAdditionalInfo);
1495 // LOG_POST(Trace << "sAdditionalInfo: " << sAdditionalInfo);
1496 // LOG_POST(Trace << "AvailableAdditionalInfoVisibleWidthPos: " << AvailableAdditionalInfoVisibleWidthPos);
1497  // widths are in screen pixels
1498  TModelUnit info_width_px = gl.TextWidth(&font, sAdditionalInfo.c_str());
1499 // LOG_POST(Trace << "initial info_width_px: " << info_width_px);
1500 
1501  if(AvailableAdditionalInfoVisibleWidthPos < m_Context->GetMinLabelWidthPos()) {
1502  return;
1503  }
1504  TModelUnit max_width_px = min(m_Context->SeqToScreen(AvailableAdditionalInfoVisibleWidthPos),
1505  m_Context->GetMaxLabelWidth(font));
1506 // LOG_POST(Trace << "max_width_px: " << max_width_px);
1507  if (info_width_px > max_width_px) {
1508  info_width_px = max_width_px;
1509  sAdditionalInfo = font.Truncate(sAdditionalInfo.c_str(), info_width_px);
1510  }
1511 // LOG_POST(Trace << "modified sAdditionalInfo: " << sAdditionalInfo << " and info_width_px: " << info_width_px);
1512  // convert back to sequence coords
1513  TModelUnit info_width_pos = m_Context->ScreenToSeq(info_width_px);
1514  TModelUnit info_x_pos = 0.0;
1515  TModelUnit info_base = base;
1516  TModelUnit info_clear_base = base;
1517  TModelUnit info_clear_height = font_height;
1518  info_base += (font_height * 0.5);
1519 
1520 // LOG_POST(Trace << "info_width_pos: " << info_width_pos);
1521  // draw background - larger of font height or
1522  // bar height (if label on same line, e.g. not label first)
1523  TModelUnit bar_height = m_Config->m_BarHeight;
1524  info_clear_base = info_base;
1525  if (bar_height > font_height) {
1526  info_clear_height = bar_height;
1527  info_clear_base = floor(base) + (info_clear_height * 0.5);
1528  }
1529  if (!x_LabelOnLeft()) {
1530  info_x_pos = visible_range.GetFrom();
1531  if (info_x_pos > GetLeft()) {
1532 // LOG_POST(Trace << " drawing background at left: " << info_x_pos << " with offset: " << m_Context->GetOffset());
1533  gl.ColorC(m_Config->m_bgColor);
1535  TModelRect(info_x_pos, info_clear_base + 1, info_x_pos + info_width_pos,
1536  info_clear_base - info_clear_height - 1), 0);
1537  }
1538  } else {
1539  info_x_pos = visible_range.GetToOpen() - info_width_pos;
1540  if (visible_range.GetTo() < GetRight()) {
1541 // LOG_POST(Trace << " drawing background at right: " << info_x_pos << " with offset: " << m_Context->GetOffset());
1542  gl.ColorC(m_Config->m_bgColor);
1544  TModelRect(info_x_pos, info_clear_base + 1, visible_range.GetToOpen(),
1545  info_clear_base - info_clear_height - 1), 0);
1546  }
1547  }
1548  gl.ColorC(IsSelected() ?
1550 
1551 // LOG_POST(Trace << "info_x_pos: " << info_x_pos);
1552  m_Context->TextOut(&font, sAdditionalInfo.c_str(), info_x_pos,
1553  info_base, false, true);
1554  }
1555 }
1556 
1558 {
1559  return m_ProjectedMappingInfo.GetAlignmentDataSource() != nullptr;
1560 }
1561 
1562 // This is exactly as it done in Sequin.
1564 {
1565  _ASSERT(GetFeature().GetData().IsCdregion());
1566 
1567  TSeqPos offset = 1; // translation offset
1568 
1569  const CCdregion& cdr = GetFeature().GetData().GetCdregion();
1570  if (cdr.IsSetFrame()) {
1571  switch (cdr.GetFrame()) {
1572  case CCdregion::eFrame_two:
1573  offset = 2;
1574  break;
1576  offset = 3;
1577  break;
1578  default:
1579  break;
1580  }
1581  }
1582  return offset;
1583 }
1584 
1586 {
1587  CRef<CSeq_loc> new_loc(new CSeq_loc);
1588  new_loc->Assign(loc);
1589 
1590  CSeq_loc_I loc_it(*new_loc);
1591  if (loc_it || loc_it.IsEmpty()) {
1592  if (loc_it.IsSetStrand() && (eNa_strand_minus == loc_it.GetStrand())) {
1593  loc_it.SetTo(loc_it.GetRange().GetTo() - offset);
1594  }
1595  else {
1596  loc_it.SetFrom(loc_it.GetRange().GetFrom() + offset);
1597  }
1598  }
1599  CRef<CSeq_loc> result = loc_it.MakeSeq_loc();
1600 
1601  return result;
1602 }
1603 
1604 void CFeatGlyph::x_DrawRuler(TModelUnit base, bool protein_scale) const
1605 {
1606  bool has_product = GetFeature().IsSetProduct();
1607  if (x_IsProjected() && has_product) {
1608  x_DrawProjectedRuler(base, protein_scale);
1609  return;
1610  }
1611 
1612  bool horz = m_Context->IsHorizontal();
1613  bool flip_strand = m_Context->IsFlippedStrand();
1614 
1615  IRender& gl = GetGl();
1616 
1617  CRuler ruler_panel;
1619  ruler_panel.SetGeometryParam (CRuler::eMinorTickHeight, 1);
1620  ruler_panel.SetGeometryParam (CRuler::eMajorTickHeight, 3);
1621  ruler_panel.SetGeometryParam (CRuler::eLabelTickHeight, 3);
1625 
1626  ruler_panel.SetHorizontal(horz, horz ? CRuler::eTop : CRuler::eRight);
1627  int display_options = 0; // don't show background
1628 
1629  auto GetCDSFrame = [&]() {
1630  if (m_Feature.GetData().Which() != CSeqFeatData::e_Cdregion)
1631  return 0;
1632  if (m_Feature.GetData().GetCdregion().IsSetFrame() && m_Feature.GetData().GetCdregion().GetFrame() > 1) {
1633  return m_Feature.GetData().GetCdregion().GetFrame() - 1;
1634  }
1635  return 0;
1636  };
1637 
1638  TSeqPos offset = GetCDSFrame(); // translation offset
1639 
1640  CRef<CPairwiseAln> aln;
1641  if (!GetMappingInfo().empty() || has_product) {
1642  const CSeq_loc& loc1 = GetLocation();
1643  const CSeq_loc& loc2 = has_product ? GetFeature().GetProduct() : GetLocation();
1644  TAlnSeqIdIRef id1(new CAlnSeqId(*loc1.GetId()));
1645  TAlnSeqIdIRef id2(new CAlnSeqId(*loc2.GetId()));
1646 
1647  // Sequence type is hardcoded, needs to be fixed:
1648  id1->SetBaseWidth(1); // location is on a nucleotide
1649  id2->SetBaseWidth(1); // product is on a protein
1650  if (m_RulerType & eAaRuler) {
1651  if (protein_scale) {
1652  ruler_panel.SetBaseWidth(3);
1653  ruler_panel.SetTextLabel("aa");
1654  } else if (m_RulerType & eNtRuler) {
1655  ruler_panel.SetTextLabel("nt");
1656  }
1657  if (!m_Config->m_CgiMode)
1658  display_options |= CRuler::fFirstLabelHasText;
1659  }
1660 
1661  // Do we really need to allow overlap? or data are incorrect?
1662  // Example feature: NP_057849.4 on NC_001802.1
1663  aln.Reset(new CPairwiseAln(id1, id2,
1665  if (/*has_product == false &&*/ !GetMappingInfo().empty()) {
1666  CRef<CSeq_loc> gen_loc(new CSeq_loc);
1667  CRef<CSeq_loc> prod_loc(new CSeq_loc);
1668  for (auto&& iter : GetMappingInfo()) {
1669  prod_loc->SetPacked_int().Set().push_back(iter.first);
1670  gen_loc->SetPacked_int().Set().push_back(iter.second);
1671  }
1672 
1673  if (offset != 0) {
1674  CSeq_loc_I loc_it(*prod_loc);
1675  if (loc_it || loc_it.IsEmpty()) {
1676  loc_it.SetFrom(loc_it.GetRange().GetFrom() - offset);
1677  }
1679  }
1680  else
1682  } else {
1683  if (m_Context->GetScale() > kMinScaleForRulerLabels) // the view is zoomed out and mapping info is not accurate
1684  display_options |= CRuler::fHideLabels;
1685  if (offset > 0) {
1686  CRef<CSeq_loc> adj_gen_loc = x_AdjustFrame(loc1, offset);
1688  }
1689  else
1691  }
1692  } else {
1693  const CSeq_loc& loc1 = GetLocation();
1694  if ( !loc1.GetId() || loc1.GetStrand() == eNa_strand_other) {
1695  return;
1696  }
1697 
1698  TAlnSeqIdIRef id1(new CAlnSeqId(*loc1.GetId()));
1699 
1700  CSeq_loc loc2;
1701  loc2.SetWhole();
1702  loc2.SetId(*loc1.GetId());
1703 
1704  // Sequence type is hardcoded, needs to be fixed:
1705  id1->SetBaseWidth(1); // location is on a nucleotide
1706 
1707  aln.Reset(new CPairwiseAln(id1, id1,
1710  }
1711 
1712  // revesre collention for filled strand
1714  TSeqPos seq_length = seq_ds->GetSequenceLength();
1715  if (flip_strand) {
1716  auto aln_reversed = Ref(new CPairwiseAln(aln->GetFirstId(), aln->GetSecondId(), CPairwiseAln::fAllowOverlap | CPairwiseAln::fKeepNormalized));
1717  REVERSE_ITERATE(CPairwiseAln, it, *aln) {
1718  CPairwiseAln::TAlnRng r = *it;
1719  r.SetFirstFrom(seq_length - r.GetFirstToOpen());
1720  r.SetReversed( !r.IsReversed() );
1721  aln_reversed->push_back(r);
1722  }
1723  aln_reversed->Sort();
1724  aln.Reset(aln_reversed.GetPointer());
1725  }
1726  ruler_panel.SetMapping(*aln);
1727  ruler_panel.SetDisplayOptions(display_options);
1728 
1729  CGlPane* pane = m_Context->GetGlPane();
1730  gl.PushMatrix();
1731  gl.LoadIdentity();
1732  pane->Close();
1733  CGlPane RP(*pane);
1734 
1735  TModelUnit ruler_y = base - GetTop(), ruler_x = 0.0;
1736  x_Local2World(ruler_x, ruler_y);
1737  TModelUnit base_top = pane->ProjectY(ruler_y);
1738  TVPRect vpt = pane->GetViewport();
1739  vpt.SetTop((int)floor(base_top));
1740  vpt.SetBottom((int)ceil(base_top - kRulerHeight));
1741  RP.SetViewport(vpt);
1742 
1743  TModelRect rcV = pane->GetVisibleRect();
1744  if (flip_strand) {
1745  rcV.SetLeft(seq_length - rcV.Left());
1746  rcV.SetRight(seq_length - rcV.Right());
1747  }
1748  rcV.SetBottom(0);
1749  rcV.SetTop(kRulerHeight);
1750  RP.SetVisibleRect(rcV);
1751 
1752  ruler_panel.Render(RP);
1753  pane->OpenOrtho();
1754  gl.PopMatrix();
1755 }
1756 
1758 {
1759  return (TVPUnit)((x > 0.0) ? floor(x + 0.5) : ceil(x - 0.5));
1760 }
1761 
1762 void CFeatGlyph::x_DrawProjectedRuler(TModelUnit base, bool protein_scale) const
1763 {
1764 
1765  bool horz = m_Context->IsHorizontal();
1766  bool flip_strand = m_Context->IsFlippedStrand();
1767 
1768  IRender& gl = GetGl();
1769 
1770  CRuler ruler_panel;
1778 
1779  ruler_panel.SetHorizontal(horz, horz ? CRuler::eTop : CRuler::eRight);
1780  int display_options = 0; // don't show background
1781  CRef<CPairwiseAln> aln;
1782 
1783  const CSeq_loc& loc1 = GetLocation();
1784  const CSeq_loc& loc2 = GetFeature().GetProduct();
1785  TAlnSeqIdIRef id1(new CAlnSeqId(*loc1.GetId()));
1786  TAlnSeqIdIRef id2(new CAlnSeqId(*loc2.GetId()));
1787 
1789 
1790  int anchor = aln_mgr->GetAnchor();
1791  int aligned_seq = aln_mgr->GetQuery();
1792  // revesre collention for filled strand
1793  TSeqPos seq_length = aln_mgr->GetSeqLength(aligned_seq);
1794  int base_width = aln_mgr->GetBaseWidth(anchor);
1795 
1796  // Sequence type is hardcoded, needs to be fixed:
1797  id1->SetBaseWidth(1); // location is on a nucleotide
1798  id2->SetBaseWidth(1); // location is on a nucleotide
1799  if (m_RulerType & eAaRuler) {
1800  if (protein_scale) {
1801  ruler_panel.SetBaseWidth(3);
1802  ruler_panel.SetTextLabel("aa");
1803  } else if (m_RulerType & eNtRuler) {
1804  ruler_panel.SetTextLabel("nt");
1805  }
1806  if (!m_Config->m_CgiMode)
1807  display_options |= CRuler::fFirstLabelHasText;
1808  }
1809  if (m_Context->GetScale() > kMinScaleForRulerLabels) // the view is zoomed out and mapping info is not accurate
1810  display_options |= CRuler::fHideLabels;
1811 
1812  ruler_panel.SetDisplayOptions(display_options);
1813 
1814  CGlPane* pane = m_Context->GetGlPane();
1815  glPushAttrib(GL_ALL_ATTRIB_BITS);
1816  gl.PushMatrix();
1817  gl.LoadIdentity();
1818  pane->Close();
1819 
1820  TModelUnit ruler_y = base - GetTop(), ruler_x = 0.0;
1821  x_Local2World(ruler_x, ruler_y);
1822  TModelUnit base_top = pane->ProjectY(ruler_y);
1823 
1824  bool anchor_neg = aln_mgr->IsNegativeStrand(anchor);
1825  bool aligned_neg = aln_mgr->IsNegativeStrand(aligned_seq);
1826 
1828  {
1829 
1830  auto& anchor_range = iter->m_AnchorRange;
1831  if (m_Context->IntersectVisible(anchor_range).Empty())
1832  continue;
1833  auto& gen_int = *iter->m_MappedInt;
1834  TSignedSeqPos gen_from = gen_int.GetFrom();
1835  TSignedSeqPos gen_to = gen_int.GetTo();
1836  auto& prod_int = *iter->m_ProductInt;
1837  auto& prod_range = iter->m_MappedProdRange;
1838 
1839  bool flip = (flip_strand != (anchor_neg || aligned_neg));
1840 
1841  CRef<CSeq_loc> prod_loc(new CSeq_loc);
1842  auto prod_interval = Ref(new CSeq_interval());
1843  prod_interval->SetId().Assign(prod_int.GetId());
1844  prod_interval->SetFrom(prod_range.GetFrom());
1845  prod_interval->SetTo(prod_range.GetTo());
1846  prod_interval->SetStrand(prod_int.GetStrand());
1847  prod_loc->SetPacked_int().Set().push_back(prod_interval);
1848 
1849  CRef<CSeq_loc> gen_loc(new CSeq_loc);
1850  auto mapped_interval = Ref(new CSeq_interval());
1851  mapped_interval->SetId().Assign(gen_int.GetId());
1852  mapped_interval->SetFrom(gen_from);
1853  mapped_interval->SetTo(gen_to);
1854  mapped_interval->SetStrand(gen_int.GetStrand());
1855 
1856  gen_loc->SetPacked_int().Set().push_back(mapped_interval);
1857 
1858  aln.Reset(new CPairwiseAln(id1, id2,
1860  ConvertSeqLocsToPairwiseAln(*aln, *gen_loc, *prod_loc,
1862  if (flip) {
1863  ITERATE(CPairwiseAln, it, *aln)
1864  {
1865  const CPairwiseAln::TAlnRng& r = *it;
1866  CPairwiseAln::TAlnRng* r1 = const_cast<CPairwiseAln::TAlnRng*>(&r);
1867  r1->SetFirstFrom(seq_length - r.GetFirstToOpen());
1868  r1->SetReversed(!r.IsReversed());
1869  }
1870  aln->Sort();
1871  }
1872  ruler_panel.SetMapping(*aln);
1873  TModelUnit seq_from = anchor_range.GetFrom();
1874  TModelUnit seq_to = min<int>(anchor_range.GetTo(), seq_from + (prod_range.GetLength() / base_width) - 1);
1875 
1876  if (m_Context->IsFlippedStrand()) {
1877  swap(seq_from, seq_to);
1878  seq_from = m_Context->GetOffset() - seq_from - 1;
1879  seq_to = m_Context->GetOffset() - seq_to- 1;
1880  } else {
1881  seq_from -= m_Context->GetOffset();
1882  seq_to -= m_Context->GetOffset();
1883  }
1884 
1885  TVPUnit view_from = s_AdjustScreenCoordinate(m_Context->SeqToScreen(seq_from));
1886  TVPUnit view_to = s_AdjustScreenCoordinate(m_Context->SeqToScreen(seq_to + 1));
1887 
1888  TModelRect rcV = pane->GetVisibleRect();
1889  rcV.SetBottom(0);
1890  rcV.SetTop(kRulerHeight);
1891 
1892  rcV.SetHorz(gen_from, gen_to + 1);
1893  if (flip) {
1894  rcV.SetHorz(rcV.Right(), rcV.Left());
1895  rcV.SetLeft(seq_length - rcV.Left());
1896  rcV.SetRight(seq_length - rcV.Right());
1897  }
1898  CGlPane RP(*pane);
1899 
1900  RP.SetModelLimitsRect(rcV);
1901  RP.SetVisibleRect(rcV);
1902 
1903  TVPRect vpt = pane->GetViewport();
1904  vpt.SetTop((int)floor(base_top));
1905  vpt.SetBottom((int)ceil(base_top - kRulerHeight));
1906  vpt.SetLeft(view_from);
1907  vpt.SetRight(view_to);
1908  RP.SetViewport(vpt);
1909  ruler_panel.Render(RP);
1910  }
1911  pane->OpenOrtho();
1912  gl.PopMatrix();
1913  glPopAttrib();
1914 }
1915 
1917 {
1919  && strand != eNa_strand_both && strand != eNa_strand_both_rev;
1920 }
1921 
1923 {
1924  IRender& gl = GetGl();
1925 
1926  TModelUnit bar_height = m_Config->m_BarHeight;
1927  if (m_Context->IsOverviewMode() && m_HideLabel) {
1928  bar_height = floor(bar_height * m_Config->m_OverviewFactor);
1929  }
1930  TModelUnit head_height = bar_height * m_Config->m_HeadHeight;
1931  TModelUnit tail_height = bar_height * m_Config->m_TailHeight;
1932  TModelUnit head_size = m_Context->ScreenToSeq(head_height);
1933  TModelUnit tail_size = m_Context->ScreenToSeq(tail_height);
1934 
1936  base += bar_height*kRSiteMarkerHeight; // Add the height of the top cut marker
1937 
1938  TModelUnit YCenterLine = base;
1939  TModelUnit BoundaryYLow = YCenterLine - bar_height * 0.5f;
1940  TModelUnit BoundaryYHigh = YCenterLine + bar_height * 0.5f;
1941 
1942  auto strand = sequence::GetStrand(GetLocation());
1943  bool neg_strand = (strand == eNa_strand_minus);
1944 
1945  EFeatureParts head_style = eHead_No;
1946  EFeatureParts tail_style = eTail_No;
1947 
1948  CRgbaColor color;
1949  if ( !GetCustomColor(color) ) {
1951 
1952  // For introns (line-style) may have special color:
1955  }
1956  // Set user defined color
1957  if (GetFeature().GetData().IsRegion()) {
1958  CConstRef< CUser_object > display_settings = GetFeature().FindExt("DisplaySettings");
1959  if (!display_settings.Empty()) {
1960  x_GetUserColor(*display_settings, color);
1961  }
1962  }
1963 
1964  bool is_pseudo = CSeqUtils::IsPseudoFeature(GetFeature());
1965  if (is_pseudo) {
1966  color.SetAlpha(0.8f);
1967  }
1968  CRgbaColor color_lite = color;
1969  color_lite.Lighten(0.2f);
1970 
1971  // distance among strand indicators
1972  TModelUnit pix_size = m_Context->ScreenToSeq(1.0);
1973  TModelUnit apart = 100.0 * pix_size; // 100 pixels on screen
1974 
1975  // Draw feature bar
1976  TSeqRange SeqRange = GetRange();
1977  TSeqPos from;
1978  TSeqPos to;
1979  x_IntersectVisible<TSeqPos>(SeqRange, from, to);
1980 
1981  if (SeqRange.GetLength() > pix_size * 2) { // At least 2 pixel
1982  TModelUnit prev_to_x = 0.0f;
1983  TModelUnit prev_from_x = 0.0f;
1984 
1985  bool first_pass = true;
1986  // draw exons and introns
1987 
1988  // Ranges, occupied by labels
1989  vector<TModelRange> labels_range;
1990  // Previous exon range
1991  TModelRange prev_exon_rng;
1992  // Range to draw strands on
1993  TModelRange strand_rng;
1994 
1995  bool has_accessory_label = false;
1996  CRgbaColor strand_indicator_color = color;
1997 
1998  // Determine strand indicator color
1999  switch (m_Config->m_BoxStyle) {
2002  strand_indicator_color = m_Config->m_fgColor.ContrastingColor();
2003  break;
2006  break;
2007  default:
2008  strand_indicator_color = color.ContrastingColor(false);
2009  // Line style means arrows are on a white background so should be darker.
2010  strand_indicator_color.Darken(0.1f);
2011  break;
2012  }
2013 
2014  vector<CConstRef<CSeq_loc>> locs;
2015  CSeq_loc_CI iter(GetLocation());
2016  for (; iter; ++iter) {
2017  locs.push_back(iter.GetRangeAsSeq_loc());
2018  }
2019  if (!m_RSite) {
2020  sort(locs.begin(), locs.end(), [](CConstRef<CSeq_loc>& a, CConstRef<CSeq_loc>& b) {
2021  return a->GetTotalRange().GetFrom() < b->GetTotalRange().GetFrom();
2022  });
2023  }
2024 
2025  for (const auto& curr_loc : locs) {
2026  TSeqRange curr = curr_loc->GetTotalRange();
2027 
2028  // Restriction sites have location mix, consisting of two points and an interval
2029  strand = sequence::GetStrand(*curr_loc);
2030  neg_strand = (strand == eNa_strand_minus);
2031 
2032  TModelUnit f = curr.GetFrom();
2033  TModelUnit t = curr.GetTo();
2034 
2035  bool is_visible_region = x_IntersectVisible<TModelUnit>(TModelRange(f, t), f, t);
2036 
2037  bool rsiteCutPnt = false;
2038  if (m_RSite) {
2039  if (curr_loc->IsPnt()) {
2040  const CSeq_point& pnt = curr_loc->GetPnt();
2041  if (pnt.CanGetFuzz()) {
2042  const CSeq_point_Base::TFuzz &fuzz = pnt.GetFuzz();
2043  if (fuzz.IsLim() && (CInt_fuzz_Base::eLim_tl == fuzz.GetLim())) {
2044  rsiteCutPnt = true;
2045  }
2046  }
2047  }
2048  }
2049 
2050  // adjust the size of exons to include style elements
2051  // such as head and tail pieces. Left (from) or right (to) sides
2052  // are adjected according to strand
2053  // 1) adjust head
2054  bool fit = head_size * 1.5 < fabs(t - f);
2055  bool adj_to = !neg_strand && t == SeqRange.GetTo() && fit;
2056  bool adj_from = neg_strand && f == SeqRange.GetFrom() && fit;
2057 
2058  if (adj_from || adj_to) {
2059  head_style = eNeedHead;
2060  }
2061 
2062  switch (m_Config->m_HeadStyle) {
2065  if (adj_to) {
2066  t = to - head_size * 1.5;
2067  }
2068  if (adj_from) {
2069  f = from + head_size * 1.5;
2070  }
2071  break;
2073  if (adj_to) {
2074  t = to - head_size;
2075  }
2076  if (adj_from) {
2077  f = from + head_size;
2078  }
2079  break;
2080 
2081  default:
2082  break;
2083  }
2084 
2085  // 2) adjust tail
2086  fit = tail_size < fabs(t - f);
2087  adj_to = neg_strand && t == SeqRange.GetTo() && fit;
2088  adj_from = !neg_strand && f == SeqRange.GetFrom() && fit;
2089 
2090  if (adj_from || adj_to) {
2091  tail_style = eNeedTail;
2092  }
2093 
2094  switch (m_Config->m_TailStyle) {
2096  if (adj_from) {
2097  f = from + tail_size * 0.5f;
2098  }
2099  if (adj_to) {
2100  t = to - tail_size * 0.5f;
2101  }
2102  break;
2104  if (adj_from) {
2105  f = from + tail_size;
2106  }
2107  if (adj_to) {
2108  t = to - tail_size;
2109  }
2110  break;
2112  if (adj_from) {
2113  f = from + tail_size; //-1
2114  }
2115  if (adj_to) {
2116  t = to - tail_size;
2117  }
2118  break;
2119 
2120  default:
2121  break;
2122  }
2123 
2124  // draw introns first
2125 
2126  TModelUnit from_x = curr.GetFrom();
2127  TModelUnit to_x = curr.GetTo() + 1;
2128 
2129  if (!first_pass) {
2130  //TModelUnit off = (m_Config->m_LineThickness) * 0.5f;
2131  TModelUnit intron_f;
2132  TModelUnit intron_t;
2133  if (!m_RSite) {
2134  intron_f = prev_to_x;
2135  intron_t = from_x;
2136  /*
2137  // In some cases, the intervals are not correctly ordered
2138  // for the feature. Maybe, it is a circular sequence, we
2139  // just can't handle it correctly.
2140  bool correctly_ordered = (neg_strand == (curr.GetFrom() < (prev_to_x - 1)));
2141  if (correctly_ordered) {
2142  intron_f = prev_to_x;
2143  intron_t = from_x;
2144  } else {
2145  intron_t = prev_from_x;
2146  intron_f = to_x;
2147  }
2148  if (neg_strand)
2149  swap(intron_f, intron_t);
2150  */
2151  } else { // The workaround above corrupts restriction sites
2152  intron_f = prev_from_x;
2153  intron_t = from_x;
2154  if (intron_f > intron_t)
2155  swap(intron_f, intron_t);
2156  }
2157 
2158  x_IntersectVisible<TModelUnit>(TModelRange(intron_f, intron_t), intron_f, intron_t);
2159 
2160  if (intron_f < intron_t) {
2161  glPushAttrib(GL_LINE_BIT);
2162  switch (m_Config->m_LineStyle) {
2164  gl.LineStipple(1, 0x0F0F);
2165  gl.Enable(GL_LINE_STIPPLE);
2166  break;
2168  gl.LineStipple(1, 0x0202);
2169  gl.Enable(GL_LINE_STIPPLE);
2170  break;
2172  gl.LineStipple(1, 0x1C47);
2173  gl.Enable(GL_LINE_STIPPLE);
2174  break;
2175  case CFeatureParams::eLine_ShortDashed: //Repeating pairs: -- -- --
2176  gl.LineStipple(2, 0xAAAA);
2177  gl.Enable(GL_LINE_STIPPLE);
2178  break;
2180  break;
2181  } // m_Config->m_LineStyle
2182 
2183 
2184  gl.LineWidth((float)(m_Config->m_LineWidth));
2185  gl.ColorC(color_lite);
2186  switch (m_Config->m_Connections) {
2188  {{
2189  TModelUnit middle_x =
2190  intron_f + (intron_t - intron_f) * 0.5f;
2191  m_Context->DrawLine(intron_f, YCenterLine, middle_x, BoundaryYLow);
2192  m_Context->DrawLine(middle_x, BoundaryYLow, intron_t, YCenterLine);
2193  }}
2194  break;
2195  case CFeatureParams::eBox:
2196  {{
2197  // if short, may look like we are drawing on one side or not at all
2198  if (m_Context->SeqToScreen(fabs(intron_t - intron_f)) < TModelUnit(6.0))
2199  gl.Disable(GL_LINE_STIPPLE);
2200 
2201  m_Context->DrawLine(intron_f, BoundaryYLow, intron_t, BoundaryYLow);
2202  m_Context->DrawLine(intron_f, BoundaryYHigh, intron_t, BoundaryYHigh);
2203  }}
2204  break;
2206  m_Context->DrawLine(intron_f, YCenterLine, intron_t, YCenterLine);
2207  break;
2209  gl.Disable(GL_LINE_STIPPLE);
2210  m_Context->Draw3DQuad(intron_f, BoundaryYLow, intron_t,
2211  BoundaryYHigh, color_lite);
2212  break;
2213  } // m_Config->m_Connections
2214  gl.Disable(GL_LINE_STIPPLE);
2215  gl.LineWidth(1.0f);
2216  glPopAttrib();
2217 
2218  if (x_CanShowStrand(strand) && !rsiteCutPnt) {
2220  TModelPoint(intron_f, BoundaryYLow),
2221  intron_t - intron_f, apart, bar_height,
2222  CRgbaColor(0.7f, 0.7f, 0.7f), neg_strand);
2223  }
2224  }
2225 
2226  } // connection lines (introns)
2227 
2228  if (is_pseudo) {
2229  CRgbaColor lcolor = color;
2230  lcolor.Lighten(0.4f);
2231  CRgbaColor dcolor = color;
2232  dcolor.Darken(0.7f);
2233 
2234  m_Context->DrawPseudoBar(f, BoundaryYLow, t + 1, BoundaryYHigh, lcolor, dcolor);
2235  }
2236 
2237  // draw features as quads, hollow rectangles or just lines as configured
2238 
2239  if (!rsiteCutPnt && is_visible_region) { // Don't draw bar if this is RSite cut point
2241  m_Context->Draw3DQuad(f, BoundaryYLow, t, BoundaryYHigh, color);
2242 // LOG_POST(Trace << " drawing eBox_Filled feature at left: " << f <<
2243 // " and right: " << t);
2244 
2245  // Draw SNPs separators
2246  gl.ColorC(m_Config->m_bgColor);
2247  if (m_Neighbours & eNghbrs_Left)
2248  m_Context->DrawLine(f, BoundaryYLow, f, BoundaryYHigh);
2249 
2251  m_Context->DrawLine(t + 1, BoundaryYLow, t + 1, BoundaryYHigh);
2252 
2254  gl.ColorC(color);
2255  m_Context->DrawRect(f, BoundaryYLow, t+1, BoundaryYHigh);
2257  m_Context->Draw3DQuad(f, BoundaryYLow, t, BoundaryYHigh, color);
2258  CRgbaColor color_insert("black");
2259  gl.ColorC(color_insert);
2260  x_DrawInsertion((f + t) * 0.5 + 0.5, BoundaryYLow, BoundaryYHigh, YCenterLine);
2262  m_Context->Draw3DQuad(f, BoundaryYLow, t, BoundaryYHigh, color);
2263  CRgbaColor color_delete("black");
2264  gl.ColorC(color_delete);
2265  x_DrawDeletion((f + t) * 0.5 + 0.5, BoundaryYLow, BoundaryYHigh);
2266  } else {
2267  gl.LineWidth(1.0f);
2268  gl.Disable(GL_LINE_SMOOTH);
2269  gl.ColorC(color);
2270  // draw line slightly off center to make room for (possible)label
2271  m_Context->DrawLine(f, YCenterLine+1, t+1, YCenterLine+1);
2272 
2273  // Draw simple line tick marks.
2274  if (f == curr.GetFrom()) // Omit the tick marks if out of the visible range
2275  m_Context->DrawLine(f, BoundaryYLow, f, BoundaryYHigh);
2276  if (t == curr.GetTo()) // Omit the tick marks if out of the visible range
2277  m_Context->DrawLine(t+1, BoundaryYLow, t+1, BoundaryYHigh);
2278  gl.Enable(GL_LINE_SMOOTH);
2279  }
2280 
2281  TModelRange exon_rng(f, t);
2282  if (prev_exon_rng.Empty())
2283  prev_exon_rng = exon_rng;
2284  else {
2285  if (prev_exon_rng.IntersectingWith(exon_rng) || prev_exon_rng.AbuttingWith(exon_rng)) // Merge the ranges, if they overlap
2286  prev_exon_rng.CombineWith(exon_rng);
2287  else {
2288  TSeqRange rng(prev_exon_rng.GetFrom(), prev_exon_rng.GetTo());
2289  if (rng.GetLength() > 1) {
2290  x_DrawInnerLabels(base, &labels_range, &rng);
2291  }
2292  strand_rng = prev_exon_rng;
2293  prev_exon_rng = exon_rng;
2294  }
2295  }
2296  }
2297 
2298  // Check for accessory label but do not draw it until after the strand
2299  // indicators (strand indicators on top of label make it hard to read).
2300  string accessory_label;
2301  TModelUnit clipped_from = std::min(t,f);
2302  TModelUnit clipped_to = std::max(t,f);
2303  const CGlTextureFont& font = m_Config->m_LabelFont;
2304  TModelUnit label_width = TModelUnit(0);
2305 
2306  if (first_pass) {
2307  GetAccessoryLabel(accessory_label);
2308  if (!accessory_label.empty()) {
2310  label_width = m_Context->ScreenToSeq(font.TextWidth(accessory_label.c_str()));
2311 
2312  // Find SeqRange that is visible inside current view. Rect can be flipped (left>right)
2313  TModelUnit clipped_from = std::min(t,f);
2314  TModelUnit clipped_to = std::max(t,f);
2315  if (r.Right() > r.Left()) {
2316  clipped_from = std::max(r.Left(), clipped_from);
2317  clipped_to = std::min(r.Right(), clipped_to);
2318  }
2319  else {
2320  clipped_to = std::min(r.Left(), clipped_to);
2321  clipped_from = std::max(r.Right(), clipped_from);
2322  }
2323 
2324  if (clipped_to-clipped_from > TModelUnit(1.5) * label_width) {
2325  has_accessory_label = true;
2326  }
2327  }
2328  }
2329 
2330  if (first_pass && has_accessory_label) {
2331  gl.ColorC(color);
2332  auto len = (clipped_to - clipped_from) - 1;
2333  const static int kLabelStep = 600;
2334  auto label_step = m_Context->ScreenToSeq(kLabelStep);
2335  if (len >= label_step * 2) {
2336  has_accessory_label = false; // use label_range instead to control whether to put strand indicators
2337  const TModelRect& rng = m_Context->GetGlPane()->GetVisibleRect();
2338  auto l = rng.Left();
2339  auto r = rng.Right();
2340  if (m_Context->IsFlippedStrand())
2341  swap(r, l);
2342  auto from = max<int>(clipped_from, l);
2343  while (true) {
2344  from += label_step;
2345  auto x = max<int>(from - label_width / TModelUnit(2), 0);
2346  if (x >= r || x >= (clipped_to - label_width))
2347  break;
2348  m_Context->TextOut(&font, accessory_label.c_str(), x, YCenterLine, false, true);
2349  labels_range.emplace_back(x, x + label_width);
2350  }
2351  }
2352  }
2353 
2354  if (is_visible_region) {
2355  // draw strand indicators
2356  if (x_CanShowStrand(strand) && !strand_rng.Empty()) {
2358  TModelPoint(strand_rng.GetFrom(), BoundaryYLow), fabs(strand_rng.GetToOpen() - strand_rng.GetFrom()), apart, bar_height,
2359  strand_indicator_color, neg_strand,
2361  !m_HideLabel, has_accessory_label, &labels_range);
2362  strand_rng.Set(0, 0);
2363  }
2364 
2365  if (has_accessory_label) {
2366  auto from = ((clipped_from + clipped_to) / TModelUnit(2)) - label_width / TModelUnit(2);
2367  m_Context->TextOut(&font, accessory_label.c_str(), from, YCenterLine, false, true);
2368  }
2369 
2370  // draw partial loc indicators
2371  bool p_start = curr_loc->IsPartialStart(objects::eExtreme_Positional);
2372  bool p_stop = curr_loc->IsPartialStop(objects::eExtreme_Positional);
2373  if (p_start || p_stop) {
2374  m_Context->DrawPartialBar(curr.GetFrom(), BoundaryYLow,
2375  curr.GetToOpen(), BoundaryYHigh, p_start, p_stop, true);
2376  }
2377  }
2378 
2379  prev_to_x = to_x;
2380  prev_from_x = m_RSite ? from_x : from_x - 1;
2381  first_pass = false;
2382  }
2383  if (x_CanShowStrand(strand)) {
2384 
2385  if ((neg_strand && from == SeqRange.GetFrom()) || (!neg_strand && to == SeqRange.GetTo())) {
2386  // Draw head (line-style boxes already have tick marks at end -don't add another.)
2387  if (head_style == eNeedHead && m_Config->m_BoxStyle != CFeatureParams::eBox_Line) {
2388  gl.LineWidth((float)(m_Config->m_LineWidth + 0.1));
2389 
2390  switch (m_Config->m_HeadStyle) {
2393  TModelPoint(neg_strand ? from : to + 1, YCenterLine),
2394  head_height, color, neg_strand, true); // with neck
2395  break;
2398  TModelPoint(neg_strand ? from : to + 1, YCenterLine),
2399  head_height, color, neg_strand, false);
2400  break;
2402  gl.ColorC(color);
2404  TModelPoint(neg_strand ? from : to + 1, YCenterLine),
2405  head_height, neg_strand);
2406  break;
2407 
2408  default:
2409  break;
2410  } // m_Config->m_HeadStyle
2411  gl.LineWidth(1.0f);
2412  } // eNeedHead
2413  }
2414 
2415  if ((neg_strand && to == SeqRange.GetTo()) || (!neg_strand && from == SeqRange.GetFrom())) {
2416  // Draw tail (line-style boxes already have tick marks at end -don't add another.)
2417  if (tail_style == eNeedTail && m_Config->m_BoxStyle != CFeatureParams::eBox_Line) {
2418  gl.LineWidth((float)(m_Config->m_LineWidth + 0.1f));
2419  switch (m_Config->m_TailStyle) {
2422  TModelPoint(neg_strand ? to + 1.0 : from, YCenterLine),
2423  tail_height, color, neg_strand);
2424  break;
2427  TModelPoint(neg_strand ? to + 1 : from, YCenterLine),
2428  tail_height, color, neg_strand);
2429  break;
2431  gl.LineWidth(1.5f);
2433  neg_strand ? to + 1 : from, BoundaryYLow, BoundaryYHigh,
2434  tail_height, color, neg_strand);
2435  break;
2436 
2437  default:
2438  break;
2439  } // m_Config->m_TailStyle
2440  gl.LineWidth(1.0f);
2441  } // eNeedTail
2442  }
2443  }
2444 
2445  // draw partial feature indicators
2447  bool draw_partial_start = (from == SeqRange.GetFrom());
2448  bool draw_partial_stop = (to == SeqRange.GetTo());
2449  m_Context->DrawPartialBar(from, BoundaryYLow, to + 1,
2450  BoundaryYHigh, draw_partial_start, draw_partial_stop, false);
2451  } else {
2452  bool p_start = CSeqUtils::IsPartialStart(GetFeature().GetLocation()) && (from == SeqRange.GetFrom());
2453  bool p_stop = CSeqUtils::IsPartialStop(GetFeature().GetLocation()) && (to == SeqRange.GetTo());
2454  if (p_start || p_stop) {
2455  if (neg_strand) swap(p_start, p_stop);
2456  m_Context->DrawPartialBar(from, BoundaryYLow, to + 1,
2457  BoundaryYHigh, p_start, p_stop, true);
2458  }
2459  }
2460  if (m_RSite)
2461  x_DrawRSites(m_Config->m_fgColor, BoundaryYLow, BoundaryYHigh);
2462 
2463  if (!prev_exon_rng.Empty()) {
2464  TSeqRange rng(prev_exon_rng.GetFrom(), prev_exon_rng.GetToOpen());
2465  x_DrawInnerLabels(base, &labels_range, &rng);
2466  if (x_CanShowStrand(strand)) {
2468  TModelPoint(prev_exon_rng.GetFrom(), BoundaryYLow), fabs(prev_exon_rng.GetToOpen() - prev_exon_rng.GetFrom()), apart, bar_height,
2469  strand_indicator_color, neg_strand,
2471  !m_HideLabel, has_accessory_label, &labels_range);
2472  }
2473 
2474  }
2475  } else {
2476  // bar is less then 2 pixel. Do not draw intervals.
2477  m_Context->Draw3DQuad(from, BoundaryYLow, to, BoundaryYHigh, color, true);
2478  }
2479 }
2480 
2481 void CFeatGlyph::x_DrawInsertion(TModelUnit SeqPosTriangleMidPointX,
2482  TModelUnit BoundaryYLow,
2483  TModelUnit BoundaryYHigh,
2484  TModelUnit YCenterLine) const
2485 {
2486  // half the insertion triangle width in sequence coordinates
2487  TModelUnit SeqTriangleHalf = m_Context->ScreenToSeq(4.0);
2488 
2489  TModelUnit TriangleOffsetY = 1.0;
2490  m_Context->DrawLine(SeqPosTriangleMidPointX, BoundaryYLow, SeqPosTriangleMidPointX, BoundaryYHigh);
2491  m_Context->DrawTriangle(SeqPosTriangleMidPointX, YCenterLine,
2492  SeqPosTriangleMidPointX + SeqTriangleHalf, BoundaryYLow - TriangleOffsetY,
2493  SeqPosTriangleMidPointX - SeqTriangleHalf, BoundaryYLow - TriangleOffsetY);
2494  m_Context->DrawTriangle(SeqPosTriangleMidPointX, YCenterLine,
2495  SeqPosTriangleMidPointX + SeqTriangleHalf, BoundaryYHigh + TriangleOffsetY,
2496  SeqPosTriangleMidPointX - SeqTriangleHalf, BoundaryYHigh + TriangleOffsetY);
2497 }
2498 
2499 void CFeatGlyph::x_DrawDeletion(TModelUnit SeqPosTriangleMidPointX,
2500  TModelUnit BoundaryYLow,
2501  TModelUnit BoundaryYHigh) const
2502 {
2503  // half the insertion triangle width in sequence coordinates
2504  TModelUnit SeqTriangleHalf = m_Context->ScreenToSeq(4.0);
2505 
2506  TModelUnit TriangleOffsetY = 1.0;
2507  m_Context->DrawTriangle(SeqPosTriangleMidPointX, BoundaryYHigh + TriangleOffsetY,
2508  SeqPosTriangleMidPointX + SeqTriangleHalf, BoundaryYLow - TriangleOffsetY,
2509  SeqPosTriangleMidPointX - SeqTriangleHalf, BoundaryYLow - TriangleOffsetY);
2510 }
2511 
2512 
2513 
2515 {
2516  IRender& gl = GetGl();
2517 
2518  TModelUnit bar_height = m_Config->m_BarHeight;
2519  if (m_Context->IsOverviewMode() && m_HideLabel) {
2520  bar_height = floor(bar_height * m_Config->m_OverviewFactor);
2521  }
2522  TModelUnit YCenterLine = base;
2523  TModelUnit BoundaryYLow = YCenterLine - bar_height * 0.5f;
2524  TModelUnit BoundaryYHigh = YCenterLine + bar_height * 0.5f;
2525 
2526  CRgbaColor color;
2527  if ( !GetCustomColor(color) ) {
2529  }
2530  // a lighter version of color
2531  CRgbaColor color_t = color;
2532  color_t.SetAlpha(0.35f);
2533 
2534  // Draw feature bar
2535  TSeqRange SeqRange = GetRange();
2536  TSeqPos SeqPosFrom;
2537  TSeqPos SeqPosTo;
2538  x_IntersectVisible<TSeqPos>(SeqRange, SeqPosFrom, SeqPosTo);
2539 
2540  if (SeqRange.GetLength() > m_Context->ScreenToSeq(2.0)) { // At least 2 pixel
2541  size_t idx = GetCustomColorIdx(GetFeature());
2542  int literal_len =
2543  s_GetLiteralLength(GetFeature().GetData().GetVariation());
2544 
2545  TModelUnit prev_to_x = 0.0f;
2546  TModelUnit prev_from_x = 0.0f;
2547 
2548  bool first_pass = true;
2549  for (CSeq_loc_CI iter(GetLocation()); iter; ++iter) {
2550  CConstRef<CSeq_loc> loc = iter.GetRangeAsSeq_loc();
2551  SeqRange = iter.GetRange();
2552  SeqPosFrom = SeqRange.GetFrom();
2553  SeqPosTo = SeqRange.GetTo();
2554  TSeqPos SeqPosFromIn = SeqPosFrom;
2555  TSeqPos SeqPosToIn = SeqPosTo;
2556 
2557  // initialize defined breakpoint SeqRanges
2558  // inner start/stop, and outer start/stop
2559  if (loc->IsInt()) {
2560  if (loc->GetInt().IsSetFuzz_from() &&
2561  loc->GetInt().GetFuzz_from().IsRange()) {
2562  const CInt_fuzz::C_Range& f_SeqRange =
2563  loc->GetInt().GetFuzz_from().GetRange();
2564  SeqPosFrom = f_SeqRange.GetMin();
2565  SeqPosFromIn = f_SeqRange.GetMax();
2566  }
2567  if (loc->GetInt().IsSetFuzz_to() &&
2568  loc->GetInt().GetFuzz_to().IsRange()) {
2569  const CInt_fuzz::C_Range& t_SeqRange =
2570  loc->GetInt().GetFuzz_to().GetRange();
2571  SeqPosTo = t_SeqRange.GetMax();
2572  SeqPosToIn = t_SeqRange.GetMin();
2573  }
2574  }
2575 
2576  // draw the connecting line between intervals
2577  if ( !first_pass ) {
2578  // use a lighter color
2579  CRgbaColor color_lite = color;
2580  color_lite.Lighten(0.2f);
2581  TModelUnit intron_f = SeqPosFrom > prev_to_x ? prev_to_x + 1 : SeqPosTo + 1;
2582  TModelUnit intron_t = SeqPosFrom > prev_to_x ? SeqPosFrom : prev_from_x;
2583  gl.LineWidth((float)(m_Config->m_LineWidth));
2584  gl.ColorC(color_lite);
2585  m_Context->DrawLine(intron_f, YCenterLine, intron_t, YCenterLine);
2586  gl.LineWidth(1.0f);
2587  }
2588 
2589  EUndefinedBpType UndefinedBreakpointFrom = x_GetUndefinedBp_from(*loc);
2590  EUndefinedBpType UndefinedBreakpointTo = x_GetUndefinedBp_to(*loc);
2591 
2592  if (idx == CCustomFeatureColor::eLoss && literal_len >= 0) {
2593  if (literal_len >= (int)(SeqPosToIn - SeqPosFromIn)) {
2594  literal_len = SeqPosToIn - SeqPosFromIn - 2;
2595  }
2596  TModelUnit xm = (SeqPosFromIn + SeqPosToIn) * 0.5;
2597  TModelUnit m = (SeqPosFromIn + SeqPosToIn - literal_len) * 0.5;
2598  TModelUnit n = (SeqPosFromIn + SeqPosToIn + literal_len) * 0.5;
2599  gl.ColorC(color_t);
2600  m_Context->DrawQuad(SeqPosFromIn, BoundaryYLow, m + 1.0, BoundaryYHigh);
2601  m_Context->DrawQuad(n, BoundaryYLow, SeqPosToIn + 1.0, BoundaryYHigh);
2602 
2603  m += 1.0;
2604  TModelUnit half_w = m_Context->ScreenToSeq(3.0);
2605  if (literal_len < half_w * 2.0) {
2606  half_w = literal_len * 0.5;
2607  }
2608 
2609  vector<TModelPoint> points;
2610  points.push_back(TModelPoint(m, YCenterLine));
2611  points.push_back(TModelPoint(xm - half_w, YCenterLine));
2612  points.push_back(TModelPoint(xm - half_w * 0.5, BoundaryYLow - 1.0));
2613  points.push_back(TModelPoint(xm + half_w * 0.5, BoundaryYHigh + 1.0));
2614  points.push_back(TModelPoint(xm + half_w, YCenterLine));
2615  points.push_back(TModelPoint(n, YCenterLine));
2616  gl.Color3f(0.0f, 0.0f, 0.0f);
2617  m_Context->DrawLineStrip(points);
2618 
2619  } else if (idx == CCustomFeatureColor::eInsertion ||
2620  (idx == CCustomFeatureColor::eGain && literal_len >= 0)) {
2621 
2622  gl.ColorC(color_t);
2623  m_Context->DrawQuad(SeqPosFromIn, BoundaryYLow, SeqPosToIn + 1.0, BoundaryYHigh);
2624  // draw insertion
2625  CRgbaColor color_insert;
2627  gl.ColorC(color_insert);
2628  x_DrawInsertion((SeqPosFromIn + SeqPosToIn) * 0.5 + 0.5, BoundaryYLow, BoundaryYHigh, YCenterLine);
2629  } else if (idx == CCustomFeatureColor::eDeletionInsertion) {
2630  // draw deletion
2631  gl.ColorC(color);
2632  m_Context->DrawQuad(SeqPosFromIn, BoundaryYLow, SeqPosToIn + 1.0, BoundaryYHigh);
2633  // draw insertion
2634  CRgbaColor color_insert;
2636  gl.ColorC(color_insert);
2637  x_DrawInsertion(SeqPosToIn + 1.0, BoundaryYLow, BoundaryYHigh, YCenterLine);
2638  } else if (idx == CCustomFeatureColor::eTranschr) {
2639  m_Context->Draw3DQuad_HorzLines(SeqPosFromIn, BoundaryYLow, SeqPosToIn + 1.0, BoundaryYHigh, color, true);
2640  } else if (UndefinedBreakpointFrom == eBp_Outer || UndefinedBreakpointFrom == eBp_Outer) {
2641  gl.ColorC(color_t);
2642  m_Context->DrawQuad(SeqPosFromIn, BoundaryYLow, SeqPosToIn + 1.0, BoundaryYHigh);
2643  } else {
2644  m_Context->Draw3DQuad(SeqPosFromIn, BoundaryYLow, SeqPosToIn, BoundaryYHigh, color);
2645  }
2646 
2647  // render defined breakpoint SeqRanges
2648  if (SeqPosFromIn != SeqPosFrom) {
2649  gl.ColorC(color_t);
2650  m_Context->DrawQuad(SeqPosFrom, BoundaryYLow, SeqPosFromIn, BoundaryYHigh);
2651  }
2652  if (SeqPosToIn != SeqPosTo) {
2653  gl.ColorC(color_t);
2654  m_Context->DrawQuad(SeqPosToIn + 1, BoundaryYLow, SeqPosTo, BoundaryYHigh);
2655  }
2656 
2657  // render undefined breakpoint SeqRanges indicators
2658  TModelUnit tri_width = m_Context->ScreenToSeq(bar_height * 0.5);
2659  TModelUnit TriangleOffsetX = m_Context->ScreenToSeq(1.0);
2660 
2661  gl.ColorC(color_t);
2662  if (UndefinedBreakpointFrom == eBp_Outer) {
2663  m_Context->DrawTriangle(SeqPosFromIn, YCenterLine, SeqPosFromIn - tri_width, BoundaryYHigh,
2664  SeqPosFromIn - tri_width, BoundaryYLow, true);
2665  } else if (UndefinedBreakpointFrom == eBp_Inner) {
2666  m_Context->DrawTriangle(SeqPosFromIn - TriangleOffsetX, BoundaryYLow, SeqPosFromIn - TriangleOffsetX, BoundaryYHigh,
2667  SeqPosFromIn - TriangleOffsetX - tri_width, YCenterLine, true);
2668  }
2669 
2670  gl.ColorC(color_t);
2671  if (UndefinedBreakpointTo == eBp_Outer) {
2672  m_Context->DrawTriangle(SeqPosToIn + 1.0, YCenterLine, SeqPosToIn + 1.0 + tri_width, BoundaryYHigh,
2673  SeqPosToIn + 1.0 + tri_width, BoundaryYLow, true);
2674  } else if (UndefinedBreakpointTo == eBp_Inner) {
2675  m_Context->DrawTriangle(SeqPosToIn + TriangleOffsetX + 1.0, BoundaryYLow, SeqPosToIn + TriangleOffsetX + 1.0, BoundaryYHigh,
2676  SeqPosToIn + TriangleOffsetX + 1.0 + tri_width, YCenterLine, true);
2677  }
2678 
2679  first_pass = false;
2680  prev_to_x = SeqPosTo;
2681  prev_from_x = SeqPosFrom;
2682  }
2683 
2684  // render Transchr ssv, only render it once per feature, not per interval
2685  if (idx == CCustomFeatureColor::eTranschr) {
2686  // use the total SeqRange for screen size comparison
2687  SeqRange = GetRange();
2688  if (m_Context->SeqToScreen(SeqRange.GetLength()) > bar_height * 2.0) {
2689  gl.Color3f(0.0f, 0.0f, 0.0f);
2690  TModelUnit x1 = SeqPosTo - m_Context->ScreenToSeq(bar_height) + 1.0;
2691 
2692  // first clear background
2693  gl.Disable(GL_BLEND);
2694  gl.Color3f(1.0f, 1.0f, 1.0f);
2695  m_Context->DrawQuad(x1, YCenterLine - bar_height, SeqPosTo + 1.0, YCenterLine + bar_height);
2696 
2697  // draw quad with lines
2699  x1, YCenterLine - bar_height, SeqPosTo + 1.0, YCenterLine + bar_height, color, true);
2700  }
2701  }
2702 
2703  x_DrawInnerLabels(base);
2704  } else {
2705  // bar is less then 2 pixel. Do not draw intervals
2706  m_Context->Draw3DQuad(SeqPosFrom, BoundaryYLow,
2707  SeqPosTo, BoundaryYHigh, color, true);
2708  }
2709 }
2710 
2711 void CFeatGlyph::x_DrawRSites(const CRgbaColor& color, TModelUnit BoundaryYLow, TModelUnit BoundaryYHigh) const
2712 {
2713  _ASSERT(m_Context);
2714 
2715  TSeqPos from = m_Context->GetVisSeqFrom();
2716  TSeqPos to = m_Context->GetVisSeqTo();
2717 
2718  IRender& gl = GetGl();
2719  TModelUnit markerHeight = BoundaryYHigh - BoundaryYLow;
2720  markerHeight *= kRSiteMarkerHeight;
2721  TModelUnit halfMarkerWidth = kRSiteMarkerWidth / 2.0;
2722 
2723 
2724  // Check if the marker is visible
2726  return;
2727 
2728  gl.ColorC(color);
2729 
2730  CSeq_loc_CI iter(GetLocation());
2731  for ( ; iter; ++iter) {
2732  CConstRef<CSeq_loc> curr_loc = iter.GetRangeAsSeq_loc();
2733  if (!curr_loc->IsPnt())
2734  continue;
2735 
2736  const CSeq_point& pnt = curr_loc->GetPnt();
2737  if (!pnt.CanGetFuzz() || !pnt.CanGetPoint())
2738  continue;
2739 
2740  if ((from > pnt.GetPoint()) || (to < pnt.GetPoint()))
2741  continue;
2742 
2743  const CSeq_point_Base::TFuzz &fuzz = pnt.GetFuzz();
2744  if (fuzz.IsLim() && (CInt_fuzz_Base::eLim_tl == fuzz.GetLim())) {
2745  TSeqPos pos = pnt.GetPoint();
2746  if (pnt.CanGetStrand() && (eNa_strand_minus == pnt.GetStrand()))
2747  m_Context->DrawTriangle(pos, BoundaryYHigh, pos + halfMarkerWidth, BoundaryYHigh + markerHeight, pos - halfMarkerWidth, BoundaryYHigh + markerHeight, true);
2748  else
2749  m_Context->DrawTriangle(pos, BoundaryYLow, pos + halfMarkerWidth, BoundaryYLow - markerHeight, pos - halfMarkerWidth, BoundaryYLow - markerHeight, true);
2750  }
2751  }
2752 }
2753 
2755 {
2756  TModelUnit height = m_Config->GetBarHeight(
2758 
2759  if (IsDbVar(GetFeature()) &&
2760  m_Context->SeqToScreen(GetRange().GetLength()) > height * 2.0 &&
2762  height += height;
2763  }
2764 
2765  return height;
2766 }
2767 
2768 
2771 {
2772  // currently only support location with type e_Int or e_Mix of e_Int.
2774  if (IsDbVar(GetFeature()) && GetFeature().GetData().GetVariation().IsInsertion()) {
2775  type = eBp_Outer;
2776  } else if (loc.IsInt() &&
2777  loc.GetInt().IsSetFuzz_from() &&
2778  loc.GetInt().GetFuzz_from().IsLim()) {
2779  CInt_fuzz::TLim lim = loc.GetInt().GetFuzz_from().GetLim();
2780  if (lim == CInt_fuzz::eLim_gt) {
2781  type = eBp_Outer;
2782  } else if (lim == CInt_fuzz::eLim_lt) {
2783  type = eBp_Inner;
2784  }
2785  } else if (loc.IsMix()) {
2786  const CSeq_loc* start_loc = loc.IsReverseStrand() ?
2787  loc.GetMix().Get().front() : loc.GetMix().Get().back();
2788  type = x_GetUndefinedBp_from(*start_loc);
2789  } else if (loc.IsPacked_int()) {
2790  const CSeq_interval* starSeqPosToInt = loc.IsReverseStrand() ?
2791  loc.GetPacked_int().Get().front() : loc.GetPacked_int().Get().back();
2792  if (starSeqPosToInt->IsSetFuzz_from() && starSeqPosToInt->GetFuzz_from().IsLim()) {
2793  CInt_fuzz::TLim lim = starSeqPosToInt->GetFuzz_from().GetLim();
2794  if (lim == CInt_fuzz::eLim_gt) {
2795  type = eBp_Outer;
2796  } else if (lim == CInt_fuzz::eLim_lt) {
2797  type = eBp_Inner;
2798  }
2799  }
2800  }
2801 
2802  return type;
2803 }
2804 
2805 
2808 {
2809  // currently only support location with type e_Int or e_Mix of e_Int.
2811  if (IsDbVar(GetFeature()) && GetFeature().GetData().GetVariation().IsInsertion()) {
2812  type = eBp_Outer;
2813  } else if (loc.IsInt() &&
2814  loc.GetInt().IsSetFuzz_to() &&
2815  loc.GetInt().GetFuzz_to().IsLim()) {
2816  CInt_fuzz::TLim lim = loc.GetInt().GetFuzz_to().GetLim();
2817  if (lim == CInt_fuzz::eLim_gt) {
2818  type = eBp_Inner;
2819  } else if (lim == CInt_fuzz::eLim_lt) {
2820  type = eBp_Outer;
2821  }
2822  } else if (loc.IsMix()) {
2823  const CSeq_loc* stop_loc = loc.IsReverseStrand() ?
2824  loc.GetMix().Get().back() : loc.GetMix().Get().front();
2825  type = x_GetUndefinedBp_from(*stop_loc);
2826  } else if (loc.IsPacked_int()) {
2827  const CSeq_interval* stop_int = loc.IsReverseStrand() ?
2828  loc.GetPacked_int().Get().back() : loc.GetPacked_int().Get().front();
2829  if (stop_int->IsSetFuzz_to() && stop_int->GetFuzz_to().IsLim()) {
2830  CInt_fuzz::TLim lim = stop_int->GetFuzz_to().GetLim();
2831  if (lim == CInt_fuzz::eLim_gt) {
2832  type = eBp_Inner;
2833  } else if (lim == CInt_fuzz::eLim_lt) {
2834  type = eBp_Outer;
2835  }
2836  }
2837  }
2838 
2839  return type;
2840 }
2841 
2842 
2844 {
2845  bool shown = false;
2848  // in MSA context, the whole range can be very small and label can be skipped altogether
2849  //if (m_Context->WillLabelFit(m_Context->GetVisibleRange())) {
2850  shown = !m_HideLabel;
2851  //}
2852  } else { // can be either ePos_Above or ePos_Inside
2854  if (m_Context->WillLabelFit(r)) {
2855  shown = !m_HideLabel || IsSelected();
2856  }
2857  if (shown) {
2858  string fl_content;
2859  GetLabel(fl_content, CLabel::eContent);
2860  IRender& gl = GetGl();
2861  TModelUnit available_width = m_Context->SeqToScreen(r.GetLength());
2862  TModelUnit label_width = gl.TextWidth(&(m_Config->m_LabelFont), fl_content.c_str());
2863  if (label_width > available_width) {
2864  fl_content = m_Config->m_LabelFont.Truncate(fl_content.c_str(), available_width);
2865  if ((string::npos != fl_content.find("...")) && (fl_content.length() <= 5))
2866  shown = false;
2867  }
2868  }
2869  }
2870 
2871  // Check if label is redudant with track name and if so, hide:
2872  if (shown) {
2873  string fl_content;
2874  GetLabel(fl_content, CLabel::eContent);
2875  if (x_RedundantLabelCheck(fl_content))
2876  shown = false;
2877  }
2878  }
2879  return shown;
2880 }
2881 
2882 
2884 {
2885  // Show ruler if a feature has ruler enabled and
2886  // is selected in details mode
2887  return IsSelected() && (m_RulerType != eNoRuler) &&
2889 }
2890 
2891 
2893 {
2894  string id;
2895  const CSeq_feat& feat = GetFeature();
2896  const CSeq_feat::TId* feat_id = NULL;
2897  if (feat.IsSetId()) {
2898  feat_id = &feat.GetId();
2899  } else if (feat.IsSetIds() && !feat.GetIds().empty()) {
2900  feat_id = feat.GetIds().front().GetPointer();
2901  }
2902 
2903  if (feat_id) {
2904  switch(feat_id->Which()) {
2905  case CFeat_id::e_Gibb:
2906  id = NStr::IntToString(feat_id->GetGibb());
2907  break;
2908  case CFeat_id::e_Giim:
2909  id = NStr::IntToString(feat_id->GetGiim().GetId());
2910  break;
2911  case CFeat_id::e_Local:
2912  if (feat_id->GetLocal().IsStr()) {
2913  id = feat_id->GetLocal().GetStr();
2914  } else if (feat_id->GetLocal().IsId()) {
2915  id = NStr::IntToString(feat_id->GetLocal().GetId());
2916  }
2917  break;
2918  case CFeat_id::e_General:
2919  id = feat_id->GetGeneral().GetDb() + ":";
2920  if (feat_id->GetGeneral().GetTag().IsStr()) {
2921  id += feat_id->GetGeneral().GetTag().GetStr();
2922  } else if (feat_id->GetGeneral().GetTag().IsId()) {
2923  id += NStr::IntToString(feat_id->GetGeneral().GetTag().GetId());
2924  }
2925  break;
2926  default:
2927  break;
2928  }
2929  }
2930 
2931  return id;
2932 }
2933 
2934 void CFeatGlyph::x_GetUserColor(const objects::CUser_object &display_settings, CRgbaColor &color) const
2935 {
2936  if (!display_settings.HasField("color", ".", NStr::eNocase))
2937  return;
2938  CRgbaColor c;
2939  try {
2940  c.FromString(display_settings.GetField("color", ".", NStr::eNocase).GetString());
2941  bool is_white = c.GetRed() == 1.f && c.GetGreen() == 1.f && c.GetBlue() == 1.f;
2942  if (!is_white)
2943  color = c;
2944  }
2945  catch (const CException &err)
2946  {
2947  LOG_POST(Error << "Invalid color found in Exts.DisplaySettings.color" << err);
2948  }
2949 }
2950 
2951 
2953  m_Context->SetIsDrawn(GetPName(), Selected);
2954  // LOG_POST(Trace << "==== CLayoutGroup::SetRelatedGlyphSelected(" << Selected << "): " << this << ": " << CStackTrace());
2955 }
2956 
2958 {
2959  return m_Context && m_Context->GetIsDrawn(GetPName());
2960 }
2961 
2962 
2964 {
2965  buffer.clear();
2966  if (empty())
2967  return;
2968  auto& id = front().m_MappedInt->GetId();
2969  CBioseq_Handle bsh = scope.GetBioseqHandle(id);
2970  if (!bsh)
2971  return;
2973  TSignedSeqPos pre_gen = -1;
2974  TSignedSeqPos pre_to = 0;
2975  TSignedSeqPos prev_anchor = -1;
2976  bool neg = m_AlnMgr->IsNegativeStrand(m_AlnMgr->GetAnchor());
2977 
2978  for (auto&& map_it : *this) {
2979  auto& gen_int = *map_it.m_MappedInt;
2980  auto& prod_range = map_it.m_MappedProdRange;
2981  auto& anchor_range = map_it.m_AnchorRange;
2982  bool gen_neg = gen_int.GetStrand() == eNa_strand_minus;
2983 
2984  int num2add = prod_range.GetFrom() - pre_to;
2985  if (num2add >= 0)
2986  buffer.append(num2add, 'N');
2987  else if (prev_anchor > 0 && pre_gen > 0) {
2988  auto d = neg ?
2989  prev_anchor - anchor_range.GetTo() : anchor_range.GetFrom() - prev_anchor;
2990  bool is_insert = d == 0;
2991  if (is_insert) {
2992  num2add = gen_neg ? pre_gen - gen_int.GetTo() : gen_int.GetFrom() - pre_gen;
2993  if (num2add > 0)
2994  buffer.append(num2add, 'N');
2995  }
2996  }
2997 
2998  string tmp_seq;
2999  vec.GetSeqData(gen_int.GetFrom(), gen_int.GetTo() + 1, tmp_seq);
3000  if (gen_neg) {
3001  string seq;
3003  0, static_cast<TSeqPos>(tmp_seq.length()), seq);
3004  tmp_seq.swap(seq);
3005  }
3006  pre_to = prod_range.GetTo() + 1;
3007  pre_gen = gen_neg ? gen_int.GetFrom() - 1 : gen_int.GetTo() + 1;
3008  prev_anchor = neg ? anchor_range.GetFrom() - 1: anchor_range.GetTo() + 1;
3009  buffer += tmp_seq;
3010  }
3011 }
3012 
3013 
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
@ eExtreme_Positional
numerical value
Definition: Na_strand.hpp:63
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
void ConvertSeqLocsToPairwiseAln(CPairwiseAln &aln, const objects::CSeq_loc &loc_1, const objects::CSeq_loc &loc_2, CAlnUserOptions::EDirection direction=CAlnUserOptions::eBothDirections)
Build pairwise alignment from a pair of seq-locs.
static void redundant(Char *flag)
Definition: bzip2.c:1670
@ fAllowOverlap
allow segments with different orientation
CAlignRange Represents an element of pairwise alignment of two sequences.
Definition: align_range.hpp:63
Default IAlnSeqId implementation based on CSeq_id_Handle.
Definition: aln_seqid.hpp:116
@ eBothDirections
No filtering: use both direct and reverse sequences.
CBioseq_Handle –.
CCdregion –.
Definition: Cdregion.hpp:66
vector< CRgbaColor > TColorCode
const TColorCode & GetColorCode() const
@ eLowIdentity
feature's default color based on feature type
TSeqPos x_GetProtOffset() const
Returns protein translation offset.
bool GetRelatedGlyphSelected() const
virtual void x_Draw() const
The default renderer for this layout object.
string m_sTopLabelPrefix
Prefix to prepend to labels on top.
virtual bool HitTestHor(TSeqPos x, const CObject *obj)
void x_DrawInsertion(TModelUnit SeqPosTriangleMidPointX, TModelUnit BoundaryYLow, TModelUnit BoundaryYHigh, TModelUnit YCenterLine) const
bool x_CanShowStrand(objects::ENa_strand strand) const
TIntervals m_Intervals
intervals (like for features or alignments).
void x_GetUserColor(const objects::CUser_object &display_settings, CRgbaColor &color) const
CRef< objects::CSeq_loc > x_AdjustFrame(const objects::CSeq_loc &loc, TSeqPos offset) const
Adjusts a location to accommodate for the protein translation offset.
void LayoutChanged()
update the layout for everything encompassing this glyph
EUndefinedBpType x_GetUndefinedBp_to(const objects::CSeq_loc &loc) const
ELinkedFeatDisplay m_LinkedFeat
linkage mode for the track where this glyph is residing
virtual void x_UpdateBoundingBox()
Update the bounding box assuming children's sizes are fixed if any.
void x_DrawAdditionalInfo(TModelUnit base) const
virtual bool HasSideLabel() const
Query if there is label and label is on the side.
void SetRelatedGlyphSelected(bool Selected)
CConstRef< CFeatureParams > m_Config
All the configs needed for rendering a feature.
bool x_isDrawn() const
determines whether the glyph should be drawn or not at all (currently children of unselected parents ...
TModelUnit x_GetBarHeight() const
CProjectedMappingInfo m_ProjectedMappingInfo
string m_sFilter
filter (if any) for the track where this glyph is residing
virtual bool IsClickable() const
Query if this glyph is clickable.
bool GetCustomColor(CRgbaColor &color) const
Get the customized color for a given feature.
virtual bool NeedTooltip(const TModelPoint &, ITooltipFormatter &, string &) const
Check if need to show tooltip.
void GetAdditionalInfo(string &sAdditionalInfo) const
Some features may have additional info on the right (alleles for SNPs)
virtual string GetSignature() const
return signature for this glyph.
void x_DrawRSites(const CRgbaColor &color, TModelUnit BoundaryYLow, TModelUnit BoundaryYHigh) const
EUndefinedBpType x_GetUndefinedBp_from(const objects::CSeq_loc &loc) const
virtual void GetTooltip(const TModelPoint &p, ITooltipFormatter &tt, string &t_title) const
Get the tooltip if available.
objects::CMappedFeat m_Feature
we store a mapped feature object which in turn holds the original feature.
void x_DrawDeletion(TModelUnit SeqPosTriangleMidPointX, TModelUnit BoundaryYLow, TModelUnit BoundaryYHigh) const
void x_DrawRuler(TModelUnit base, bool protein_scale=false) const
const TMappingInfo & GetMappingInfo() const
virtual bool HasObject(CConstRef< CObject > obj) const
check if the wrapped object(s) is the one.
bool m_ProjectedFeat
Projected features.
bool isRmtBased() const
void x_DrawFeatureBar(TModelUnit &base) const
bool m_HideLabel
Force to hide the label.
virtual void SetHideLabel(bool b)
Force to hide label.
virtual bool LessBySeqPos(const CSeqGlyph &obj) const
compare this object to another based on glyph sequence position.
virtual void GetObjects(vector< CConstRef< CObject > > &objs) const
retrieve CObjects corresponding to this CSeqGlyph.
virtual CConstRef< CObject > GetObject(TSeqPos pos) const
Retrieve the feature as an object.
bool x_RedundantLabelCheck(const string &label) const
virtual const objects::CSeq_loc & GetLocation(void) const
access the position of this object.
CFeatGlyph(const objects::CMappedFeat &feat, ELinkedFeatDisplay LinkedFeat=ELinkedFeatDisplay::eLFD_Default)
bool x_ShowRuler() const
void x_DrawInnerLabels(TModelUnit base, vector< TModelRange > *labels_range=nullptr, TSeqRange *interval=nullptr) const
void x_DrawProjectedRuler(TModelUnit base, bool protein_scale=false) const
CConstRef< objects::CSeq_loc > m_Location
Mapped location in top sequence coordinate.
bool x_LabelOnLeft() const
true if a label should be placed to the left of the feature bar (provided that it is ePos_Side)
TMappingInfo m_MappingInfo
Feature product sequence mapping info.
bool x_IsProjected() const
void x_DrawLabelWithYPinned(TModelUnit base) const
static bool IsDbVar(const objects::CSeq_feat &feat)
Utility to check if a feature is a structural variation.
void x_MaybeDrawLabelOthers(TModelUnit base) const
bool m_RSite
Flag indicating if this is a restriction site.
bool x_ShowLabel() const
virtual bool IsConsensus() const
Check if (intron) feature is consensus or not.
TModelUnit GetBarCenter() const
void x_DrawLabelWithXPinned(TModelUnit &base) const
virtual bool SetSelected(bool f)
Select or deselect this glyph.
void x_DrawRNAProductSequence(TModelUnit base) const
bool x_isExpandable(size_t &nChildren) const
returns true if this glyph is expandable i.e.
void x_MaybeDrawLabelAbove(TModelUnit &base) const
bool x_isCollapsible() const
returns true if this glyph is collapsible i.e.
virtual void GetAccessoryLabel(string &accessory_label) const
Some features may have an accessory label on top (e.g. introns)
const objects::CMappedFeat & GetMappedFeature(void) const
Access a new, fully remapped feature.
string x_GetFeatureId() const
virtual TSeqRange GetRange(void) const
get the total range of this object.
map< CLabel::ELabelType, string > m_Labels
virtual string GetPName() const
persistent name of the glyph should not depend on the instance of the glyph, but should uniquely refl...
void x_DrawFeatureBar_sv(TModelUnit base) const
virtual const TIntervals & GetIntervals(void) const
access sub-intervals (if any).
const objects::CSeq_feat & GetFeature(void) const
Access the original feature.
static size_t GetCustomColorIdx(const objects::CSeq_feat &feat)
Get the customized color idx for a given feature.
virtual void GetHTMLActiveAreas(TAreaVector *p_areas) const
Get html active areas.
void GetLabel(string &label, CLabel::ELabelType type) const
retrieve feature label for a given type
CFeat_id –.
Definition: Feat_id.hpp:66
ELineStyle m_LineStyle
EConnection m_Connections
TModelUnit m_LineWidth
absolute value (in pixel)
EHeadStyle m_HeadStyle
CRgbaColor m_LabelColor
TModelUnit m_HeadHeight
ratio to bar height
TModelUnit m_TailHeight
ratio to bar height
CRgbaColor m_NonConsensus
CRgbaColor m_bgColor
CRef< CCustomFeatureColor > m_CustomColors
custom color code for features with a special attribute.
EBoxStyle m_BoxStyle
TModelUnit m_OverviewFactor
ratio to bar height
CRgbaColor m_fgColor
CGlTextureFont m_LabelFont
TModelUnit GetBarHeight(bool overview) const
ELabelPosition m_LabelPos
@ eBox_Insertion
additional decoration for the box
@ eBox_Deletion
add an inverted triangle to mark a deletion
@ eBox_Line
No box - just a line.
TModelUnit m_BarHeight
absolute size (in pixel)
@ ePos_NoLabel
no label
@ ePos_Side
always on 5' side
@ ePos_Inside
inside the rendered bar
@ ePos_Above
above the rendered bar
ETailStyle m_TailStyle
bool m_ShowStrandIndicator
class CGlPane
Definition: glpane.hpp:62
static CGuiRegistry & GetInstance()
access the application-wide singleton
Definition: registry.cpp:400
string m_Descr
description that can be used as label or tooltip
@ fNoCaching
The tooltip for this feature should not be cached.
@ fIgnorable
feature can be ignored (isca browser feature editing only)
@ fEditable
can be modified (isca browser feature editing only)
string m_ID
area identifier
int m_Flags
area flags, will need to replace m_Type
bool m_PositiveStrand
the default is true
CLayoutGroup is a container of CSeqGlyphs (layout objects).
static void PropagateRelatedSelection(bool isSelected, CSeqGlyph *pGlyph, CSeqGlyph *pGlyphFrom=NULL)
set "RelatedGlyphSelected" in CLayoutGroup-based glyph hierarchies everywhere in the hierarchy contai...
CConstRef< CSeqGlyph > GetChild(int idx) const
Get the layout object at index 'idx'.
size_t GetChildrenNum() const
Get total number of children.
bool IsMaster(const CSeqGlyph *glyph) const
bool AllChildrenSameType() const
Return true if there are 0 or 1 children, or all children are features of the same type (e....
File Description:
CMappedFeat –.
Definition: mapped_feat.hpp:59
static string GetFeatSignature(const objects::CSeq_feat &feat, objects::CScope *scope, const string &data_source="", const string &sAdditionalInfo="")
CObject –.
Definition: ncbiobj.hpp:180
A pairwise aln is a collection of ranges for a pair of rows.
void GetAnchorSequence(objects::CScope &scope, string &buffer) const
CConstRef< IAlnGraphicDataSource > m_AlnMgr
const IAlnGraphicDataSource * GetAlignmentDataSource() const
CRange –.
Definition: Range.hpp:68
class CRegistryReadView provides a nested hierarchical view at a particular key.
Definition: reg_view.hpp:58
CRenderingContext offers the basic context and utility methods for rendering layout objects in featur...
bool GetIsDrawn(const string &sPName) const
void DrawDisk(const TModelPoint &p, TModelUnit radius, GLint from=0, GLint to=360) const
bool IsHorizontal() const
void TextOut(const CGlTextureFont *font, const char *text, TModelUnit x, TModelUnit y, bool center, bool adjust_flip=true) const
static const int kLabelSpacePx
extra space for side labeling, in screen pixels
void DrawTriangle(TModelUnit x1, TModelUnit y1, TModelUnit x2, TModelUnit y2, TModelUnit x3, TModelUnit y3, bool border=false) const
void Draw3DFletch(TModelUnit pos_x, TModelUnit line_y1, TModelUnit line_y2, TModelUnit tail_height, const CRgbaColor &color, bool neg_strand) const
void DrawPseudoBar(TModelUnit x1, TModelUnit y1, TModelUnit x2, TModelUnit y2, const CRgbaColor &light_color, const CRgbaColor &dark_color) const
CRef< CSGSequenceDS > GetSeqDS() const
const TSeqRange & GetVisSeqRange() const
CGlPane * GetGlPane()
inline method implementations
const TModelUnit & GetOffset() const
TModelRange IntersectVisible(const CSeqGlyph *obj) const
TModelUnit GetMinLabelWidthPos() const
TSeqPos GetVisSeqTo() const
void Draw3DQuad_HorzLines(TModelUnit x1, TModelUnit y1, TModelUnit x2, TModelUnit y2, const CRgbaColor &color, bool border=false) const
void DrawLineStrip(const vector< TModelPoint > &points) const
void DrawLine(TModelUnit x1, TModelUnit y1, TModelUnit x2, TModelUnit y2) const
void DrawRect(const TModelRect &rc) 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 GetMaxLabelWidth(const CGlBitmapFont &font) const
In screen pixel..
void DrawPartialBar(TModelUnit x1, TModelUnit y1, TModelUnit x2, TModelUnit y2, bool p_start, bool p_stop, bool loc) 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.
TSeqPos GetVisSeqFrom() const
const CRgbaColor & GetSelLabelColor() const
bool WillLabelFit(const TModelRect &rc) const
void DrawSquare(const TModelPoint &p, TModelUnit size, const CRgbaColor &color, bool neg_strand) const
void Draw3DArrow(const TModelPoint &p, TModelUnit size, bool neg_strand) const
void Draw3DQuad(TModelUnit x1, TModelUnit y1, TModelUnit x2, TModelUnit y2, const CRgbaColor &color, bool border=false) const
void SetIsDrawn(const string &sPName, bool isDrawn)
void Draw3DTriangle(const TModelPoint &p, TModelUnit size, const CRgbaColor &color, bool neg_strand, bool need_neck) const
void DrawBackground(const TModelRect &rcm, TModelUnit border) const
void DrawStrandIndicators(const TModelPoint &start, TModelUnit length, TModelUnit apart, TModelUnit size, const CRgbaColor &color, bool neg_strand, bool avoid_center=false, bool single_indicator_center=false, const vector< TModelRange > *labels_ranges=nullptr) const
class CRgbaColor provides a simple abstraction for managing colors.
Definition: rgba_color.hpp:58
CRuler is a renderable object drawing a scale with position labels.
Definition: ruler.hpp:49
@ fFirstLabelHasText
Definition: ruler.hpp:117
@ fHideLabels
Definition: ruler.hpp:109
void SetTextLabel(const string &label)
Definition: ruler.cpp:197
void SetFont(CGlTextureFont::EFontFace font_type, unsigned int font_size=12)
Definition: ruler.cpp:145
void SetBaseWidth(int value)
Definition: ruler.hpp:308
@ eTop
Definition: ruler.hpp:93
@ eRight
Definition: ruler.hpp:95
@ eOppLabelTickHeight
tick size at label position (opposite)
Definition: ruler.hpp:88
@ eOppMajorTickHeight
major tick on the opposite side
Definition: ruler.hpp:87
@ eMajorTickHeight
Definition: ruler.hpp:84
@ eMinorTickHeight
Definition: ruler.hpp:83
@ eOppMinorTickHeight
minor tick on the opposite side
Definition: ruler.hpp:86
@ eLabelTickHeight
tick size at label position
Definition: ruler.hpp:85
void SetHorizontal(bool b_horz, ELabelPlacement place=eDefault, ELabelAlign aln=eAln_Center)
Definition: ruler.cpp:92
void SetDisplayOptions(int options)
Definition: ruler.cpp:165
virtual void Render(CGlPane &pane)
Definition: ruler.cpp:460
void SetGeometryParam(EGeometryParam geom, int value)
Definition: ruler.cpp:203
void SetMapping(const TAlignColl &coll)
Definition: ruler.cpp:190
static CRegistryReadView GetColorReadView(const CGuiRegistry &reg, const string &base_key, const string &sect, const string &key, const string &def_sect="")
Create a read view specifically for 'Color' section.
static void GetColor(const CRegistryReadView &view, const string &key, CRgbaColor &color)
TSeqPos GetSequenceLength() const
const objects::CSeqVector & GetSeqVector(void) const
CScope –.
Definition: scope.hpp:92
class CSeqGlyph defines an interface that wraps a rectilinear abstract object.
Definition: seq_glyph.hpp:82
string GetTearlineText() const
Definition: seq_glyph.hpp:278
ENeighbours m_Neighbours
Indicates whether the glyph has neighbours.
Definition: seq_glyph.hpp:348
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
@ eNghbrs_Left
Definition: seq_glyph.hpp:97
@ eNghbrs_Right
Definition: seq_glyph.hpp:98
virtual void x_OnLayoutChanged()
update the layout.
Definition: seq_glyph.cpp:353
virtual void SetHeight(TModelUnit h)
Definition: seq_glyph.hpp:650
const CRenderingContext * GetRenderingContext() const
Get the rendering context.
Definition: seq_glyph.hpp:690
int GetLevel() const
Definition: seq_glyph.hpp:286
virtual TModelUnit GetRight() const
Definition: seq_glyph.hpp:603
void x_DrawInnerLabels(TModelUnit base, const string &label, const CRgbaColor &color, const CGlTextureFont &font, bool side_label_visible, bool inside_only, vector< TModelRange > *labels_ranges=nullptr, TSeqRange *interval=nullptr, bool XOR_mode=false) const
Definition: seq_glyph.cpp:224
bool IsInHor(TModelUnit x) const
Definition: seq_glyph.cpp:149
void x_DrawException() const
Draw a shading background to indicate exception.
Definition: seq_glyph.cpp:338
virtual void SetWidth(TModelUnit w)
Definition: seq_glyph.hpp:646
bool IsSelected() const
Definition: seq_glyph.hpp:573
CSeqGlyph * m_Parent
parent/child relationships for this feature
Definition: seq_glyph.hpp:345
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
virtual void SetTop(TModelUnit b)
Definition: seq_glyph.hpp:658
virtual bool SetSelected(bool flag)
Select or deselect this glyph.
Definition: seq_glyph.hpp:525
void x_Local2World(TModelPoint &p) const
Transform the coordiantes from local coord. to world coord.
Definition: seq_glyph.hpp:726
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
const CSeqGlyph * GetParent(void) const
Definition: seq_glyph.hpp:622
static SIZE_TYPE ReverseComplement(const string &src, TCoding src_coding, TSeqPos pos, TSeqPos length, string &dst)
@ e_Iupacna
Definition: sequtil.hpp:47
CSeqVector –.
Definition: seq_vector.hpp:65
namespace ncbi::objects::
Definition: Seq_feat.hpp:58
const string & GetNamedQual(const CTempString &qual_name) const
Return a named qualifier.
Definition: Seq_feat.cpp:429
Seq-loc iterator class – iterates all intervals from a seq-loc in the correct order.
Definition: Seq_loc.hpp:453
Seq-loc iterator class – iterates all intervals from a seq-loc in the correct order.
Definition: Seq_loc.hpp:593
bool IsLoss() const
bool IsComplex() const
bool IsEversion() const
bool IsDeletionInsertion() const
bool IsGain() const
bool IsTranslocation() const
bool IsInversion() const
bool IsInsertion() const
bool IsDeletion() const
bool IsCNV() const
virtual bool IsNegativeStrand(TNumrow row) const =0
vector< TSeqRange > TIntervals
virtual IAlnExplorer::TNumrow GetAnchor() const =0
primitive interface to arrange tabular data in the tooltips
Definition: tooltip.hpp:55
static CConstRef< CDbtag > GetTag(const CSeq_feat &SrcFeat)
find a SNP tag in the feature returns NULL if no such tag (sm_dbTag_dbSNP)
Definition: snp_utils.cpp:77
vector< string > TAlleles
list of alleles belonging to particular SNP a deletion is represented by a "-"
Definition: snp_utils.hpp:188
static void GetAlleles(const CMappedFeat &mapped_feat, TAlleles &Alleles)
Return list of alleles encoded in qual.
Definition: snp_utils.cpp:237
const_iterator end() const
Definition: map.hpp:152
const_iterator find(const key_type &key) const
Definition: map.hpp:153
static const Colors colors
Definition: cn3d_colors.cpp:50
static CMemoryRegistry registry
Definition: cn3d_tools.cpp:81
int GetSubtype(CFieldNamePanel *field_name_panel, string &ncRNA_class)
ELinkedFeatDisplay
@ eLFD_Expandable
static const float kMinScaleForRulerLabels
Shoudl match feature_ds.cpp::kMinScaleForMapping i.e.
USING_SCOPE(objects)
static const TModelUnit kRSiteMarkerThreshold
Restriction sites marker visibility threshold (ie if the marker's width is smaller then the threshold...
static const int kVertSpace
vertical space between elements.
static const TModelUnit kRSiteMarkerWidth
Restriction sites marker width (absolute)
static int s_GetLiteralLength(const CVariation_ref &var)
TVPUnit s_AdjustScreenCoordinate(TModelUnit x)
static const int kRulerHeight
feature ruler height.
static const TModelUnit kRSiteMarkerHeight
Restriction sites marker height (relative to the height of the bar)
bool Empty(const CNcbiOstrstream &src)
Definition: fileutil.cpp:523
CS_CONTEXT * ctx
Definition: t0006.c:12
#define false
Definition: bool.h:36
static int type
Definition: getdata.c:31
int offset
Definition: replacements.h:160
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 REVERSE_ITERATE(Type, Var, Cont)
ITERATE macro to reverse sequence through container elements.
Definition: ncbimisc.hpp:827
string
Definition: cgiapp.hpp:687
#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
static bool IsException(const objects::CSeq_feat &feat)
Definition: utils.cpp:962
static bool IsPartialStart(const objects::CSeq_loc &loc)
Definition: utils.cpp:937
static bool IsPartialFeature(const objects::CSeq_feat &feat)
Definition: utils.cpp:926
static bool IsPseudoFeature(const objects::CSeq_feat &feat)
Definition: utils.cpp:910
static bool IsPartialStop(const objects::CSeq_loc &loc)
Definition: utils.cpp:943
static bool IsSameStrands(const objects::CSeq_loc &loc)
Definition: utils.cpp:948
static bool isRmtAnnotName(const string &sAnnotname)
check if a given annotation was created by a remote file pipeline
Definition: utils.cpp:813
vector< TMappedInt > TMappingInfo
Definition: utils.hpp:165
GLdouble TModelUnit
Definition: gltypes.hpp:48
void SetModelLimitsRect(const TModelRect &R)
Definition: glpane.hpp:342
void SetRight(T right)
Definition: glrect.hpp:114
T X() const
Definition: glpoint.hpp:59
void SetViewport(const TVPRect &R)
Definition: glpane.cpp:96
virtual void Enable(GLenum glstate)=0
bool OpenOrtho()
Definition: glpane.hpp:427
virtual void LineStipple(GLint factor, GLushort pattern)=0
Set line stipple pattern: glLineStipple(). Deprecated in gl 3.2+.
void SetBottom(T bottom)
Definition: glrect.hpp:113
void Color3f(GLfloat r, GLfloat g, GLfloat b)
Definition: irender.hpp:95
IRender & GetGl()
convenience function for getting current render manager
T Right() const
Definition: glrect.hpp:83
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
virtual void LoadIdentity()=0
TVPUnit ProjectY(TModelUnit m_y) const
Definition: glpane.cpp:676
virtual void PopMatrix()=0
T Left() const
Definition: glrect.hpp:81
void Close(void)
Definition: glpane.cpp:178
int TVPUnit
Definition: gltypes.hpp:47
CRange< TModelUnit > TModelRange
Definition: gltypes.hpp:56
void SetVisibleRect(const TModelRect &R)
Definition: glpane.cpp:113
void SetLeft(T left)
Definition: glrect.hpp:112
virtual TModelUnit TextWidth(const char *text) const
Compute and return font metrics.
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()
void SetHorz(T left, T right)
Definition: glrect.hpp:117
CGlPoint< TModelUnit > TModelPoint
Definition: gltypes.hpp:51
virtual void ColorC(const CRgbaColor &c)=0
Set current color (glColor{3,4}{f,d}{v,})
void SetTop(T top)
Definition: glrect.hpp:115
virtual void PushMatrix()=0
string Truncate(const char *text, TModelUnit w, ETruncate trunc=eTruncate_Ellipsis) const
Truncate text to the secified width.
CRgbaColor ContrastingColor(bool onlyBW=true) const
Return a color guaranteed to contrast nicely with this color.
static void GetLabel(const CObject &obj, string *label, ELabelType type=eDefault)
Definition: label.cpp:140
void Darken(float scale)
Definition: rgba_color.cpp:472
void SetLocation(const objects::CSeq_loc &loc)
static NSnp::TClinSigID ClinSigFromString(const string &clinsig)
converts string to clinical significance type (CPhenotype::EClinical_significance)
Definition: snp_gui.cpp:224
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
static CIRef< ITooltipFormatter > CreateTooltipFormatter(ETooltipFormatters)
factory for requested tooltip formatter creation
Definition: tooltip.cpp:40
void FromString(const string &str)
Assign color values encoded in a string.
Definition: rgba_color.cpp:363
void Lighten(float scale)
Definition: rgba_color.cpp:463
static bool GetClinSigValue(const CSeq_feat &ref, string &attr_value)
returns CLNSIG attribute value from VcfAttribute user object returns false if not found
Definition: snp_gui.cpp:743
static bool isFromVcf(const CSeq_feat &variation_ref)
Definition: snp_gui.cpp:719
void SetMappingInfo(const CSeqUtils::TMappingInfo &mapping_info)
static CVariation_inst::EType GetVcfType(const CSeq_feat &variation_ref)
Definition: snp_gui.cpp:750
void SetMappedFeat(const objects::CMappedFeat &mapped_feat)
ELabelType
Definition: label.hpp:60
static void ClinSigAsColor(NSnp::TClinSigID ClinSigID, CRgbaColor &color)
returns color for clinsig values (SV-4908) returns #767677 for undefined values
Definition: snp_gui.cpp:258
float GetRed(void) const
Get specific channels in floating point values.
Definition: rgba_color.hpp:321
@ eTooltipFormatter_CSSTable
generated table is CSS based, generated NCBI URLs are paths (recommended for SViewer)
Definition: tooltip.hpp:59
@ eType
Definition: label.hpp:65
@ eUserTypeAndContent
Definition: label.hpp:66
@ eContent
Definition: label.hpp:62
virtual void Assign(const CSerialObject &source, ESerialRecursionMode how=eRecursive)
Optimized implementation of CSerialObject::Assign, which is not so efficient.
Definition: Seq_id.cpp:318
CConstRef< CSeq_id > GetSeqId(void) const
string AsString(void) const
@ eContent
Untagged human-readable accession or the like.
Definition: Seq_id.hpp:605
CRef< CSeq_loc > MakeSeq_loc(EMakeType make_type=eMake_CompactType) const
return constructed CSeq_loc with all changes
Definition: Seq_loc.cpp:2946
void SetPacked_int(TPacked_int &v)
Definition: Seq_loc.hpp:984
void SetFrom(TSeqPos from)
Set the range from position.
Definition: Seq_loc.cpp:2818
void SetWhole(TWhole &v)
Definition: Seq_loc.hpp:982
void SetTo(TSeqPos to)
Set the range to position.
Definition: Seq_loc.cpp:2829
ENa_strand GetStrand(void) const
Get the location's strand.
Definition: Seq_loc.cpp:882
bool IsReverseStrand(void) const
Return true if all ranges have reverse strand.
Definition: Seq_loc.hpp:995
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
CConstRef< CSeq_loc > GetRangeAsSeq_loc(void) const
Get seq-loc for the current iterator position.
Definition: Seq_loc.cpp:2585
bool IsSetStrand(void) const
Get strand.
Definition: Seq_loc.hpp:1049
bool IsEmpty(void) const
True if the current location is empty.
Definition: Seq_loc.hpp:1084
const CSeq_id * GetId(void) const
Get the id of the location return NULL if has multiple ids or no id at all.
Definition: Seq_loc.hpp:941
TRange GetRange(void) const
Get the range.
Definition: Seq_loc.hpp:1042
ENa_strand GetStrand(void) const
Definition: Seq_loc.hpp:1056
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.
ENa_strand GetStrand(const CSeq_loc &loc, CScope *scope=0)
Returns eNa_strand_unknown if multiple Bioseqs in loc Returns eNa_strand_other if multiple strands in...
TTaxId GetTaxId(const CBioseq_Handle &handle)
return the tax-id associated with a given sequence.
Definition: sequence.cpp:274
@ eGetId_ForceGi
return only a gi-based seq-id
Definition: sequence.hpp:99
CBioseq_Handle GetBioseqHandle(const CSeq_id &id)
Get bioseq handle by seq-id.
Definition: scope.cpp:95
@ 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
TSeqPos size(void) const
Definition: seq_vector.hpp:291
bool Empty(void) const THROWS_NONE
Check if CConstRef is empty – not pointing to any object which means having a null value.
Definition: ncbiobj.hpp:1385
TObjectType * GetPointer(void) const THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:1684
CRef< C > Ref(C *object)
Helper functions to get CRef<> and CConstRef<> objects.
Definition: ncbiobj.hpp:2015
TObjectType * GetPointer(void) THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:998
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:1439
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
position_type GetLength(void) const
Definition: range.hpp:158
void SetReversed(bool reversed=true)
bool AbuttingWith(const TThisType &r) const
Definition: range.hpp:336
bool IntersectingWith(const TThisType &r) const
Definition: range.hpp:331
TThisType & CombineWith(const TThisType &r)
Definition: range.hpp:345
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
TThisType & SetFirstFrom(position_type from)
#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 SIZE_TYPE FindNoCase(const CTempString str, const CTempString pattern, SIZE_TYPE start, SIZE_TYPE end, EOccurrence which=eFirst)
Find the pattern in the specified range of a string using a case insensitive search.
Definition: ncbistr.cpp:2993
static double StringToDouble(const CTempStringEx str, TStringToNumFlags flags=0)
Convert string to double.
Definition: ncbistr.cpp:1387
#define NPOS
Definition: ncbistr.hpp:133
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5084
static string Join(const TContainer &arr, const CTempString &delim)
Join strings using the specified delimiter.
Definition: ncbistr.hpp:2697
static string & Replace(const string &src, const string &search, const string &replace, string &dst, SIZE_TYPE start_pos=0, SIZE_TYPE max_replace=0, SIZE_TYPE *num_replace=0)
Replace occurrences of a substring within a string.
Definition: ncbistr.cpp:3314
static bool EqualNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive equality of a substring with another string.
Definition: ncbistr.hpp:5353
static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
Definition: ncbistr.hpp:673
static string & ReplaceInPlace(string &src, const string &search, const string &replace, SIZE_TYPE start_pos=0, SIZE_TYPE max_replace=0, SIZE_TYPE *num_replace=0)
Replace occurrences of a substring within a string.
Definition: ncbistr.cpp:3405
@ eNocase
Case insensitive compare.
Definition: ncbistr.hpp:1206
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
bool IsStr(void) const
Check if variant Str is selected.
Definition: Object_id_.hpp:291
bool IsLim(void) const
Check if variant Lim is selected.
Definition: Int_fuzz_.hpp:636
const TTag & GetTag(void) const
Get the Tag member data.
Definition: Dbtag_.hpp:267
bool IsId(void) const
Check if variant Id is selected.
Definition: Object_id_.hpp:264
const TDb & GetDb(void) const
Get the Db member data.
Definition: Dbtag_.hpp:220
TLim GetLim(void) const
Get the variant data.
Definition: Int_fuzz_.hpp:642
ELim
some limit value
Definition: Int_fuzz_.hpp:209
TMin GetMin(void) const
Get the Min member data.
Definition: Int_fuzz_.hpp:519
const TStr & GetStr(void) const
Get the variant data.
Definition: Object_id_.hpp:297
bool IsRange(void) const
Check if variant Range is selected.
Definition: Int_fuzz_.hpp:603
TMax GetMax(void) const
Get the Max member data.
Definition: Int_fuzz_.hpp:472
TId GetId(void) const
Get the variant data.
Definition: Object_id_.hpp:270
const TRange & GetRange(void) const
Get the variant data.
Definition: Int_fuzz_.cpp:159
@ eLim_gt
greater than
Definition: Int_fuzz_.hpp:211
@ eLim_lt
less than
Definition: Int_fuzz_.hpp:212
@ eLim_tl
space to left of position
Definition: Int_fuzz_.hpp:214
E_Choice Which(void) const
Which variant is currently selected.
const TIds & GetIds(void) const
Get the Ids member data.
Definition: Seq_feat_.hpp:1452
list< CRef< CUser_object > > TExts
Definition: Seq_feat_.hpp:127
E_Choice Which(void) const
Which variant is currently selected.
Definition: Feat_id_.hpp:291
const TId & GetId(void) const
Get the Id member data.
Definition: Seq_feat_.hpp:904
const TLocal & GetLocal(void) const
Get the variant data.
Definition: Feat_id_.cpp:134
TFrame GetFrame(void) const
Get the Frame member data.
Definition: Cdregion_.hpp:534
const TData & GetData(void) const
Get the Data member data.
Definition: Seq_feat_.hpp:925
const TGeneral & GetGeneral(void) const
Get the variant data.
Definition: Feat_id_.cpp:156
const TGiim & GetGiim(void) const
Get the variant data.
Definition: Feat_id_.cpp:112
bool IsSetIds(void) const
set of Ids; will replace 'id' field Check if a value has been assigned to Ids data member.
Definition: Seq_feat_.hpp:1440
bool IsSetId(void) const
Check if a value has been assigned to Id data member.
Definition: Seq_feat_.hpp:892
TGibb GetGibb(void) const
Get the variant data.
Definition: Feat_id_.hpp:326
const TVariation & GetVariation(void) const
Get the variant data.
bool IsSetFrame(void) const
Check if a value has been assigned to Frame data member.
Definition: Cdregion_.hpp:509
@ e_Giim
geninfo import
Definition: Feat_id_.hpp:93
@ e_General
for use by various databases
Definition: Feat_id_.hpp:95
@ e_Gibb
geninfo backbone
Definition: Feat_id_.hpp:92
@ e_Local
for local software use
Definition: Feat_id_.hpp:94
@ eFrame_three
reading frame
Definition: Cdregion_.hpp:98
const TFuzz_from & GetFuzz_from(void) const
Get the Fuzz_from member data.
TId GetId(void) const
Get the Id member data.
bool IsMix(void) const
Check if variant Mix is selected.
Definition: Seq_loc_.hpp:552
ENa_strand
strand of nucleic acid
Definition: Na_strand_.hpp:64
const Tdata & Get(void) const
Get the member data.
const TPnt & GetPnt(void) const
Get the variant data.
Definition: Seq_loc_.cpp:238
TPoint GetPoint(void) const
Get the Point member data.
Definition: Seq_point_.hpp:303
const TFuzz_to & GetFuzz_to(void) const
Get the Fuzz_to member data.
const TFuzz & GetFuzz(void) const
Get the Fuzz member data.
Definition: Seq_point_.hpp:420
TStrand GetStrand(void) const
Get the Strand member data.
Definition: Seq_point_.hpp:350
const Tdata & Get(void) const
Get the member data.
bool CanGetFuzz(void) const
Check if it is safe to call GetFuzz method.
Definition: Seq_point_.hpp:414
bool CanGetStrand(void) const
Check if it is safe to call GetStrand method.
Definition: Seq_point_.hpp:337
bool IsPacked_int(void) const
Check if variant Packed_int is selected.
Definition: Seq_loc_.hpp:534
bool CanGetPoint(void) const
Check if it is safe to call GetPoint method.
Definition: Seq_point_.hpp:290
bool IsSetFuzz_to(void) const
Check if a value has been assigned to Fuzz_to data member.
bool IsInt(void) const
Check if variant Int is selected.
Definition: Seq_loc_.hpp:528
const TInt & GetInt(void) const
Get the variant data.
Definition: Seq_loc_.cpp:194
bool IsSetFuzz_from(void) const
Check if a value has been assigned to Fuzz_from data member.
const TMix & GetMix(void) const
Get the variant data.
Definition: Seq_loc_.cpp:282
bool IsPnt(void) const
Check if variant Pnt is selected.
Definition: Seq_loc_.hpp:540
const TPacked_int & GetPacked_int(void) const
Get the variant data.
Definition: Seq_loc_.cpp:216
@ eNa_strand_plus
Definition: Na_strand_.hpp:66
@ eNa_strand_other
Definition: Na_strand_.hpp:70
@ eNa_strand_minus
Definition: Na_strand_.hpp:67
@ eNa_strand_both_rev
in reverse orientation
Definition: Na_strand_.hpp:69
@ eNa_strand_both
in forward orientation
Definition: Na_strand_.hpp:68
const TInstance & GetInstance(void) const
Get the variant data.
bool IsSetDelta(void) const
Sequence that replaces the location, in biological order.
const TId & GetId(void) const
Get the Id member data.
const TDelta & GetDelta(void) const
Get the Delta member data.
const TData & GetData(void) const
Get the Data member data.
bool IsInstance(void) const
Check if variant Instance is selected.
list< CRef< CDelta_item > > TDelta
bool CanGetId(void) const
Check if it is safe to call GetId method.
@ eType_snv
delta=[morph of length 1] NOTE: this is snV not snP; the latter requires frequency-based validation t...
@ eType_mnp
delta=[morph of length >1]
@ eType_delins
delta=[del, ins]
bm::gap_word_t gap_length(const bm::gap_word_t *buf) noexcept
Returs GAP block length.
Definition: bmfunc.h:1603
n background color
yy_size_t n
int len
static void text(MDB_val *v)
Definition: mdb_dump.c:62
constexpr auto sort(_Init &&init)
constexpr auto front(list< Head, As... >, T=T()) noexcept -> Head
constexpr bool empty(list< Ts... >) noexcept
#define fabs(v)
Definition: ncbi_dispd.c:46
unsigned int a
Definition: ncbi_localip.c:102
EIPRangeType t
Definition: ncbi_localip.c:101
const char * tag
T max(T x_, T y_)
T min(T x_, T y_)
Int4 delta(size_t dimension_, const Int4 *score_)
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
double f(double x_, const double &y_)
Definition: njn_root.hpp:188
static pcre_uint8 * buffer
Definition: pcretest.c:1051
static bool GetIds(const T &d, set< string > &labels, const string name="", bool detect=false, bool found=false)
string GetProduct(const CProt_ref &prot_ref)
sorting functor for finding a range inside a collection of layout objects
Definition: layout.cpp:258
bool operator()(const CRef< CLayoutObject > &obj1, const CRef< CLayoutObject > &obj2) const
Definition: layout.cpp:259
Definition: type.c:6
#define _ASSERT
else result
Definition: token2.c:20
Modified on Wed Apr 17 13:10:13 2024 by modify_doxy.py rev. 669887