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 47783 2024-08-23 19:29:57Z asztalos $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: 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 
1982  if (SeqRange.GetLength() > pix_size * 2) { // At least 2 pixel
1983  TModelUnit prev_to_x = 0.0f;
1984  TModelUnit prev_from_x = 0.0f;
1985 
1986  bool first_pass = true;
1987  // draw exons and introns
1988 
1989  // Ranges, occupied by labels
1990  vector<TModelRange> labels_range;
1991  // Previous exon range
1992  TModelRange prev_exon_rng;
1993  // Range to draw strands on
1994  TModelRange strand_rng;
1995 
1996  bool has_accessory_label = false;
1997  CRgbaColor strand_indicator_color = color;
1998 
1999  // Determine strand indicator color
2000  switch (m_Config->m_BoxStyle) {
2003  strand_indicator_color = m_Config->m_fgColor.ContrastingColor();
2004  break;
2007  break;
2008  default:
2009  strand_indicator_color = color.ContrastingColor(false);
2010  // Line style means arrows are on a white background so should be darker.
2011  strand_indicator_color.Darken(0.1f);
2012  break;
2013  }
2014 
2015  vector<CConstRef<CSeq_loc>> locs;
2016  CSeq_loc_CI iter(GetLocation());
2017  for (; iter; ++iter) {
2018  locs.push_back(iter.GetRangeAsSeq_loc());
2019  }
2020  if (!m_RSite) {
2021  sort(locs.begin(), locs.end(), [](CConstRef<CSeq_loc>& a, CConstRef<CSeq_loc>& b) {
2022  return a->GetTotalRange().GetFrom() < b->GetTotalRange().GetFrom();
2023  });
2024  }
2025 
2026  for (const auto& curr_loc : locs) {
2027  TSeqRange curr = curr_loc->GetTotalRange();
2028 
2029  // Restriction sites have location mix, consisting of two points and an interval
2030  strand = sequence::GetStrand(*curr_loc);
2031  neg_strand = (strand == eNa_strand_minus);
2032 
2033  TModelUnit f = curr.GetFrom();
2034  TModelUnit t = curr.GetTo();
2035 
2036  bool is_visible_region = x_IntersectVisible<TModelUnit>(TModelRange(f, t), f, t);
2037 
2038  bool rsiteCutPnt = false;
2039  if (m_RSite) {
2040  if (curr_loc->IsPnt()) {
2041  const CSeq_point& pnt = curr_loc->GetPnt();
2042  if (pnt.CanGetFuzz()) {
2043  const CSeq_point_Base::TFuzz &fuzz = pnt.GetFuzz();
2044  if (fuzz.IsLim() && (CInt_fuzz_Base::eLim_tl == fuzz.GetLim())) {
2045  rsiteCutPnt = true;
2046  }
2047  }
2048  }
2049  }
2050 
2051  // adjust the size of exons to include style elements
2052  // such as head and tail pieces. Left (from) or right (to) sides
2053  // are adjected according to strand
2054  // 1) adjust head
2055  bool fit = head_size * 1.5 < fabs(t - f);
2056  bool adj_to = !neg_strand && t == SeqRange.GetTo() && fit;
2057  bool adj_from = neg_strand && f == SeqRange.GetFrom() && fit;
2058 
2059  if (adj_from || adj_to) {
2060  head_style = eNeedHead;
2061  }
2062 
2063  switch (m_Config->m_HeadStyle) {
2066  if (adj_to) {
2067  t = to - head_size * 1.5;
2068  }
2069  if (adj_from) {
2070  f = from + head_size * 1.5;
2071  }
2072  break;
2074  if (adj_to) {
2075  t = to - head_size;
2076  }
2077  if (adj_from) {
2078  f = from + head_size;
2079  }
2080  break;
2081 
2082  default:
2083  break;
2084  }
2085 
2086  // 2) adjust tail
2087  fit = tail_size < fabs(t - f);
2088  adj_to = neg_strand && t == SeqRange.GetTo() && fit;
2089  adj_from = !neg_strand && f == SeqRange.GetFrom() && fit;
2090 
2091  if (adj_from || adj_to) {
2092  tail_style = eNeedTail;
2093  }
2094 
2095  switch (m_Config->m_TailStyle) {
2097  if (adj_from) {
2098  f = from + tail_size * 0.5f;
2099  }
2100  if (adj_to) {
2101  t = to - tail_size * 0.5f;
2102  }
2103  break;
2105  if (adj_from) {
2106  f = from + tail_size;
2107  }
2108  if (adj_to) {
2109  t = to - tail_size;
2110  }
2111  break;
2113  if (adj_from) {
2114  f = from + tail_size; //-1
2115  }
2116  if (adj_to) {
2117  t = to - tail_size;
2118  }
2119  break;
2120 
2121  default:
2122  break;
2123  }
2124 
2125  // draw introns first
2126 
2127  TModelUnit from_x = curr.GetFrom();
2128  TModelUnit to_x = curr.GetTo() + 1;
2129 
2130  if (!first_pass) {
2131  //TModelUnit off = (m_Config->m_LineThickness) * 0.5f;
2132  TModelUnit intron_f;
2133  TModelUnit intron_t;
2134  if (!m_RSite) {
2135  intron_f = prev_to_x;
2136  intron_t = from_x;
2137  /*
2138  // In some cases, the intervals are not correctly ordered
2139  // for the feature. Maybe, it is a circular sequence, we
2140  // just can't handle it correctly.
2141  bool correctly_ordered = (neg_strand == (curr.GetFrom() < (prev_to_x - 1)));
2142  if (correctly_ordered) {
2143  intron_f = prev_to_x;
2144  intron_t = from_x;
2145  } else {
2146  intron_t = prev_from_x;
2147  intron_f = to_x;
2148  }
2149  if (neg_strand)
2150  swap(intron_f, intron_t);
2151  */
2152  } else { // The workaround above corrupts restriction sites
2153  intron_f = prev_from_x;
2154  intron_t = from_x;
2155  if (intron_f > intron_t)
2156  swap(intron_f, intron_t);
2157  }
2158 
2159  x_IntersectVisible<TModelUnit>(TModelRange(intron_f, intron_t), intron_f, intron_t);
2160 
2161  if (intron_f < intron_t) {
2162  glPushAttrib(GL_LINE_BIT);
2163  switch (m_Config->m_LineStyle) {
2165  gl.LineStipple(1, 0x0F0F);
2166  gl.Enable(GL_LINE_STIPPLE);
2167  break;
2169  gl.LineStipple(1, 0x0202);
2170  gl.Enable(GL_LINE_STIPPLE);
2171  break;
2173  gl.LineStipple(1, 0x1C47);
2174  gl.Enable(GL_LINE_STIPPLE);
2175  break;
2176  case CFeatureParams::eLine_ShortDashed: //Repeating pairs: -- -- --
2177  gl.LineStipple(2, 0xAAAA);
2178  gl.Enable(GL_LINE_STIPPLE);
2179  break;
2181  break;
2182  } // m_Config->m_LineStyle
2183 
2184 
2185  gl.LineWidth((float)(m_Config->m_LineWidth));
2186  gl.ColorC(color_lite);
2187  switch (m_Config->m_Connections) {
2189  {{
2190  TModelUnit middle_x =
2191  intron_f + (intron_t - intron_f) * 0.5f;
2192  m_Context->DrawLine(intron_f, YCenterLine, middle_x, BoundaryYLow);
2193  m_Context->DrawLine(middle_x, BoundaryYLow, intron_t, YCenterLine);
2194  }}
2195  break;
2196  case CFeatureParams::eBox:
2197  {{
2198  // if short, may look like we are drawing on one side or not at all
2199  if (m_Context->SeqToScreen(fabs(intron_t - intron_f)) < TModelUnit(6.0))
2200  gl.Disable(GL_LINE_STIPPLE);
2201 
2202  m_Context->DrawLine(intron_f, BoundaryYLow, intron_t, BoundaryYLow);
2203  m_Context->DrawLine(intron_f, BoundaryYHigh, intron_t, BoundaryYHigh);
2204  }}
2205  break;
2207  m_Context->DrawLine(intron_f, YCenterLine, intron_t, YCenterLine);
2208  break;
2210  gl.Disable(GL_LINE_STIPPLE);
2211  m_Context->Draw3DQuad(intron_f, BoundaryYLow, intron_t,
2212  BoundaryYHigh, color_lite);
2213  break;
2214  } // m_Config->m_Connections
2215  gl.Disable(GL_LINE_STIPPLE);
2216  gl.LineWidth(1.0f);
2217  glPopAttrib();
2218 
2219  if (x_CanShowStrand(strand) && !rsiteCutPnt) {
2221  TModelPoint(intron_f, BoundaryYLow),
2222  intron_t - intron_f, apart, bar_height,
2223  CRgbaColor(0.7f, 0.7f, 0.7f), neg_strand);
2224  }
2225  }
2226 
2227  } // connection lines (introns)
2228 
2229  if (is_pseudo) {
2230  CRgbaColor lcolor = color;
2231  lcolor.Lighten(0.4f);
2232  CRgbaColor dcolor = color;
2233  dcolor.Darken(0.7f);
2234 
2235  m_Context->DrawPseudoBar(f, BoundaryYLow, t + 1, BoundaryYHigh, lcolor, dcolor);
2236  }
2237 
2238  // draw features as quads, hollow rectangles or just lines as configured
2239 
2240  if (!rsiteCutPnt && is_visible_region) { // Don't draw bar if this is RSite cut point
2242  m_Context->Draw3DQuad(f, BoundaryYLow, t, BoundaryYHigh, color);
2243 // LOG_POST(Trace << " drawing eBox_Filled feature at left: " << f <<
2244 // " and right: " << t);
2245 
2246  // Draw SNPs separators
2247  gl.ColorC(m_Config->m_bgColor);
2248  if (m_Neighbours & eNghbrs_Left)
2249  m_Context->DrawLine(f, BoundaryYLow, f, BoundaryYHigh);
2250 
2252  m_Context->DrawLine(t + 1, BoundaryYLow, t + 1, BoundaryYHigh);
2253 
2255  gl.ColorC(color);
2256  m_Context->DrawRect(f, BoundaryYLow, t+1, BoundaryYHigh);
2258  m_Context->Draw3DQuad(f, BoundaryYLow, t, BoundaryYHigh, color);
2259  CRgbaColor color_insert("black");
2260  gl.ColorC(color_insert);
2261  x_DrawInsertion((f + t) * 0.5 + 0.5, BoundaryYLow, BoundaryYHigh, YCenterLine);
2263  m_Context->Draw3DQuad(f, BoundaryYLow, t, BoundaryYHigh, color);
2264  CRgbaColor color_delete("black");
2265  gl.ColorC(color_delete);
2266  x_DrawDeletion((f + t) * 0.5 + 0.5, BoundaryYLow, BoundaryYHigh);
2267  } else {
2268  gl.LineWidth(1.0f);
2269  gl.Disable(GL_LINE_SMOOTH);
2270  gl.ColorC(color);
2271  // draw line slightly off center to make room for (possible)label
2272  m_Context->DrawLine(f, YCenterLine+1, t+1, YCenterLine+1);
2273 
2274  // Draw simple line tick marks.
2275  if (f == curr.GetFrom()) // Omit the tick marks if out of the visible range
2276  m_Context->DrawLine(f, BoundaryYLow, f, BoundaryYHigh);
2277  if (t == curr.GetTo()) // Omit the tick marks if out of the visible range
2278  m_Context->DrawLine(t+1, BoundaryYLow, t+1, BoundaryYHigh);
2279  gl.Enable(GL_LINE_SMOOTH);
2280  }
2281 
2282  TModelRange exon_rng(f, t);
2283  if (prev_exon_rng.Empty())
2284  prev_exon_rng = exon_rng;
2285  else {
2286  if (prev_exon_rng.IntersectingWith(exon_rng) || prev_exon_rng.AbuttingWith(exon_rng)) // Merge the ranges, if they overlap
2287  prev_exon_rng.CombineWith(exon_rng);
2288  else {
2289  TSeqRange rng(prev_exon_rng.GetFrom(), prev_exon_rng.GetTo());
2290  if (rng.GetLength() > 1) {
2291  x_DrawInnerLabels(base, &labels_range, &rng);
2292  }
2293  strand_rng = prev_exon_rng;
2294  prev_exon_rng = exon_rng;
2295  }
2296  }
2297  }
2298 
2299  // Check for accessory label but do not draw it until after the strand
2300  // indicators (strand indicators on top of label make it hard to read).
2301  string accessory_label;
2302  TModelUnit clipped_from = std::min(t,f);
2303  TModelUnit clipped_to = std::max(t,f);
2304  const CGlTextureFont& font = m_Config->m_LabelFont;
2305  TModelUnit label_width = TModelUnit(0);
2306 
2307  if (first_pass) {
2308  GetAccessoryLabel(accessory_label);
2309  if (!accessory_label.empty()) {
2311  label_width = m_Context->ScreenToSeq(font.TextWidth(accessory_label.c_str()));
2312 
2313  // Find SeqRange that is visible inside current view. Rect can be flipped (left>right)
2314  TModelUnit clipped_from = std::min(t,f);
2315  TModelUnit clipped_to = std::max(t,f);
2316  if (r.Right() > r.Left()) {
2317  clipped_from = std::max(r.Left(), clipped_from);
2318  clipped_to = std::min(r.Right(), clipped_to);
2319  }
2320  else {
2321  clipped_to = std::min(r.Left(), clipped_to);
2322  clipped_from = std::max(r.Right(), clipped_from);
2323  }
2324 
2325  if (clipped_to-clipped_from > TModelUnit(1.5) * label_width) {
2326  has_accessory_label = true;
2327  }
2328  }
2329  }
2330 
2331  if (first_pass && has_accessory_label) {
2332  gl.ColorC(color);
2333  auto len = (clipped_to - clipped_from) - 1;
2334  const static int kLabelStep = 600;
2335  auto label_step = m_Context->ScreenToSeq(kLabelStep);
2336  if (len >= label_step * 2) {
2337  has_accessory_label = false; // use label_range instead to control whether to put strand indicators
2338  const TModelRect& rng = m_Context->GetGlPane()->GetVisibleRect();
2339  auto l = rng.Left();
2340  auto r = rng.Right();
2341  if (m_Context->IsFlippedStrand())
2342  swap(r, l);
2343  auto from = max<int>(clipped_from, l);
2344  while (true) {
2345  from += label_step;
2346  auto x = max<int>(from - label_width / TModelUnit(2), 0);
2347  if (x >= r || x >= (clipped_to - label_width))
2348  break;
2349  m_Context->TextOut(&font, accessory_label.c_str(), x, YCenterLine, false, true);
2350  labels_range.emplace_back(x, x + label_width);
2351  }
2352  }
2353  }
2354 
2355  if (is_visible_region) {
2356  // draw strand indicators
2357  if (x_CanShowStrand(strand) && !strand_rng.Empty()) {
2359  TModelPoint(strand_rng.GetFrom(), BoundaryYLow), fabs(strand_rng.GetToOpen() - strand_rng.GetFrom()), apart, bar_height,
2360  strand_indicator_color, neg_strand,
2362  !m_HideLabel, has_accessory_label, &labels_range);
2363  strand_rng.Set(0, 0);
2364  }
2365 
2366  if (has_accessory_label) {
2367  auto from = ((clipped_from + clipped_to) / TModelUnit(2)) - label_width / TModelUnit(2);
2368  m_Context->TextOut(&font, accessory_label.c_str(), from, YCenterLine, false, true);
2369  }
2370 
2371  // draw partial loc indicators
2372  bool p_start = curr_loc->IsPartialStart(objects::eExtreme_Positional);
2373  bool p_stop = curr_loc->IsPartialStop(objects::eExtreme_Positional);
2374  if (p_start || p_stop) {
2375  m_Context->DrawPartialBar(curr.GetFrom(), BoundaryYLow,
2376  curr.GetToOpen(), BoundaryYHigh, p_start, p_stop, true);
2377  }
2378  }
2379 
2380  prev_to_x = to_x;
2381  prev_from_x = m_RSite ? from_x : from_x - 1;
2382  first_pass = false;
2383  }
2384  if (x_CanShowStrand(strand)) {
2385 
2386  if ((neg_strand && from == SeqRange.GetFrom()) || (!neg_strand && to == SeqRange.GetTo())) {
2387  // Draw head (line-style boxes already have tick marks at end -don't add another.)
2388  if (head_style == eNeedHead && m_Config->m_BoxStyle != CFeatureParams::eBox_Line) {
2389  gl.LineWidth((float)(m_Config->m_LineWidth + 0.1));
2390 
2391  switch (m_Config->m_HeadStyle) {
2394  TModelPoint(neg_strand ? from : to + 1, YCenterLine),
2395  head_height, color, neg_strand, true); // with neck
2396  break;
2399  TModelPoint(neg_strand ? from : to + 1, YCenterLine),
2400  head_height, color, neg_strand, false);
2401  break;
2403  gl.ColorC(color);
2405  TModelPoint(neg_strand ? from : to + 1, YCenterLine),
2406  head_height, neg_strand);
2407  break;
2408 
2409  default:
2410  break;
2411  } // m_Config->m_HeadStyle
2412  gl.LineWidth(1.0f);
2413  } // eNeedHead
2414  }
2415 
2416  if ((neg_strand && to == SeqRange.GetTo()) || (!neg_strand && from == SeqRange.GetFrom())) {
2417  // Draw tail (line-style boxes already have tick marks at end -don't add another.)
2418  if (tail_style == eNeedTail && m_Config->m_BoxStyle != CFeatureParams::eBox_Line) {
2419  gl.LineWidth((float)(m_Config->m_LineWidth + 0.1f));
2420  switch (m_Config->m_TailStyle) {
2423  TModelPoint(neg_strand ? to + 1.0 : from, YCenterLine),
2424  tail_height, color, neg_strand);
2425  break;
2428  TModelPoint(neg_strand ? to + 1 : from, YCenterLine),
2429  tail_height, color, neg_strand);
2430  break;
2432  gl.LineWidth(1.5f);
2434  neg_strand ? to + 1 : from, BoundaryYLow, BoundaryYHigh,
2435  tail_height, color, neg_strand);
2436  break;
2437 
2438  default:
2439  break;
2440  } // m_Config->m_TailStyle
2441  gl.LineWidth(1.0f);
2442  } // eNeedTail
2443  }
2444  }
2445 
2446  // draw partial feature indicators
2448  bool draw_partial_start = (from == SeqRange.GetFrom());
2449  bool draw_partial_stop = (to == SeqRange.GetTo());
2450  m_Context->DrawPartialBar(from, BoundaryYLow, to + 1,
2451  BoundaryYHigh, draw_partial_start, draw_partial_stop, false);
2452  } else {
2453  bool p_start = CSeqUtils::IsPartialStart(GetFeature().GetLocation()) && (from == SeqRange.GetFrom());
2454  bool p_stop = CSeqUtils::IsPartialStop(GetFeature().GetLocation()) && (to == SeqRange.GetTo());
2455  if (p_start || p_stop) {
2456  if (neg_strand) swap(p_start, p_stop);
2457  m_Context->DrawPartialBar(from, BoundaryYLow, to + 1,
2458  BoundaryYHigh, p_start, p_stop, true);
2459  }
2460  }
2461  if (m_RSite)
2462  x_DrawRSites(m_Config->m_fgColor, BoundaryYLow, BoundaryYHigh);
2463 
2464  if (!prev_exon_rng.Empty()) {
2465  TSeqRange rng(prev_exon_rng.GetFrom(), prev_exon_rng.GetToOpen());
2466  x_DrawInnerLabels(base, &labels_range, &rng);
2467  if (x_CanShowStrand(strand)) {
2469  TModelPoint(prev_exon_rng.GetFrom(), BoundaryYLow), fabs(prev_exon_rng.GetToOpen() - prev_exon_rng.GetFrom()), apart, bar_height,
2470  strand_indicator_color, neg_strand,
2472  !m_HideLabel, has_accessory_label, &labels_range);
2473  }
2474 
2475  }
2476  } else {
2477  // bar is less then 2 pixel. Do not draw intervals.
2478  m_Context->Draw3DQuad(from, BoundaryYLow, to, BoundaryYHigh, color, true);
2479  }
2480 }
2481 
2482 void CFeatGlyph::x_DrawInsertion(TModelUnit SeqPosTriangleMidPointX,
2483  TModelUnit BoundaryYLow,
2484  TModelUnit BoundaryYHigh,
2485  TModelUnit YCenterLine) const
2486 {
2487  // half the insertion triangle width in sequence coordinates
2488  TModelUnit SeqTriangleHalf = m_Context->ScreenToSeq(4.0);
2489 
2490  TModelUnit TriangleOffsetY = 1.0;
2491  m_Context->DrawLine(SeqPosTriangleMidPointX, BoundaryYLow, SeqPosTriangleMidPointX, BoundaryYHigh);
2492  m_Context->DrawTriangle(SeqPosTriangleMidPointX, YCenterLine,
2493  SeqPosTriangleMidPointX + SeqTriangleHalf, BoundaryYLow - TriangleOffsetY,
2494  SeqPosTriangleMidPointX - SeqTriangleHalf, BoundaryYLow - TriangleOffsetY);
2495  m_Context->DrawTriangle(SeqPosTriangleMidPointX, YCenterLine,
2496  SeqPosTriangleMidPointX + SeqTriangleHalf, BoundaryYHigh + TriangleOffsetY,
2497  SeqPosTriangleMidPointX - SeqTriangleHalf, BoundaryYHigh + TriangleOffsetY);
2498 }
2499 
2500 void CFeatGlyph::x_DrawDeletion(TModelUnit SeqPosTriangleMidPointX,
2501  TModelUnit BoundaryYLow,
2502  TModelUnit BoundaryYHigh) const
2503 {
2504  // half the insertion triangle width in sequence coordinates
2505  TModelUnit SeqTriangleHalf = m_Context->ScreenToSeq(4.0);
2506 
2507  TModelUnit TriangleOffsetY = 1.0;
2508  m_Context->DrawTriangle(SeqPosTriangleMidPointX, BoundaryYHigh + TriangleOffsetY,
2509  SeqPosTriangleMidPointX + SeqTriangleHalf, BoundaryYLow - TriangleOffsetY,
2510  SeqPosTriangleMidPointX - SeqTriangleHalf, BoundaryYLow - TriangleOffsetY);
2511 }
2512 
2513 
2514 
2516 {
2517  IRender& gl = GetGl();
2518 
2519  TModelUnit bar_height = m_Config->m_BarHeight;
2520  if (m_Context->IsOverviewMode() && m_HideLabel) {
2521  bar_height = floor(bar_height * m_Config->m_OverviewFactor);
2522  }
2523  TModelUnit YCenterLine = base;
2524  TModelUnit BoundaryYLow = YCenterLine - bar_height * 0.5f;
2525  TModelUnit BoundaryYHigh = YCenterLine + bar_height * 0.5f;
2526 
2527  CRgbaColor color;
2528  if ( !GetCustomColor(color) ) {
2530  }
2531  // a lighter version of color
2532  CRgbaColor color_t = color;
2533  color_t.SetAlpha(0.35f);
2534 
2535  // Draw feature bar
2536  TSeqRange SeqRange = GetRange();
2537  TSeqPos SeqPosFrom;
2538  TSeqPos SeqPosTo;
2539  x_IntersectVisible<TSeqPos>(SeqRange, SeqPosFrom, SeqPosTo);
2540 
2541  if (SeqRange.GetLength() > m_Context->ScreenToSeq(2.0)) { // At least 2 pixel
2542  size_t idx = GetCustomColorIdx(GetFeature());
2543  int literal_len =
2544  s_GetLiteralLength(GetFeature().GetData().GetVariation());
2545 
2546  TModelUnit prev_to_x = 0.0f;
2547  TModelUnit prev_from_x = 0.0f;
2548 
2549  bool first_pass = true;
2550  for (CSeq_loc_CI iter(GetLocation()); iter; ++iter) {
2551  CConstRef<CSeq_loc> loc = iter.GetRangeAsSeq_loc();
2552  SeqRange = iter.GetRange();
2553  SeqPosFrom = SeqRange.GetFrom();
2554  SeqPosTo = SeqRange.GetTo();
2555  TSeqPos SeqPosFromIn = SeqPosFrom;
2556  TSeqPos SeqPosToIn = SeqPosTo;
2557 
2558  // initialize defined breakpoint SeqRanges
2559  // inner start/stop, and outer start/stop
2560  if (loc->IsInt()) {
2561  if (loc->GetInt().IsSetFuzz_from() &&
2562  loc->GetInt().GetFuzz_from().IsRange()) {
2563  const CInt_fuzz::C_Range& f_SeqRange =
2564  loc->GetInt().GetFuzz_from().GetRange();
2565  SeqPosFrom = f_SeqRange.GetMin();
2566  SeqPosFromIn = f_SeqRange.GetMax();
2567  }
2568  if (loc->GetInt().IsSetFuzz_to() &&
2569  loc->GetInt().GetFuzz_to().IsRange()) {
2570  const CInt_fuzz::C_Range& t_SeqRange =
2571  loc->GetInt().GetFuzz_to().GetRange();
2572  SeqPosTo = t_SeqRange.GetMax();
2573  SeqPosToIn = t_SeqRange.GetMin();
2574  }
2575  }
2576 
2577  // draw the connecting line between intervals
2578  if ( !first_pass ) {
2579  // use a lighter color
2580  CRgbaColor color_lite = color;
2581  color_lite.Lighten(0.2f);
2582  TModelUnit intron_f = SeqPosFrom > prev_to_x ? prev_to_x + 1 : SeqPosTo + 1;
2583  TModelUnit intron_t = SeqPosFrom > prev_to_x ? SeqPosFrom : prev_from_x;
2584  gl.LineWidth((float)(m_Config->m_LineWidth));
2585  gl.ColorC(color_lite);
2586  m_Context->DrawLine(intron_f, YCenterLine, intron_t, YCenterLine);
2587  gl.LineWidth(1.0f);
2588  }
2589 
2590  EUndefinedBpType UndefinedBreakpointFrom = x_GetUndefinedBp_from(*loc);
2591  EUndefinedBpType UndefinedBreakpointTo = x_GetUndefinedBp_to(*loc);
2592 
2593  if (idx == CCustomFeatureColor::eLoss && literal_len >= 0) {
2594  if (literal_len >= (int)(SeqPosToIn - SeqPosFromIn)) {
2595  literal_len = SeqPosToIn - SeqPosFromIn - 2;
2596  }
2597  TModelUnit xm = (SeqPosFromIn + SeqPosToIn) * 0.5;
2598  TModelUnit m = (SeqPosFromIn + SeqPosToIn - literal_len) * 0.5;
2599  TModelUnit n = (SeqPosFromIn + SeqPosToIn + literal_len) * 0.5;
2600  gl.ColorC(color_t);
2601  m_Context->DrawQuad(SeqPosFromIn, BoundaryYLow, m + 1.0, BoundaryYHigh);
2602  m_Context->DrawQuad(n, BoundaryYLow, SeqPosToIn + 1.0, BoundaryYHigh);
2603 
2604  m += 1.0;
2605  TModelUnit half_w = m_Context->ScreenToSeq(3.0);
2606  if (literal_len < half_w * 2.0) {
2607  half_w = literal_len * 0.5;
2608  }
2609 
2610  vector<TModelPoint> points;
2611  points.push_back(TModelPoint(m, YCenterLine));
2612  points.push_back(TModelPoint(xm - half_w, YCenterLine));
2613  points.push_back(TModelPoint(xm - half_w * 0.5, BoundaryYLow - 1.0));
2614  points.push_back(TModelPoint(xm + half_w * 0.5, BoundaryYHigh + 1.0));
2615  points.push_back(TModelPoint(xm + half_w, YCenterLine));
2616  points.push_back(TModelPoint(n, YCenterLine));
2617  gl.Color3f(0.0f, 0.0f, 0.0f);
2618  m_Context->DrawLineStrip(points);
2619 
2620  } else if (idx == CCustomFeatureColor::eInsertion ||
2621  (idx == CCustomFeatureColor::eGain && literal_len >= 0)) {
2622 
2623  gl.ColorC(color_t);
2624  m_Context->DrawQuad(SeqPosFromIn, BoundaryYLow, SeqPosToIn + 1.0, BoundaryYHigh);
2625  // draw insertion
2626  CRgbaColor color_insert;
2628  gl.ColorC(color_insert);
2629  x_DrawInsertion((SeqPosFromIn + SeqPosToIn) * 0.5 + 0.5, BoundaryYLow, BoundaryYHigh, YCenterLine);
2630  } else if (idx == CCustomFeatureColor::eDeletionInsertion) {
2631  // draw deletion
2632  gl.ColorC(color);
2633  m_Context->DrawQuad(SeqPosFromIn, BoundaryYLow, SeqPosToIn + 1.0, BoundaryYHigh);
2634  // draw insertion
2635  CRgbaColor color_insert;
2637  gl.ColorC(color_insert);
2638  x_DrawInsertion(SeqPosToIn + 1.0, BoundaryYLow, BoundaryYHigh, YCenterLine);
2639  } else if (idx == CCustomFeatureColor::eTranschr) {
2640  m_Context->Draw3DQuad_HorzLines(SeqPosFromIn, BoundaryYLow, SeqPosToIn + 1.0, BoundaryYHigh, color, true);
2641  } else if (UndefinedBreakpointFrom == eBp_Outer || UndefinedBreakpointFrom == eBp_Outer) {
2642  gl.ColorC(color_t);
2643  m_Context->DrawQuad(SeqPosFromIn, BoundaryYLow, SeqPosToIn + 1.0, BoundaryYHigh);
2644  } else {
2645  m_Context->Draw3DQuad(SeqPosFromIn, BoundaryYLow, SeqPosToIn, BoundaryYHigh, color);
2646  }
2647 
2648  // render defined breakpoint SeqRanges
2649  if (SeqPosFromIn != SeqPosFrom) {
2650  gl.ColorC(color_t);
2651  m_Context->DrawQuad(SeqPosFrom, BoundaryYLow, SeqPosFromIn, BoundaryYHigh);
2652  }
2653  if (SeqPosToIn != SeqPosTo) {
2654  gl.ColorC(color_t);
2655  m_Context->DrawQuad(SeqPosToIn + 1, BoundaryYLow, SeqPosTo, BoundaryYHigh);
2656  }
2657 
2658  // render undefined breakpoint SeqRanges indicators
2659  TModelUnit tri_width = m_Context->ScreenToSeq(bar_height * 0.5);
2660  TModelUnit TriangleOffsetX = m_Context->ScreenToSeq(1.0);
2661 
2662  gl.ColorC(color_t);
2663  if (UndefinedBreakpointFrom == eBp_Outer) {
2664  m_Context->DrawTriangle(SeqPosFromIn, YCenterLine, SeqPosFromIn - tri_width, BoundaryYHigh,
2665  SeqPosFromIn - tri_width, BoundaryYLow, true);
2666  } else if (UndefinedBreakpointFrom == eBp_Inner) {
2667  m_Context->DrawTriangle(SeqPosFromIn - TriangleOffsetX, BoundaryYLow, SeqPosFromIn - TriangleOffsetX, BoundaryYHigh,
2668  SeqPosFromIn - TriangleOffsetX - tri_width, YCenterLine, true);
2669  }
2670 
2671  gl.ColorC(color_t);
2672  if (UndefinedBreakpointTo == eBp_Outer) {
2673  m_Context->DrawTriangle(SeqPosToIn + 1.0, YCenterLine, SeqPosToIn + 1.0 + tri_width, BoundaryYHigh,
2674  SeqPosToIn + 1.0 + tri_width, BoundaryYLow, true);
2675  } else if (UndefinedBreakpointTo == eBp_Inner) {
2676  m_Context->DrawTriangle(SeqPosToIn + TriangleOffsetX + 1.0, BoundaryYLow, SeqPosToIn + TriangleOffsetX + 1.0, BoundaryYHigh,
2677  SeqPosToIn + TriangleOffsetX + 1.0 + tri_width, YCenterLine, true);
2678  }
2679 
2680  first_pass = false;
2681  prev_to_x = SeqPosTo;
2682  prev_from_x = SeqPosFrom;
2683  }
2684 
2685  // render Transchr ssv, only render it once per feature, not per interval
2686  if (idx == CCustomFeatureColor::eTranschr) {
2687  // use the total SeqRange for screen size comparison
2688  SeqRange = GetRange();
2689  if (m_Context->SeqToScreen(SeqRange.GetLength()) > bar_height * 2.0) {
2690  gl.Color3f(0.0f, 0.0f, 0.0f);
2691  TModelUnit x1 = SeqPosTo - m_Context->ScreenToSeq(bar_height) + 1.0;
2692 
2693  // first clear background
2694  gl.Disable(GL_BLEND);
2695  gl.Color3f(1.0f, 1.0f, 1.0f);
2696  m_Context->DrawQuad(x1, YCenterLine - bar_height, SeqPosTo + 1.0, YCenterLine + bar_height);
2697 
2698  // draw quad with lines
2700  x1, YCenterLine - bar_height, SeqPosTo + 1.0, YCenterLine + bar_height, color, true);
2701  }
2702  }
2703 
2704  x_DrawInnerLabels(base);
2705  } else {
2706  // bar is less then 2 pixel. Do not draw intervals
2707  m_Context->Draw3DQuad(SeqPosFrom, BoundaryYLow,
2708  SeqPosTo, BoundaryYHigh, color, true);
2709  }
2710 }
2711 
2712 void CFeatGlyph::x_DrawRSites(const CRgbaColor& color, TModelUnit BoundaryYLow, TModelUnit BoundaryYHigh) const
2713 {
2714  _ASSERT(m_Context);
2715 
2716  TSeqPos from = m_Context->GetVisSeqFrom();
2717  TSeqPos to = m_Context->GetVisSeqTo();
2718 
2719  IRender& gl = GetGl();
2720  TModelUnit markerHeight = BoundaryYHigh - BoundaryYLow;
2721  markerHeight *= kRSiteMarkerHeight;
2722  TModelUnit halfMarkerWidth = kRSiteMarkerWidth / 2.0;
2723 
2724 
2725  // Check if the marker is visible
2727  return;
2728 
2729  gl.ColorC(color);
2730 
2731  CSeq_loc_CI iter(GetLocation());
2732  for ( ; iter; ++iter) {
2733  CConstRef<CSeq_loc> curr_loc = iter.GetRangeAsSeq_loc();
2734  if (!curr_loc->IsPnt())
2735  continue;
2736 
2737  const CSeq_point& pnt = curr_loc->GetPnt();
2738  if (!pnt.CanGetFuzz() || !pnt.CanGetPoint())
2739  continue;
2740 
2741  if ((from > pnt.GetPoint()) || (to < pnt.GetPoint()))
2742  continue;
2743 
2744  const CSeq_point_Base::TFuzz &fuzz = pnt.GetFuzz();
2745  if (fuzz.IsLim() && (CInt_fuzz_Base::eLim_tl == fuzz.GetLim())) {
2746  TSeqPos pos = pnt.GetPoint();
2747  if (pnt.CanGetStrand() && (eNa_strand_minus == pnt.GetStrand()))
2748  m_Context->DrawTriangle(pos, BoundaryYHigh, pos + halfMarkerWidth, BoundaryYHigh + markerHeight, pos - halfMarkerWidth, BoundaryYHigh + markerHeight, true);
2749  else
2750  m_Context->DrawTriangle(pos, BoundaryYLow, pos + halfMarkerWidth, BoundaryYLow - markerHeight, pos - halfMarkerWidth, BoundaryYLow - markerHeight, true);
2751  }
2752  }
2753 }
2754 
2756 {
2757  TModelUnit height = m_Config->GetBarHeight(
2759 
2760  if (IsDbVar(GetFeature()) &&
2761  m_Context->SeqToScreen(GetRange().GetLength()) > height * 2.0 &&
2763  height += height;
2764  }
2765 
2766  return height;
2767 }
2768 
2769 
2772 {
2773  // currently only support location with type e_Int or e_Mix of e_Int.
2775  if (IsDbVar(GetFeature()) && GetFeature().GetData().GetVariation().IsInsertion()) {
2776  type = eBp_Outer;
2777  } else if (loc.IsInt() &&
2778  loc.GetInt().IsSetFuzz_from() &&
2779  loc.GetInt().GetFuzz_from().IsLim()) {
2780  CInt_fuzz::TLim lim = loc.GetInt().GetFuzz_from().GetLim();
2781  if (lim == CInt_fuzz::eLim_gt) {
2782  type = eBp_Outer;
2783  } else if (lim == CInt_fuzz::eLim_lt) {
2784  type = eBp_Inner;
2785  }
2786  } else if (loc.IsMix()) {
2787  const CSeq_loc* start_loc = loc.IsReverseStrand() ?
2788  loc.GetMix().Get().front() : loc.GetMix().Get().back();
2789  type = x_GetUndefinedBp_from(*start_loc);
2790  } else if (loc.IsPacked_int()) {
2791  const CSeq_interval* starSeqPosToInt = loc.IsReverseStrand() ?
2792  loc.GetPacked_int().Get().front() : loc.GetPacked_int().Get().back();
2793  if (starSeqPosToInt->IsSetFuzz_from() && starSeqPosToInt->GetFuzz_from().IsLim()) {
2794  CInt_fuzz::TLim lim = starSeqPosToInt->GetFuzz_from().GetLim();
2795  if (lim == CInt_fuzz::eLim_gt) {
2796  type = eBp_Outer;
2797  } else if (lim == CInt_fuzz::eLim_lt) {
2798  type = eBp_Inner;
2799  }
2800  }
2801  }
2802 
2803  return type;
2804 }
2805 
2806 
2809 {
2810  // currently only support location with type e_Int or e_Mix of e_Int.
2812  if (IsDbVar(GetFeature()) && GetFeature().GetData().GetVariation().IsInsertion()) {
2813  type = eBp_Outer;
2814  } else if (loc.IsInt() &&
2815  loc.GetInt().IsSetFuzz_to() &&
2816  loc.GetInt().GetFuzz_to().IsLim()) {
2817  CInt_fuzz::TLim lim = loc.GetInt().GetFuzz_to().GetLim();
2818  if (lim == CInt_fuzz::eLim_gt) {
2819  type = eBp_Inner;
2820  } else if (lim == CInt_fuzz::eLim_lt) {
2821  type = eBp_Outer;
2822  }
2823  } else if (loc.IsMix()) {
2824  const CSeq_loc* stop_loc = loc.IsReverseStrand() ?
2825  loc.GetMix().Get().back() : loc.GetMix().Get().front();
2826  type = x_GetUndefinedBp_from(*stop_loc);
2827  } else if (loc.IsPacked_int()) {
2828  const CSeq_interval* stop_int = loc.IsReverseStrand() ?
2829  loc.GetPacked_int().Get().back() : loc.GetPacked_int().Get().front();
2830  if (stop_int->IsSetFuzz_to() && stop_int->GetFuzz_to().IsLim()) {
2831  CInt_fuzz::TLim lim = stop_int->GetFuzz_to().GetLim();
2832  if (lim == CInt_fuzz::eLim_gt) {
2833  type = eBp_Inner;
2834  } else if (lim == CInt_fuzz::eLim_lt) {
2835  type = eBp_Outer;
2836  }
2837  }
2838  }
2839 
2840  return type;
2841 }
2842 
2843 
2845 {
2846  bool shown = false;
2849  // in MSA context, the whole range can be very small and label can be skipped altogether
2850  //if (m_Context->WillLabelFit(m_Context->GetVisibleRange())) {
2851  shown = !m_HideLabel;
2852  //}
2853  } else { // can be either ePos_Above or ePos_Inside
2855  if (m_Context->WillLabelFit(r)) {
2856  shown = !m_HideLabel || IsSelected();
2857  }
2858  if (shown) {
2859  string fl_content;
2860  GetLabel(fl_content, CLabel::eContent);
2861  IRender& gl = GetGl();
2862  TModelUnit available_width = m_Context->SeqToScreen(r.GetLength());
2863  TModelUnit label_width = gl.TextWidth(&(m_Config->m_LabelFont), fl_content.c_str());
2864  if (label_width > available_width) {
2865  fl_content = m_Config->m_LabelFont.Truncate(fl_content.c_str(), available_width);
2866  if ((string::npos != fl_content.find("...")) && (fl_content.length() <= 5))
2867  shown = false;
2868  }
2869  }
2870  }
2871 
2872  // Check if label is redudant with track name and if so, hide:
2873  if (shown) {
2874  string fl_content;
2875  GetLabel(fl_content, CLabel::eContent);
2876  if (x_RedundantLabelCheck(fl_content))
2877  shown = false;
2878  }
2879  }
2880  return shown;
2881 }
2882 
2883 
2885 {
2886  // Show ruler if a feature has ruler enabled and
2887  // is selected in details mode
2888  return IsSelected() && (m_RulerType != eNoRuler) &&
2890 }
2891 
2892 
2894 {
2895  string id;
2896  const CSeq_feat& feat = GetFeature();
2897  const CSeq_feat::TId* feat_id = NULL;
2898  if (feat.IsSetId()) {
2899  feat_id = &feat.GetId();
2900  } else if (feat.IsSetIds() && !feat.GetIds().empty()) {
2901  feat_id = feat.GetIds().front().GetPointer();
2902  }
2903 
2904  if (feat_id) {
2905  switch(feat_id->Which()) {
2906  case CFeat_id::e_Gibb:
2907  id = NStr::IntToString(feat_id->GetGibb());
2908  break;
2909  case CFeat_id::e_Giim:
2910  id = NStr::IntToString(feat_id->GetGiim().GetId());
2911  break;
2912  case CFeat_id::e_Local:
2913  if (feat_id->GetLocal().IsStr()) {
2914  id = feat_id->GetLocal().GetStr();
2915  } else if (feat_id->GetLocal().IsId()) {
2916  id = NStr::IntToString(feat_id->GetLocal().GetId());
2917  }
2918  break;
2919  case CFeat_id::e_General:
2920  id = feat_id->GetGeneral().GetDb() + ":";
2921  if (feat_id->GetGeneral().GetTag().IsStr()) {
2922  id += feat_id->GetGeneral().GetTag().GetStr();
2923  } else if (feat_id->GetGeneral().GetTag().IsId()) {
2924  id += NStr::IntToString(feat_id->GetGeneral().GetTag().GetId());
2925  }
2926  break;
2927  default:
2928  break;
2929  }
2930  }
2931 
2932  return id;
2933 }
2934 
2935 void CFeatGlyph::x_GetUserColor(const objects::CUser_object &display_settings, CRgbaColor &color) const
2936 {
2937  static string sColorFieldNames[]{"color", "colour", "itemRgb", "reserved"};
2938  string sUsedColorFieldName;
2939 
2940  for(auto sCheckColorFieldName: sColorFieldNames) {
2941  if(display_settings.HasField(sCheckColorFieldName, ".", NStr::eNocase)) {
2942  sUsedColorFieldName = sCheckColorFieldName;
2943  break;
2944  }
2945  }
2946 
2947  if (sUsedColorFieldName.empty())
2948  return;
2949  CRgbaColor c;
2950  try {
2951  try {
2952  Int8 ColorAsInt(display_settings.GetField(sUsedColorFieldName, ".", NStr::eNocase).GetInt8());
2953  c.Set((unsigned char)((ColorAsInt >> 16) & 0xFF), (unsigned char)((ColorAsInt >> 8) & 0xFF), (unsigned char)(ColorAsInt & 0xFF));
2954  }
2955  catch(...) {
2956  c.FromString(display_settings.GetField(sUsedColorFieldName, ".", NStr::eNocase).GetString());
2957  }
2958  bool is_white = c.GetRed() == 1.f && c.GetGreen() == 1.f && c.GetBlue() == 1.f;
2959  if (!is_white)
2960  color = c;
2961  }
2962  catch (const CException &err)
2963  {
2964  LOG_POST(Error << "Invalid color found in Exts.DisplaySettings.color" << err);
2965  }
2966 }
2967 
2968 
2970  m_Context->SetIsDrawn(GetPName(), Selected);
2971  // LOG_POST(Trace << "==== CLayoutGroup::SetRelatedGlyphSelected(" << Selected << "): " << this << ": " << CStackTrace());
2972 }
2973 
2975 {
2976  return m_Context && m_Context->GetIsDrawn(GetPName());
2977 }
2978 
2979 
2981 {
2982  buffer.clear();
2983  if (empty())
2984  return;
2985  auto& id = front().m_MappedInt->GetId();
2986  CBioseq_Handle bsh = scope.GetBioseqHandle(id);
2987  if (!bsh)
2988  return;
2990  TSignedSeqPos pre_gen = -1;
2991  TSignedSeqPos pre_to = 0;
2992  TSignedSeqPos prev_anchor = -1;
2993  bool neg = m_AlnMgr->IsNegativeStrand(m_AlnMgr->GetAnchor());
2994 
2995  for (auto&& map_it : *this) {
2996  auto& gen_int = *map_it.m_MappedInt;
2997  auto& prod_range = map_it.m_MappedProdRange;
2998  auto& anchor_range = map_it.m_AnchorRange;
2999  bool gen_neg = gen_int.GetStrand() == eNa_strand_minus;
3000 
3001  int num2add = prod_range.GetFrom() - pre_to;
3002  if (num2add >= 0)
3003  buffer.append(num2add, 'N');
3004  else if (prev_anchor > 0 && pre_gen > 0) {
3005  auto d = neg ?
3006  prev_anchor - anchor_range.GetTo() : anchor_range.GetFrom() - prev_anchor;
3007  bool is_insert = d == 0;
3008  if (is_insert) {
3009  num2add = gen_neg ? pre_gen - gen_int.GetTo() : gen_int.GetFrom() - pre_gen;
3010  if (num2add > 0)
3011  buffer.append(num2add, 'N');
3012  }
3013  }
3014 
3015  string tmp_seq;
3016  vec.GetSeqData(gen_int.GetFrom(), gen_int.GetTo() + 1, tmp_seq);
3017  if (gen_neg) {
3018  string seq;
3020  0, static_cast<TSeqPos>(tmp_seq.length()), seq);
3021  tmp_seq.swap(seq);
3022  }
3023  pre_to = prod_range.GetTo() + 1;
3024  pre_gen = gen_neg ? gen_int.GetFrom() - 1 : gen_int.GetTo() + 1;
3025  prev_anchor = neg ? anchor_range.GetFrom() - 1: anchor_range.GetTo() + 1;
3026  buffer += tmp_seq;
3027  }
3028 }
3029 
3030 
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
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
static FILE * f
Definition: readconf.c:23
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:690
#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:963
static bool IsPartialStart(const objects::CSeq_loc &loc)
Definition: utils.cpp:938
static bool IsPartialFeature(const objects::CSeq_feat &feat)
Definition: utils.cpp:927
static bool IsPseudoFeature(const objects::CSeq_feat &feat)
Definition: utils.cpp:911
static bool IsPartialStop(const objects::CSeq_loc &loc)
Definition: utils.cpp:944
static bool IsSameStrands(const objects::CSeq_loc &loc)
Definition: utils.cpp:949
static bool isRmtAnnotName(const string &sAnnotname)
check if a given annotation was created by a remote file pipeline
Definition: utils.cpp:814
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)
void Set(float r, float g, float b)
set the color from an Fl_Color
Definition: rgba_color.cpp:226
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
int64_t Int8
8-byte (64-bit) signed integer
Definition: ncbitype.h:104
position_type GetLength(void) const
Definition: range.hpp:158
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
#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:2984
static double StringToDouble(const CTempStringEx str, TStringToNumFlags flags=0)
Convert string to double.
Definition: ncbistr.cpp:1381
#define NPOS
Definition: ncbistr.hpp:133
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5078
static string Join(const TContainer &arr, const CTempString &delim)
Join strings using the specified delimiter.
Definition: ncbistr.hpp:2699
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:3305
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:5347
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:3396
@ 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_)
static uint8_t * buffer
Definition: pcre2test.c:1016
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)
static const sljit_gpr r1
static SLJIT_INLINE sljit_ins lg(sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b)
static const sljit_gpr r0
static SLJIT_INLINE sljit_ins l(sljit_gpr r, sljit_s32 d, sljit_gpr x, sljit_gpr b)
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 Fri Sep 20 14:57:29 2024 by modify_doxy.py rev. 669887