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

Go to the SVN repository for this file.

1 /* $Id: feature_graph.cpp 46025 2021-01-21 13:48:44Z grichenk $
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: Andrey Yazhuk
27  *
28  * File Description:
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
33 #include <corelib/ncbistd.hpp>
34 
38 
41 
42 #include <gui/opengl/glhelpers.hpp>
43 #include <gui/opengl/irender.hpp>
44 #include <gui/types.hpp>
45 
46 #include <gui/objutils/utils.hpp>
47 #include <gui/objutils/label.hpp>
48 
50 
51 #include <objmgr/util/sequence.hpp>
52 #include <objmgr/impl/synonyms.hpp>
53 
54 #include <math.h>
55 #include <memory>
56 #include <vector>
57 
58 
61 
62 
63 ///////////////////////////////////////////////////////////////////////////////
64 /// CFeatureLoadingJob
66  SAnnotSelector& sel,
67  const CRange<TSeqPos>& total_range,
68  TMapRanges& ranges,
69  const string& descr,
70  bool separate_types,
71  bool link_genes,
72  int track_order)
73 : m_Handle(handle),
74  m_Sel(sel),
75  m_TotalRange(total_range),
76  m_MapRanges(&ranges),
77  m_SeparateTypes(separate_types),
78  m_LinkGenes(link_genes),
79  m_Descr(descr),
80  m_Order(track_order)
81 {
83 }
84 
85 
87 {
88 }
89 
90 
92 {
93  //LOG_POST("CFeatureLoadingJob::Run() STARTED " << m_Descr);
94  {
95  CMutexGuard Guard(m_Mutex); // synchronize
96  m_Result.Reset();
97  m_Error.Reset();
98  }
99 
100  /// load features and separate them by subtypes if needed
101 
103  TMap subtype_to_feats; // subtype -> mapped features
104 
105  // cache TMappedFeatLocs* to avoid lookups for every feature
106  CSeqFeatData::ESubtype subtype, prev_subtype = CSeqFeatData::eSubtype_bad;
107  TMappedFeatLocs* locs = NULL;
108 
110 
111  // iterate by features
112  CFeat_CI feat_it(m_Handle, m_TotalRange, m_Sel);
113  for ( ; feat_it && !IsCanceled(); ++feat_it) {
114  const CMappedFeat& mp_feat = *feat_it;
115  const CSeq_feat& feat = mp_feat.GetMappedFeature();
116  // remap the original feature through the alignment
117  CRef<CSeq_loc> mapped_loc = mapper.Map(feat.GetLocation());
118 
119  // if mapping is successful - add feature to the map
120  if( ! mapped_loc->IsEmpty() && ! mapped_loc->IsNull()) {
121  // choose container based on settings and subtype
122  subtype = m_SeparateTypes ? feat.GetData().GetSubtype()
124  if(subtype != prev_subtype) {
125  TMap::iterator it = subtype_to_feats.find(subtype);
126  if(it == subtype_to_feats.end()) {
127  it = subtype_to_feats.insert(
129  }
130  locs = & it->second;
131  prev_subtype = subtype;
132  }
133 
134  // add the feature to the container
135 // locs->push_back(SMappedFeatLoc(feat, *mapped_loc));
136  locs->push_back(SMappedFeatLoc(mp_feat, *mapped_loc));
137  }
138  }
139 
140  // create Result object
141  if( ! IsCanceled()) {
143  res->m_Descr = m_Descr;
144 
145  // create graphs
146  NON_CONST_ITERATE(TMap, it, subtype_to_feats) {
147  if (IsCanceled()) {
148  return eCanceled;
149  }
150  TMappedFeatLocs& locs = it->second;
151  if( ! locs.empty()) {
153  res->m_Graphs.push_back(graph);
154 
155  locs.clear();
156  }
157  }
158 
159  CMutexGuard Guard(m_Mutex);
160  m_Result.Reset(res);
161  }
162 
163  //LOG_POST(Info << "------ CFeatureLoadingJob::Run() FINISHED " << m_Descr);
164 
165  return IsCanceled() ? eCanceled : eCompleted;
166 }
167 
168 
169 // create a Graph from the given set of features
171  CFeatureLoadingJob::x_CreateGraph(TMappedFeatLocs& feat_locs, const string& descr)
172 {
173  static const size_t kHistThreshold = 1000;
174  CIRef<IRenderable> graph;
175 
176  size_t n_feat = feat_locs.size();
177  if(n_feat > kHistThreshold) {
178  // too many features - create a Histogram
179  CHistogramGraph* hist = new CHistogramGraph(true);
180  graph.Reset(hist);
181 
183  props.m_Margin = 1;
184  hist->SetProperties(props);
185 
186  CFeatHistogramDS* ds = new CFeatHistogramDS(feat_locs, descr);
187  hist->SetDataSource(ds);
188 
189  //LOG_POST("Histogram Graph created - " << descr);
190  } else if(n_feat > 0) {
191  bool link_genes = ! m_SeparateTypes && m_LinkGenes;
192  graph = new CAlignedFeatureGraph(feat_locs, m_Handle.GetScope(),
193  descr, link_genes);
194  //LOG_POST("Layered Graph created - " << descr);
195  }
196  graph->SetOrder(m_Order);
197  return graph;
198 }
199 
200 
202 {
203  CMutexGuard Guard(m_Mutex); // synchronize
205 }
206 
207 
209 {
210  CMutexGuard Guard(m_Mutex); // synchronize
212 }
213 
214 
216 {
217  CMutexGuard Guard(m_Mutex); // synchronize
219 }
220 
221 
223 {
224  return m_Descr;
225 }
226 
227 
228 ////////////////////////////////////////////////////////////////////////////////
229 /// CFeatureGraph
230 
231 const static int kGradColors = 32;
232 
233 CFeatureGraph::CFeatureGraph(const IAlignRowHandle& row_handle, bool isDataReadSync)
234  : CGraphContainer(eHorzStack),
235  m_RowHandle(row_handle),
236  m_Created(false),
237  m_Font(CGlTextureFont::eFontFace_Helvetica, 10),
238  m_isDataReadSync(isDataReadSync),
239  m_Updated(false)
240 {
241  // add all feature types to the set
242  const CFeatList& list = *CSeqFeatData::GetFeatList();
244 
245  ITERATE(CFeatList, ft_it, list) {
246  const CFeatListItem& item = *ft_it;
247  set.insert(item);
248  }
249 }
250 
251 
253 {
254  Destroy();
255 }
256 
257 
259 {
260  return m_Created;
261 }
262 
263 
264 // performs basic initilization and laucnhes async jobs that will create graphs
266 {
267  if (m_ModelRect.Width() > 0.0 && m_ModelRect.Left() >= 0.0) {
269  m_Created = true;
270  return true;
271  }
272  return false;
273 }
274 
275 
277  const TSubtypeSet& filter,
278  bool positive,
279  CRange<TSeqPos>& total_range,
280  TMapRanges& map_ranges,
281  const string& descr,
282  bool separate_types,
283  bool link_genes,
284  int order)
285 {
286  // apply "filter" to "feat_set", results are accumulated in "final_set"
287  TFeatTypeItemSet final_set;
288  bool include_snp = false;
289 
290  ITERATE(TFeatTypeItemSet, it, feat_set) {
291  CSeqFeatData::ESubtype subtype =
292  (CSeqFeatData::ESubtype) it->GetSubtype();
293 
294  if(subtype != CSeqFeatData::eSubtype_any) {
295  bool found = (filter.find(subtype) != filter.end());
296  if(found == positive) {
297  final_set.insert(*it);
298  if(subtype == CSeqFeatData::eSubtype_variation) {
299  include_snp = true;
300  }
301  }
302  }
303  }
304 
305  // create SAnnotSelector according to the "final_set" and launch the job
306  if( ! final_set.empty()) {
308 
309  ITERATE(TFeatTypeItemSet, it, final_set) {
310  CSeqFeatData::ESubtype subtype =
311  (CSeqFeatData::ESubtype) it->GetSubtype();
312  sel.IncludeFeatSubtype(subtype);
313  }
314  if(include_snp) {
315  sel.AddNamedAnnots("SNP");
316  } else {
317  sel.ExcludeNamedAnnots("SNP");
318  }
319 
320  x_StartJob(sel, total_range, map_ranges, descr, separate_types, link_genes, order);
321  }
322 }
323 
324 
326 {
327  x_CancelJobs();
328 
329  RemoveAllGraphs();
330  m_Created = false;
331 }
332 
333 
334 void CFeatureGraph::Update(double start, double stop)
335 {
336  if (((TSeqPos)start == (TSeqPos)m_ModelRect.Left() &&
337  (TSeqPos)stop == (TSeqPos)m_ModelRect.Right()) ||
338  start < 0.0 || start > stop) {
339  return;
340  }
341  if (m_isDataReadSync && m_Updated) return;
342  m_Updated = true;
343 
344  x_CancelJobs();
345  x_Create(start, stop);
346 }
347 
348 
350 {
351  return NULL;
352 }
353 
354 
356 {
357  CFeatureGraphProperties* gr_props =
358  dynamic_cast<CFeatureGraphProperties*>(props);
359  _ASSERT(gr_props);
360  if(gr_props) {
361  m_Properties = *gr_props;
362  }
363 }
364 
365 
367 {
368  //LOG_POST(Info << " ");
369  //LOG_POST(Info << this << " CFeatureGraph::Render() m_StatusText = " << m_StatusText);
370  //LOG_POST(Info << " Viewport " << m_VPRect.ToString() << "\n Visible " << m_ModelRect.ToString());
371 
372  //CGlAttrGuard AttrGuard(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_HINT_BIT
373  // | GL_LINE_SMOOTH | GL_POLYGON_MODE | GL_LINE_BIT);
374 
376 
377  x_RenderStatusText(pane);
378 }
379 
380 
381 static const int kTextOff = 2;
382 
384 {
385  //LOG_POST("CFeatureGraph::x_RenderStatusText() m_StatusText = " << m_StatusText);
386  if( ! m_StatusText.empty()) {
387  //CGlAttrGuard guard(GL_LINE_BIT | GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT );
388 
389  IRender& gl = GetGl();
390 
391  gl.Enable(GL_BLEND);
392  gl.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
393 
394  gl.Enable(GL_LINE_SMOOTH);
395  glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
396 
397  // calculate bounding rectangle
398  TVPRect rc = m_VPRect;
399  rc.Inflate(-kTextOff, -kTextOff);
400  TVPUnit h = (TVPUnit) m_Font.TextHeight()+ 1 + kTextOff * 2;
401  rc.SetBottom(rc.Top() - h);
402 
403  pane.OpenPixels();
404 
405  double alpha = 0.5;
406 
407  // render text in rectangular frame
408  gl.Color4d(0.8, 0.8, 0.8, alpha);
409  gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
410  gl.RectC(rc);
411 
412  gl.Color4d(0.2, 0.2, 0.2, alpha);
413  gl.PolygonMode(GL_FRONT_AND_BACK, GL_LINE);
414  gl.RectC(rc);
415  gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
416 
417  rc.Inflate(-kTextOff, -kTextOff);
418 
419  m_Font.TextOut(rc.Left(), rc.Bottom(), rc.Right(), rc.Top(),
421 
422  pane.Close();
423  }
424 }
425 
426 
429  &CFeatureGraph::OnAJNotification)
431 
432 
433 TVPPoint CFeatureGraph::PreferredSize()
434 {
436  if( ! m_StatusText.empty()) {
437  TVPUnit h = (TVPUnit) m_Font.TextHeight() + 4 * kTextOff;
438  size.m_Y = max(size.m_Y, h);
439  }
440  return size;
441 }
442 
444 {
446 
447  /// adjust model space for graphs
448  /// the trik is that model space is in the same units as viewport (pixels), however
449  /// it is flipped so that range [a, b] in viewport corresponds to [b, a] in model space
450  switch(m_LayoutPolicy) {
451  case eHorzStack: {
452  TVPRect rc_vp(m_VPRect);
453  TVPUnit shift = 0;
454  TModelRect rc_vis(m_ModelRect);
455 
457  TGraph& graph = **it;
458  TVPUnit size = graph.PreferredSize().Y();
459 
460  // adjust viewport rect
461  TVPUnit vp_bottom = m_VPRect.Bottom() + shift;
462  TVPUnit vp_top = vp_bottom + (size - 1);
463  rc_vp.SetVert(vp_bottom, vp_top);
464  graph.SetVPRect(rc_vp);
465 
466  // adjust model rect
467  TModelUnit m_bottom = m_ModelRect.Bottom() - shift;
468  TModelUnit m_top = m_bottom - (size - 1);
469  rc_vis.SetVert(m_bottom, m_top);
470  graph.SetModelRect(rc_vis);
471 
472  shift += size;
473  }
474  break;
475  }
476  case eVertStack:
477  default:
478  _ASSERT(false);
479  break;
480  }
481 }
482 
483 
484 // creates CMappingRanges based on m_RowHandle
486 {
487  typedef IAlnExplorer::TSignedRange TSignedRange;
488 
489  // get a segment iterator
490  TSignedRange total_r;
492  total_r.SetTo(m_RowHandle.GetSeqAlnStop());
493 
494  unique_ptr<IAlnSegmentIterator>
496 
497  // prepare ID handles
499  CConstRef<CSeq_id> seq_id = handle.GetSeqId();
500  CScope& scope = m_RowHandle.GetBioseqHandle().GetScope();
501  CConstRef<CSynonymsSet> syns = scope.GetSynonyms(*seq_id);
502 
504 
505  // create CMappingRanges
506  CRef<CMappingRanges> ranges(new CMappingRanges());
507 
508  // iterate by the segments in the alignment and populate CMappingRanges
509  for( ; *it; ++(*it)) {
510  const IAlnSegment& seg = **it;
511  if(seg.IsAligned()) {
512  TSignedRange aln_range = seg.GetAlnRange();
513  TSignedRange range = seg.GetRange();
514  ENa_strand aln_strand = seg.IsReversed() ? eNa_strand_minus : eNa_strand_plus;
515 
516  // add a range for every Seq-id synonym, this is necessary because features
517  // can refer to different Seq-ids
518  ITERATE(CSynonymsSet, it_s, *syns) {
520  ranges->AddConversion(seq_idh, range.GetFrom(), range.GetLength(),
522  aln_idh, aln_range.GetFrom(),
523  aln_strand);
524  }
525  }
526  }
527  return ranges;
528 }
529 
530 
532  CRange<TSeqPos>& total_range,
533  TMapRanges& map_ranges,
534  const string& descr,
535  bool separate_types,
536  bool link_genes,
537  int order)
538 {
539  //LOG_POST("CFeatureGraph::x_StartJob(CFeatureLoadingJob& job)");
540 
543  new CFeatureLoadingJob(m_RowHandle.GetBioseqHandle(), sel, total_range, map_ranges,
544  descr, separate_types, link_genes, order));
545 
546  int job_id = -1;
547  if (m_isDataReadSync) {
548  // do everything synchronously
549  if(IAppJob::eCompleted == job->Run()) {
550  CAppJobNotification notification(-1, job->GetResult().GetPointer());
551  x_OnJobCompleted( notification );
552  m_StatusText = "";
553  return true;
554  } else {
555  CAppJobError errorNotification("Synchronous feature loading job failed.");
556  IAppJobError & rErrorNotification( errorNotification );
557  CAppJobNotification notification(-1, rErrorNotification);
558  x_OnJobFailed( notification );
559  m_StatusText = "";
560  return false;
561  }
562 
563  job.Reset();
564  } else {
565  try {
566  /// launch on ObjManagerEngine, receive notifications, no progress reports
567  /// delete the Job when completed
568  job_id =
569  disp.StartJob(*job, "ObjManagerEngine", *this, -1, true);
570  m_Jobs[job_id] = job;
571  //LOG_POST("Started job id = " << job_id << " " << job->GetDescr());
572  return true;
573  } catch(CAppJobException& e) {
574  ERR_POST("CFeatureGraph::x_StartJob - Failed");
575  LOG_POST(e.ReportAll());
576  return false;
577  }
578  }
579 
580  return false;
581 }
582 
584 {
587  TJobID job_id = it->first;
588  try {
589  disp.DeleteJob(job_id);
590  } catch(CException&) {
591  }
592  }
593  m_Jobs.clear();
594  m_PendingGraphs.clear();
595 }
596 
598 {
599  TJobMap::iterator it = m_Jobs.find(job_id);
600  if(it != m_Jobs.end()) {
602  m_Jobs.erase(it);
603  try {
604  disp.DeleteJob(job_id);
605  } catch(CAppJobException& e) {
606  switch(e.GetErrCode()) {
609  /// this is fine - job probably already finished
610  break;
611  default:
612  // something wrong
613  ERR_POST("CFeatureGraph::x_CancelJob() " << "Error canceling job");
614  LOG_POST(e.ReportAll());
615  return false;
616  }
617  }
618  return true;
619  } else {
620  _ASSERT(false);
621  ERR_POST("CFeatureGraph::x_CancelJob - invalid job id" << job_id);
622  return false;
623  }
624  return false;
625 }
626 
627 
629 {
630  //LOG_POST("CFeatureGraph::OnAJNotification(CEvent* evt)");
631  CAppJobNotification* notn = dynamic_cast<CAppJobNotification*>(evt);
632  _ASSERT(notn);
633 
634  if(notn) {
635  int job_id = notn->GetJobID();
636  TJobMap::iterator it = m_Jobs.find(job_id);
637 
638  //if(notn->GetState() != IAppJob::eRunning) {
639  // string s = CAppJobDispatcher::StateToStr(notn->GetState());
640  // LOG_POST("OnAJNotification(), id = " << job_id << ", State " << s);
641  //}
642 
643  if(it == m_Jobs.end()) {
644  // Maybe, the job has been removed/canceled.
645  return;
646  }
647 
648  size_t old_graphs_n = GetGraphsCount();
649 
650  switch(notn->GetState()) {
651  case IAppJob::eCompleted:
652  x_OnJobCompleted(*notn);
653  break;
654  case IAppJob::eFailed:
655  x_OnJobFailed(*notn);
656  break;
657  case IAppJob::eCanceled:
658  break;
659  case IAppJob::eRunning:
660  return;
661  default:
662  _ASSERT(false);
663  return;
664  }
665 
666  m_Jobs.erase(it);
667  if(m_Jobs.empty()) {
668  RemoveAllGraphs();
669  if (size_t n = m_PendingGraphs.size()) {
670  for (size_t i = 0; i < n; ++i) {
671  AddGraph(m_PendingGraphs[i].GetPointer());
672  }
673  }
674  m_StatusText = "";
675  }
676 
677  if(GetGraphsCount() != old_graphs_n || m_Jobs.empty()) {
678  // notify parent graph about the changes
680  Send(&nt, ePool_Parent);
681  }
682  }
683 }
684 
685 
687 {
688  //LOG_POST("CFeatureGraph::x_OnJobCompleted(CAppJobNotification& notify)");
689  CRef<CObject> res_obj = notify.GetResult();
691  dynamic_cast<CFeatureLoadingJobResult*>(res_obj.GetPointer());
692 
693  if(result) {
694  CFeatureLoadingJobResult::TGraphs& graphs = result->m_Graphs;
695  size_t n = graphs.size();
696  //LOG_POST("CFeatureGraph::x_OnJobCompleted() " << n << " graphs arrived");
697  if(n) {
698  std::copy(graphs.begin(), graphs.end(), back_inserter(m_PendingGraphs));
699  }
700  } else {
701  ERR_POST("CFeatureGraph::x_OnJobCompleted() notification for job "
702  << notify.GetJobID() << " does not contain results.");
703  }
704 }
705 
706 
708 {
709  CConstIRef<IAppJobError> err = notify.GetError();
710  if(err) {
711  // TODO report result in graph
712  } else {
713  ERR_POST("CFeatureGraph::x_OnJobFailed() notification for job "
714  << notify.GetJobID() << " does not have an error object");
715  }
716 }
717 
718 
719 void CFeatureGraph::x_Create(double start, double stop)
720 {
721  //LOG_POST(Info);
722  m_StatusText = "Features Graph - Loading data...";
723 
724  // setup groups
725  TSubtypeSet gene_set; // Genes, mRNAsm CDS-es
729 
730  TSubtypeSet snp_set; // SNPs
732 
733  TSubtypeSet sts_set; // STS-es
735 
736  TSubtypeSet others_set; // all other types - negative set
742 
743  // here we launch all the Feature Loading Jobs
744  // groupped by features types with filter
745  CRef<TMapRanges> map_ranges = x_CreateMapRanges();
746 
747  //CRange<TSeqPos> total_range(m_RowHandle.GetSeqStart(),
748  // m_RowHandle.GetSeqStop());
751  if (f > t) {
752  swap(f, t);
753  }
754  CRange<TSeqPos> total_range((TSeqPos)f, (TSeqPos)t);
756 
757  x_StartJob(load_set, gene_set, true, total_range, *map_ranges, "Gene, CDS, mRNA", false, true, 10);
758  //x_StartJob(load_set, snp_set, true, total_range, *map_ranges, "SNP", false, false);
759  x_StartJob(load_set, sts_set, true, total_range, *map_ranges, "STS", false, false, 20);
760  x_StartJob(load_set, others_set, false, total_range, *map_ranges, "Other feature types", false, false, 30);
761  if (m_isDataReadSync) {
762  // Piece from OnAJNotification suitable for sync execution
763  //RemoveAllGraphs();
764  if (size_t n = m_PendingGraphs.size()) {
765  while (n > 0) {
766  AddGraph(m_PendingGraphs[--n].GetPointer());
767  }
768  }
769  m_StatusText = "";
771  Send(&nt, ePool_Parent);
772  }
773 }
774 
775 
776 
777 ///////////////////////////////////////////////////////////////////////////////
778 /// CAlignedFeatureGraph
779 static const int kLayerH = 12;
780 static const int kLayerOffY = 2;
781 
783  : m_Scope(0),
784  m_Label(NcbiEmptyString),
785  m_LinkGenes(false),
786  m_TooltipRec(NULL),
787  m_LayerH(kLayerH)
788 {
789 }
790 
791 CAlignedFeatureGraph::CAlignedFeatureGraph(TMappedFeatLocs& feat_locs,
792  CScope& scope,
793  const string& label,
794  bool link_genes)
795 : m_Scope(&scope),
796  m_Label(label),
797  m_LinkGenes(link_genes),
798  m_TooltipRec(NULL),
799  m_LayerH(kLayerH)
800 {
801  x_Init(feat_locs, scope, label, link_genes);
802 }
803 
804 void CAlignedFeatureGraph::x_Init(TMappedFeatLocs& feat_locs,
805  CScope& scope,
806  const string& label,
807  bool link_genes)
808 {
809  x_Clear();
810  m_Scope = &scope;
811  m_Label = label;
812  m_LinkGenes = link_genes;
813  m_FeatRecs.clear();
814  size_t n = feat_locs.size();
815  m_FeatRecs.resize(n);
816  for( size_t i = 0; i < n; i++) {
817  SFeatRec s(feat_locs[i]);
818  m_FeatRecs[i] = s;
819  }
820  x_Layout();
821 
822 }
823 
825  CScope& scope,
826  const string& label,
827  bool link_genes)
828 {
829  x_Clear();
830  m_Scope = &scope;
831  m_Label = label;
832  m_LinkGenes = link_genes;
833  m_FeatRecs.clear();
834  m_FeatRecs.reserve(glyphs.size());
836  CFeatGlyph* feat_glyph = dynamic_cast<CFeatGlyph*>(&**it);
837  if (!feat_glyph)
838  continue;
839  SFeatRec s(*feat_glyph);
840  m_FeatRecs.push_back(s);
841  }
842  x_Layout();
843 
844 }
845 
847 {
848  x_Clear();
849 }
850 
851 
853 
855 {
856  //LOG_POST(Info << " CAlignedFeatureGraph::Render()");
857  //LOG_POST(Info << " Viewport " << m_VPRect.ToString() << "\n Visible " << m_ModelRect.ToString());
858 
859  //CGlAttrGuard AttrGuard(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT | GL_HINT_BIT
860  // | GL_LINE_SMOOTH | GL_POLYGON_MODE | GL_LINE_BIT);
861 
862  IRender& gl = GetGl();
863 
864  gl.Enable(GL_BLEND);
865  gl.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
866 
867  // render bounds rectangle
868  pane.OpenPixels();
869  gl.Color3d(0.97, 0.97, 0.97);
870  gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
871  gl.RectC(m_VPRect);
872  pane.Close();
873  // END of render bounds rectangle
874 
875  pane.OpenOrtho();
876 
877  gl.Color3d(1, 0.5, 0.5);
878  gl.PolygonMode(GL_FRONT_AND_BACK, GL_FILL);
879 
880  //LOG_POST(Info << " Rendering " << m_Layers.size() << " layers");
881  TModelUnit top = m_ModelRect.Top() - pane.GetOffsetY();
882  TModelUnit bottom = top + m_LayerH;
883 
884  // render all Layers
885  for( size_t i = 0; i < m_Layers.size(); i++ ) {
886  TFeatRecPtrs& recs = m_Layers[i]->m_FeatRecPtrs;
887 
888  // render Layer with index i
889  for( size_t j = 0; j < recs.size(); j++ ) {
890  SFeatRec& rec = *recs[j];
891  x_RenderFeature(pane, rec, (int)i, top, bottom);
892  }
893 
894  top += m_LayerH;
895  bottom += m_LayerH;
896  }
897 
898  pane.Close();
899 }
900 
901 
903 {
904  static CRgbaColor c_red(1.0f, 0.5f, 0.5f);
905  int angle = i_color * 131;
906  return CRgbaColor(CRgbaColor::RotateColor(c_red, (float) angle));
907 }
908 
909 
911 {
912  typedef map<CSeqFeatData::ESubtype, CRgbaColor> TTypeToColor;
913 
914  static TTypeToColor s_map;
915  if(s_map.empty()) {
916  s_map[CSeqFeatData::eSubtype_gene] = CRgbaColor(0.0f, 0.8f, 0.0f);
917  s_map[CSeqFeatData::eSubtype_mRNA] = CRgbaColor(0.0f, 0.0f, 0.8f);
918  s_map[CSeqFeatData::eSubtype_cdregion] = CRgbaColor(0.8f, 0.0f, 0.0f);
919  }
920 
921  TTypeToColor::iterator it = s_map.find(subtype);
922  if(it == s_map.end()) {
923  size_t i = s_map.size();
925  it = s_map.insert(TTypeToColor::value_type(subtype, color)).first;
926  }
927  return it->second;
928 }
929 
930 
931 
932 // assuming CGlPane::OpenOrtho()
933 void CAlignedFeatureGraph::x_RenderFeature(CGlPane& pane, const SFeatRec& rec, int layer,
934  TModelUnit top, TModelUnit bottom)
935 {
936  IRender& gl = GetGl();
937 
938 // const CSeq_feat& feat = *rec.m_FeatLoc.m_Feature;
939  const CSeq_feat& feat = rec.GetFeature();
940  const CSeq_loc& loc = rec.GetLocation();
941 
942  TFeatRange r = loc.GetTotalRange();
943 
944  const TModelRect& rc_vis = pane.GetVisibleRect();
945  if(r.GetFrom() > rc_vis.Right() || r.GetToOpen() < rc_vis.Left()) {
946  return; // feature does not overlap visible range
947  }
948 
949  TModelUnit off_x = pane.GetOffsetX();
950  TModelUnit scale_x = pane.GetScaleX();
951 
952  TModelUnit y1, y2;
953  TModelUnit x1 = r.GetFrom() - off_x;
954  TModelUnit x2 = r.GetToOpen() - off_x;
955 
956  // render cluster's backgorund
957  if(rec.GetClusterIndex() >= 0) {
958  _ASSERT(rec.GetClusterIndex() < (int) m_Clusters.size());
959  const SCluster& cluster = m_Clusters[rec.GetClusterIndex()];
960 
961  y1 = top + ((layer == cluster.m_FirstLayer) ? +2 : 0);
962  y2 = bottom + ((layer == cluster.m_LastLayer) ? -2 : 0);
963 
964  gl.Color3d(0.90, 0.90, 0.90);
965  TModelUnit cl_off = std::min(cluster.m_Offset / 2.0, scale_x * 3.0);
966  gl.Rectd(x1 - cl_off, y1, x2 + cl_off, y2);
967  }
968 
969  // render total range
970  TModelUnit y_c = (top + bottom) / 2;
971 
972  CRgbaColor& c = GetColor(feat.GetData().GetSubtype());
973  gl.ColorC(c);
974 
975  gl.Begin(GL_LINES);
976  gl.Vertex2d(x1, y_c);
977  gl.Vertex2d(x2, y_c);
978  gl.End();
979 
980  // render segments
981  for( CSeq_loc_CI it(loc); it; ++it) {
982  CSeq_loc::TRange r = it.GetRange();
983 
984  x1 = r.GetFrom() - off_x;
985  x2 = r.GetToOpen() - off_x;
986 
987  if((x2 - x1) / scale_x < 1.0) {
988  // render at least 1 pixel
989  x1 = (x1 + x2 - scale_x) / 2;
990  x2 = x1 + scale_x;
991  }
992 
993  gl.Rectd(x1, top + kLayerOffY, x2, bottom - kLayerOffY);
994  }
995 }
996 
997 
999 {
1000  TVPUnit h = m_LayerH * (TVPUnit)m_Layers.size();
1001  return TVPPoint(0, h);
1002 }
1003 
1004 static const int kTootipPix = 2;
1005 
1006 bool CAlignedFeatureGraph::NeedTooltip(CGlPane& pane, int vp_x, int vp_y)
1007 {
1008  m_TooltipRec = NULL;
1009 
1010  if(m_VPRect.PtInRect(vp_x, vp_y)) {
1011  int layer = (m_VPRect.Top() - vp_y) / m_LayerH;
1012  if(layer >= 0 && layer < (int) m_Layers.size()) {
1013  pane.OpenOrtho();
1014  pane.Close();
1015  TModelUnit pos = pane.UnProjectX(vp_x);
1016 
1017  // find the closet feature
1018  TModelUnit min_dist = -1, dist;
1019  SFeatRec* min_rec = NULL;
1020 
1021  TFeatRecPtrs& recs = m_Layers[layer]->m_FeatRecPtrs;
1022  NON_CONST_ITERATE(TFeatRecPtrs, it, recs) {
1023  SFeatRec& rec = **it;
1024 // CSeq_loc& loc = *rec.m_FeatLoc.m_MappedLoc;
1025  const CSeq_loc& loc = rec.GetLocation();
1026 
1027  TFeatRange r = loc.GetTotalRange();
1028 
1029  // calculate the horx distance from mouse pos to the feature
1030  if(pos < r.GetFrom()) {
1031  dist = r.GetFrom() - pos;
1032  } else {
1033  if(pos > r.GetToOpen()) {
1034  dist = pos - r.GetToOpen();
1035  } else {
1036  dist = 0.0;
1037  }
1038  }
1039 
1040  if(min_dist < 0 || dist < min_dist) {
1041  min_rec = &rec;
1042  min_dist = dist;
1043  }
1044  }
1045 
1046  TModelUnit d = pane.GetScaleX() * kTootipPix;
1047  if(min_dist < d) {
1048  m_TooltipRec = min_rec;
1049  }
1050  }
1051  return true;
1052  }
1053  _ASSERT(false);
1054  return false;
1055 }
1056 
1057 
1059 {
1060  if(m_TooltipRec) {
1061  string s = x_GetTooltip(*m_TooltipRec);
1062  //s += "\n\nDEBUG Feat ptr";
1063  //s += NStr::PtrToString(&feat);
1064  return s;
1065  }
1066  return string("Feature Graph - ") + m_Label;
1067 }
1068 
1069 
1070 // copy of CDefaultPolicy::x_GetTitle()
1071 // TODO - code reuse
1073 {
1074  string title;
1075  const CSeq_feat& feat = rec.GetFeature();
1076  const CSeq_feat::TData& data = feat.GetData();
1077  title = "Feature";
1078  const CFeatList& feats(*CSeqFeatData::GetFeatList());
1079  CFeatListItem item;
1080  if (feats.GetItemBySubtype(feat.GetData().GetSubtype(), item)) {
1081  title += "[" + item.GetStoragekey() + "]";
1082  }
1083  title += ": ";
1084 
1085  // const CSeq_feat& feat = *rec.m_FeatLoc.m_Feature;
1086  string label;
1088  title += label;
1089 
1090 
1091  string feat_title;
1092  // Brief description goes here
1093  if (data.IsSeq()) {
1095  } else if (data.IsGene() && data.GetGene().IsSetDesc()) {
1096  feat_title = data.GetGene().GetDesc();
1097  } else {
1099  }
1100  if (feat_title != label) {
1101  // avoid showing the duplicated information
1102  title += "\nTitle: " + feat_title;
1103  }
1104 
1105  //CLabel::GetLabel(feat, &title, CLabel::eDescriptionBrief,
1106  // m_Scope.GetPointer());
1107 
1108  /// add on a statement about feature lengths
1109  title += "\nTotal length: ";
1110  title += NStr::IntToString
1112  if ( ! feat.GetLocation().IsInt() &&
1113  !feat.GetLocation().IsPnt() ) {
1114  try {
1115  title += "; Processed length: ";
1116  title += NStr::IntToString
1119  }
1120  catch (CException&) {
1121  }
1122  }
1123  if (feat.IsSetProduct()) {
1124  try {
1125  string prod_len_str;
1126  CBioseq_Handle h = m_Scope->GetBioseqHandle(*feat.GetProduct().GetId());
1127  prod_len_str += "; Product length: ";
1128  prod_len_str += NStr::IntToString(h.GetBioseqLength(),
1130  title += prod_len_str;
1131  }
1132  catch (CException&) {
1133  }
1134  }
1135 
1136  // report mapped location
1137  // const CSeq_loc& loc = *rec.m_FeatLoc.m_MappedLoc;
1138  const CSeq_loc& loc = rec.GetLocation();
1139 
1140  TFeatRange r = loc.GetTotalRange();
1141  title += "\nPosition in alignment: start ";
1142  title += NStr::IntToString(r.GetFrom() + 1, NStr::fWithCommas);
1143  title += ", end ";
1144  title += NStr::IntToString(r.GetTo() + 1, NStr::fWithCommas);
1145 
1146  return title;
1147 }
1148 
1149 
1151 {
1152  ITERATE(TLayers, it, m_Layers) {
1153  delete *it;
1154  }
1155  m_Layers.clear();
1156 }
1157 
1158 
1159 
1160 typedef pair<size_t, TSeqPos> TIndexLenPair; // rec index -> length
1161 static bool s_ILPLonger(const TIndexLenPair& p1, const TIndexLenPair& p2)
1162 {
1163  return p1.second > p2.second;
1164 }
1165 
1167 {
1168  //LOG_POST("CAlignedFeatureGraph::x_Layout() - started");
1169  size_t feat_n = m_FeatRecs.size();
1170 
1171  //sort features by length of mapped locations
1172  typedef pair<size_t, TSeqPos> TIndexLenPair; // rec index -> length
1173  vector<TIndexLenPair> feat_lens;
1174  feat_lens.reserve(feat_n);
1175 
1176  for( size_t i = 0; i < feat_n; i++ ) {
1177 // const SMappedFeatLoc& feat_loc = m_FeatRecs[i].m_FeatLoc;
1178 // const CSeq_loc& loc = *feat_loc.m_MappedLoc;
1179 
1180  const CSeq_loc& loc = m_FeatRecs[i].GetLocation();
1181 
1182  TFeatRange r = loc.GetTotalRange();
1183  int len = r.GetLength();
1184 
1185  feat_lens.push_back(TIndexLenPair(i, len));
1186  }
1187 
1188  // stable sort by length
1189  std::stable_sort(feat_lens.begin(), feat_lens.end(), s_ILPLonger);
1190 
1191  // place record pointers into a vector in the sorted order
1192  TFeatRecPtrs sorted_recs(feat_n, NULL);
1193  for( size_t i = 0; i < feat_n; i++ ) {
1194  size_t index = feat_lens[i].first;
1195  sorted_recs[i] = &m_FeatRecs[index];
1196  }
1197 
1198  // layout features
1199  if(m_LinkGenes) {
1200  x_LinkedLayout(sorted_recs);
1201  } else {
1202  x_SimpleLayout(sorted_recs);
1203  }
1204 
1205  //clean-up temporary structures
1207  delete *it;
1208  }
1209  m_Occupied.clear();
1211 }
1212 
1213 
1215 {
1216  //LOG_POST("x_SimpleLayout() - " << m_Label << ", " << feat_recs.size() << " features");
1217 
1218  size_t n = feat_recs.size();
1219  for( size_t i = 0; i < n; i++ ) {
1220  SFeatRec& rec = *feat_recs[i];
1221  x_PlaceFeature(rec);
1222  }
1223 }
1224 
1225 
1227 {
1228  //LOG_POST("x_LinkedLayout() - " << m_Label << ", " << feat_recs.size() << " features");
1229 
1230  size_t feat_n = feat_recs.size();
1231 
1232  // preapre m_FeatToRecFlag
1233  for( size_t i = 0; i < feat_n; i++ ) {
1234  SFeatRec& feat_rec = *feat_recs[i];
1235 // const CSeq_feat* feat = feat_rec.m_FeatLoc.m_Feature.GetPointer();
1236  const CSeq_feat* feat = &feat_rec.GetFeature();
1237 
1238  CSeqFeatData::ESubtype subtype = feat->GetData().GetSubtype();
1239  if(subtype == CSeqFeatData::eSubtype_mRNA ||
1240  subtype == CSeqFeatData::eSubtype_cdregion) {
1241  m_FeatToRecFlag[feat] = TFeatToRecFlag::mapped_type(&feat_rec, false);
1242  }
1243  }
1244 
1245  // place Genes clusters (Gene + mRNAs and CDS-es)
1246  TFeatRecPtrs cluster;
1247  for( size_t i = 0; i < feat_n; i++ ) {
1248  SFeatRec& feat_rec = *feat_recs[i];
1249 // const CSeq_feat* feat = feat_rec.m_FeatLoc.m_Feature.GetPointer();
1250  const CSeq_feat* feat = &feat_rec.GetFeature();
1251 
1253  x_GatherCluster(feat_rec, cluster);
1254  x_PlaceCluster(cluster);
1255  cluster.clear();
1256  }
1257  }
1258 
1259  // place mRNA-s clusters
1260  for( size_t i = 0; i < feat_n; i++ ) {
1261  SFeatRec& feat_rec = *feat_recs[i];
1262 // const CSeq_feat* feat = feat_rec.m_FeatLoc.m_Feature.GetPointer();
1263  const CSeq_feat* feat = &feat_rec.GetFeature();
1264 
1266  if(x_mRNA_CDS_ToBePlaced(*feat)) {
1267  x_GatherCluster(feat_rec, cluster);
1268  x_PlaceCluster(cluster);
1269  cluster.clear();
1270  }
1271  }
1272  }
1273 
1274  // place CDS-es that are not linked
1275  for( size_t i = 0; i < feat_n; i++ ) {
1276  SFeatRec& feat_rec = *feat_recs[i];
1277 // const CSeq_feat* feat = feat_rec.m_FeatLoc.m_Feature.GetPointer();
1278  const CSeq_feat* feat = &feat_rec.GetFeature();
1279 
1281  x_TryPlaceCDSFeature(feat_rec);
1282  }
1283  }
1284 
1285  // place everything that has not been placed yet
1286  for( size_t i = 0; i < feat_n; i++ ) {
1287  SFeatRec& feat_rec = *feat_recs[i];
1288  const CSeq_feat* feat = &feat_rec.GetFeature();
1289 // const CSeq_feat* feat = feat_rec.m_FeatLoc.m_Feature.GetPointer();
1290 
1291  CSeqFeatData::ESubtype subtype = feat->GetData().GetSubtype();
1292  switch(subtype) {
1296  break; // should be already placed
1297  }
1298  default:
1299  x_PlaceFeature(feat_rec);
1300  }
1301  }
1302 }
1303 
1304 
1305 // for a given features gathers or linked features and packs all features into
1306 // provided container in proper order
1308  TFeatRecPtrs& cluster)
1309 {
1310  //CSeqFeatData::ESubtype subtype = feat_rec.m_FeatLoc.m_Feature->GetData().GetSubtype();
1311  CSeqFeatData::ESubtype subtype = feat_rec.GetFeature().GetData().GetSubtype();
1312 
1313  switch(subtype) {
1315  cluster.push_back(&feat_rec); // add gene record
1316 
1317  // process linked mRNAs
1318  TFeatList mrna_feats;
1319 // const CSeq_feat& feat = *feat_rec.m_FeatLoc.m_Feature;
1320  const CSeq_feat& feat = feat_rec.GetFeature();
1321 
1322 
1323  sequence::GetMrnasForGene(feat, *m_Scope, mrna_feats);
1324 
1325  vector<TFeatRecPtrLenPair> pairs;
1326  x_GetRecsSortedByLength(mrna_feats, pairs);
1327 
1328  ITERATE(vector<TFeatRecPtrLenPair>, it_mrna, pairs) {
1329  SFeatRec* mrna_feat_rec = it_mrna->first;
1330 // const CSeq_feat& mrna_feat = *mrna_feat_rec->m_FeatLoc.m_Feature;
1331  const CSeq_feat& mrna_feat = mrna_feat_rec->GetFeature();
1332 
1333 
1334  if(x_mRNA_CDS_ToBePlaced(mrna_feat)) {
1335  x_GatherCluster(*mrna_feat_rec, cluster);
1336  }
1337  }
1338 
1339  // process CDS-es linked directly to the Gene
1340  TFeatList cds_feats;
1341  sequence::GetCdssForGene(feat, *m_Scope, cds_feats);
1342 
1343  pairs.clear();
1344  x_GetRecsSortedByLength(cds_feats, pairs);
1345 
1346  ITERATE(vector<TFeatRecPtrLenPair>, it_cds, pairs) {
1347  SFeatRec* cds_feat_rec = it_cds->first;
1348  //const CSeq_feat& cds_feat = *cds_feat_rec->m_FeatLoc.m_Feature;
1349  const CSeq_feat& cds_feat = cds_feat_rec->GetFeature();
1350 
1351 
1352  // check if this CDS is already included in the cluster
1353  TFeatRecPtrs::const_iterator it =
1354  std::find(cluster.begin(), cluster.end(), cds_feat_rec);
1355  // if not in cluster and not placed yet - place it
1356  if((it == cluster.end()) && x_mRNA_CDS_ToBePlaced(cds_feat)) {
1357  x_GatherCluster(*cds_feat_rec, cluster);
1358  }
1359  }
1360  break;
1361  }
1363  cluster.push_back(&feat_rec); // add mRNA
1364 
1365  // get linked CDS
1366 // const CSeq_feat& feat = *feat_rec.m_FeatLoc.m_Feature;
1367  const CSeq_feat& feat = feat_rec.GetFeature();
1368 
1369 
1371 
1373  if((it != m_FeatToRecFlag.end()) && ! it->second.second) {
1374  SFeatRec* cds_feat_rec = it->second.first;
1375  x_GatherCluster(*cds_feat_rec, cluster);
1376  }
1377  break;
1378  }
1380  cluster.push_back(&feat_rec); // add CDS
1381  break;
1382  }
1383  default:
1384  break;
1385  }
1386 }
1387 
1388 
1391 {
1392  return p1.second > p2.second;
1393 }
1394 
1395 // takes a list of features, finds records corresponding to the features
1396 // and sorts them by length of their mapped locations
1398  vector<TFeatRecPtrLenPair>& pairs)
1399 {
1400  pairs.clear();
1401 
1402  ITERATE(TFeatList, it_f, input) {
1403  const CSeq_feat* feat = *it_f;
1405 
1406  if(it != m_FeatToRecFlag.end()) {
1407  SFeatRec* rec = it->second.first;
1408 // TFeatRange r = rec->m_FeatLoc.m_MappedLoc->GetTotalRange();
1409  TFeatRange r = rec->GetLocation().GetTotalRange();
1410 
1411  int len = r.GetLength();
1412 
1413  pairs.push_back(TFeatRecPtrLenPair(rec, len));
1414  }
1415  }
1416  std::stable_sort(pairs.begin(), pairs.end(), s_FRPLPLonger);
1417 }
1418 
1419 
1420 // returns true if the given feature is mRNA or CDS, belongs to this
1421 // graph and have not been placed yet
1423 {
1425  bool found = it != m_FeatToRecFlag.end();
1426  return (found && ! it->second.second);
1427 }
1428 
1429 
1430 // places all features in the cluster
1432 {
1433  size_t cl_n = cluster.size();
1434 
1435  // calculate cluster bounds
1436  TFeatRange total_r;
1437  vector<TFeatRange> cluster_ranges(cl_n); // extents of the features
1438 
1439  for( size_t i = 0; i < cluster.size(); i++ ) {
1440  SFeatRec* rec = cluster[i];
1441 // TFeatRange r = rec->m_FeatLoc.m_MappedLoc->GetTotalRange();
1442  TFeatRange r = rec->GetLocation().GetTotalRange();
1443 
1444 
1445  cluster_ranges[i] = r;
1446  if(i == 0) {
1447  total_r = r;
1448  } else {
1449  total_r.CombineWith(r);
1450  }
1451  }
1452 
1453  // Extend ranges on both sides to separate this cluster from other features
1454  // offset on each side is the larger of 4% of total_r and kMinOffset
1455  static const TSeqPos kMinOffset = 500;
1456  TSeqPos percent = TSeqPos(total_r.GetLength() / 25); // 4%
1457  TSeqPos offset = std::max(percent, kMinOffset);
1458 
1459  for( size_t i = 0; i < cluster.size(); i++ ) {
1460  TFeatRange& r = cluster_ranges[i];
1461  r.SetFrom(r.GetFrom() > offset ? r.GetFrom() - offset : 0);
1462  r.SetTo(r.GetTo() + offset);
1463  }
1464 
1465  // now find the area where we can place the whole cluster, so that all
1466  // features will be located in the proper order on neighbouring layers
1467  size_t layer_index = m_Layers.size(); // invalid index
1468 
1469  _ASSERT(cl_n > 0);
1470  size_t occ_n = m_Occupied.size();
1471  for( size_t j = 0; j < occ_n; j++ ) {
1472  // iterate by features in the cluster
1473  bool clash = false;
1474  size_t k_end = min(cl_n, occ_n - j);
1475  for( size_t k = 0; ! clash && k < k_end; k++ ) {
1476  TColl& coll = *m_Occupied[j + k];
1477  SFeatRec* rec = cluster[k];
1478 // const TFeatRange& r = rec->m_FeatLoc.m_MappedLoc->GetTotalRange();
1479  TFeatRange r = rec->GetLocation().GetTotalRange();
1480 
1481  clash = coll.IntersectingWith(r);
1482  }
1483  if( ! clash) {
1484  // all features in cluster can be placed
1485  layer_index = j;
1486  break;
1487  }
1488  }
1489 
1490  if(layer_index + cl_n > m_Layers.size()) {
1491  // need to create new layers
1492  size_t k_end = layer_index + cl_n;
1493  for( size_t k = m_Layers.size(); k < k_end; k++ ) {
1494  m_Layers.push_back(new SLayer());
1495  m_Occupied.push_back(new TColl);
1496  }
1497  }
1498 
1499  // create cluster
1500  m_Clusters.push_back(SCluster((int)layer_index, (int)(layer_index + cl_n - 1), (int)offset));
1501  size_t cluster_index = m_Clusters.size() - 1;
1502 
1503  // add features to the layers
1504  for( size_t k = 0; k < cl_n; k++ ) {
1505  size_t index = size_t(layer_index + k);
1506  SFeatRec* rec = cluster[k];
1507  rec->SetClusterIndex((int)cluster_index);
1508  m_Layers[index]->m_FeatRecPtrs.push_back(rec);
1509 
1510  const TFeatRange& r = cluster_ranges[k];
1511 
1512  m_Occupied[index]->CombineWith(r); // reserve occupied space
1513 
1514  // mark CDS or mRNA as placed
1515 // const CSeq_feat* feat = rec->m_FeatLoc.m_Feature.GetPointer();
1516  const CSeq_feat* feat = &rec->GetFeature();
1517 
1518 
1520  if(it != m_FeatToRecFlag.end()) {
1521  it->second.second = true;
1522  }
1523  }
1524 }
1525 
1526 
1528 {
1529 // const CSeq_feat* feat = rec.m_FeatLoc.m_Feature.GetPointer();
1530  const CSeq_feat* feat = &rec.GetFeature();
1531 
1532 
1534 
1535  if(it != m_FeatToRecFlag.end() && ! it->second.second) {
1536  // this is our feature and it is not placed yet
1537  x_PlaceFeature(rec);
1538  it->second.second = true; // now placed
1539  }
1540 }
1541 
1542 
1543 // places the provided feature and updates m_Occupied accordingly
1544 // if needed a new layer is created
1546 {
1547  //TFeatRange r = rec.m_FeatLoc.m_MappedLoc->GetTotalRange();
1548  TFeatRange r = rec.GetLocation().GetTotalRange();
1549  // extend the range by 1 base on both side to make
1550  // sure abutting features are on different layers
1551  if (r.GetFrom() > 0) r.SetFrom(r.GetFrom() - 1);
1552  r.SetTo(r.GetTo() + 1);
1553 
1554  // index of the layer where the feature will be placed
1555  size_t layer_index = m_Layers.size(); // init with out of range value
1556 
1557  // iterate existing layers and try to find a place for the feature
1558  for( size_t j = 0; j < m_Occupied.size(); j++ ) {
1559  TColl& coll = *m_Occupied[j];
1560  if( ! coll.IntersectingWith(r)) {
1561  layer_index = j; // found a spot
1562  break;
1563  }
1564  }
1565 
1566  if(layer_index == m_Layers.size()) {
1567  // no space available - create a new layer
1568  m_Layers.push_back(new SLayer());
1569  m_Occupied.push_back(new TColl);
1570  }
1571 
1572  // add feature record to the layer
1573  m_Layers[layer_index]->m_FeatRecPtrs.push_back(&rec);
1574 
1575  // reserve occupied space
1576  m_Occupied[layer_index]->CombineWith(r);
1577 }
1578 
1579 
1580 ///////////////////////////////////////////////////////////////////////////////
1581 /// CFeatHistogramDS
1582 
1584 : m_Label(label),
1585  m_FeatLocs(feat_locs)
1586 {
1587  ITERATE(TMappedFeatLocs, it, feat_locs) {
1588  const CSeq_loc& loc= *it->m_MappedLoc;
1589  TFeatRange r = loc.GetTotalRange();
1590  if(m_FeatRange.Empty()) {
1591  m_FeatRange = r;
1592  } else {
1594  }
1595  }
1597 }
1598 
1599 
1601 {
1602  return m_FeatRange.GetToOpen();
1603 }
1604 
1605 
1607 {
1608  return m_Map->GetStart();
1609 }
1610 
1612 {
1613  return m_Map->GetStop();
1614 }
1615 
1616 
1618 {
1619  return m_Map->GetWindow();
1620 }
1621 
1622 
1624 {
1625  return m_Map->GetBins();
1626 }
1627 
1628 
1629 double CFeatHistogramDS::GetValue(size_t index)
1630 {
1631  return (*m_Map)[index];
1632 }
1633 
1634 
1636 {
1637  return m_Map->GetMax();
1638 }
1639 
1640 
1642 {
1643  return m_Label;
1644 }
1645 
1646 static const int kBins = 2048;
1647 
1648 void CFeatHistogramDS::Update(double start, double stop)
1649 {
1650  //LOG_POST("CFeatHistogramDS::Update() " << start << " " << stop);
1651 
1652  _ASSERT(start >= 0 && stop <= m_FeatRange.GetToOpen() && start < stop);
1653 
1654  TSeqPos pos_start = (TSeqPos) floor(start);
1655  TSeqPos pos_stop = (TSeqPos) ceil(stop);
1656 
1657  if(m_Map.get() == NULL || pos_start != m_Map->GetStart() || pos_stop != m_Map->GetStop()) {
1658  float window = float(pos_stop - start) / float(kBins);
1659  m_Map.reset(new TMap(pos_start, pos_stop, window));
1660 
1662  const CSeq_loc& loc= *it->m_MappedLoc;
1663  m_Map->AddLocation(loc);
1664  }
1665  }
1666 }
1667 
1668 
static CRef< CScope > m_Scope
vector< TColl * > TCollVector
virtual void x_Init(TMappedFeatLocs &feat_locs, objects::CScope &scope, const string &label, bool link_genes)
void x_GetRecsSortedByLength(const TFeatList &input, vector< TFeatRecPtrLenPair > &pairs)
void x_GatherCluster(SFeatRec &feat_rec, TFeatRecPtrs &cluster)
virtual ~CAlignedFeatureGraph()
list< CConstRef< objects::CSeq_feat > > TFeatList
virtual bool NeedTooltip(CGlPane &pane, int vp_x, int vp_y)
virtual TVPPoint PreferredSize()
void x_RenderFeature(CGlPane &pane, const SFeatRec &rec, int layer, TModelUnit top, TModelUnit bottom)
virtual void Render(CGlPane &pane)
void x_PlaceCluster(TFeatRecPtrs &cluster)
pair< SFeatRec *, TSeqPos > TFeatRecPtrLenPair
virtual string x_GetTooltip(const SFeatRec &rec)
bool x_mRNA_CDS_ToBePlaced(const objects::CSeq_feat &feat)
CRef< objects::CScope > m_Scope
TFeatToRecFlag m_FeatToRecFlag
void x_SimpleLayout(TFeatRecPtrs &feat_recs)
void x_PlaceFeature(SFeatRec &rec)
void x_TryPlaceCDSFeature(SFeatRec &rec)
virtual string GetTooltip()
vector< SLayer * > TLayers
void x_LinkedLayout(TFeatRecPtrs &feat_recs)
vector< SFeatRec * > TFeatRecPtrs
CAppJobDispatcher.
CAppJobError Default implementation for IAppJobError - encapsulates a text error message.
IAppJobListener Interface for components that need to be notified about changes in Jobs.
CAppJobNotification Notification send by CAppJobEventTranslator.
CBioseq_Handle –.
CEventHandler.
CEvent - generic event implementation TODO TODO - Attachments.
Definition: event.hpp:86
CFeatHistogramDS.
virtual void Update(double start, double stop)
vector< SMappedFeatLoc > TMappedFeatLocs
CFeatHistogramDS(TMappedFeatLocs &feat_locs, const string &label)
CFeatHistogramDS.
virtual string GetLabel() const
TFeatRange m_FeatRange
virtual double GetStop() const
virtual double GetValue(size_t index)
value of the sample with the given index
CDensityMap< int > TMap
virtual double GetMaxValue()
virtual double GetLimit() const
returns start of the series in model space
TMappedFeatLocs m_FeatLocs
virtual double GetStart() const
unique_ptr< TMap > m_Map
virtual double GetStep() const
discrete size in model space
virtual size_t GetCount() const
number of samples in the series
CFeatListItem - basic configuration data for one "feature" type.
string GetStoragekey() const
CConfigurableItems - a static list of items that can be configured.
bool GetItemBySubtype(int subtype, CFeatListItem &config_item) const
CFeat_CI –.
Definition: feat_ci.hpp:64
CFeatureGraphProperties.
TFeatTypeItemSet m_FeatureTypes
defines what feature types / subtypes shall be shown
CFeatureGraph.
TGraphs m_PendingGraphs
Candidate graphs waiting for replacing the current ones.
virtual void Layout()
CFeatureGraph(const IAlignRowHandle &row_handle, bool isDataReadSync)
virtual bool IsCreated() const
Graph is not considered fully functional until it has been "created" by the call to create function.
virtual const IAlnRowGraphProperties * GetProperties() const
virtual void Destroy()
void OnAJNotification(CEvent *evt)
void x_StartJob(const TFeatTypeItemSet &feat_set, const TSubtypeSet &filter, bool positive, CRange< TSeqPos > &total_range, TMapRanges &map_ranges, const string &descr, bool separate_types, bool link_genes, int order)
CFeatureGraphProperties m_Properties
CGlTextureFont m_Font
virtual bool Create()
void x_Create(double start, double stop)
virtual ~CFeatureGraph()
CRef< TMapRanges > x_CreateMapRanges()
const IAlignRowHandle & m_RowHandle
virtual void Update(double start, double stop)
Update data according to the input range.
virtual void Render(CGlPane &pane, IAlnSegmentIterator &it)
CAppJobDispatcher::TJobID TJobID
objects::CMappingRanges TMapRanges
bool x_CancelJob(TJobID job_id)
void x_RenderStatusText(CGlPane &pane)
void x_CancelJobs()
Cancel all active jobs.
void x_OnJobFailed(CAppJobNotification &notify)
virtual void SetProperties(IAlnRowGraphProperties *props)
void x_OnJobCompleted(CAppJobNotification &notify)
CFeatureLoadingJobResult.
vector< CIRef< IRenderable > > TGraphs
CFeatureLoadingJob.
virtual EJobState Run()
Function that does all the useful work, called by the Engine.
CRef< CFeatureLoadingJobResult > m_Result
CRange< TSeqPos > m_TotalRange
objects::CBioseq_Handle m_Handle
bool m_LinkGenes
links genes with CDS and mRNA
objects::CMappingRanges TMapRanges
virtual string GetDescr() const
Returns a human readable description of the Job (optional)
vector< SMappedFeatLoc > TMappedFeatLocs
CMutex m_Mutex
synchronizes access to the Job members
objects::SAnnotSelector m_Sel
CFeatureLoadingJob(const objects::CBioseq_Handle &handle, objects::SAnnotSelector &sel, const CRange< TSeqPos > &total_range, TMapRanges &ranges, const string &descr, bool separate_types, bool link_genes, int track_order)
CFeatureLoadingJob.
virtual ~CFeatureLoadingJob()
bool m_SeparateTypes
separate features by different graphs
virtual CConstIRef< IAppJobProgress > GetProgress()
return progress object, the function shall be synchronized internally.
CIRef< IAppJobError > m_Error
CRef< TMapRanges > m_MapRanges
virtual CConstIRef< IAppJobError > GetError()
Returns IAppJobError object describing internal error that caused the Job to fail.
virtual CRef< CObject > GetResult()
Returns the Job Result.
CIRef< IRenderable > x_CreateGraph(TMappedFeatLocs &feat_locs, const string &descr)
class CGlPane
Definition: glpane.hpp:62
CGraphContainer CGraphContainer a composite IRenderable that manages several child IRenderable graphs...
virtual void Layout()
vector< TGraphRef > TGraphs
virtual void RemoveAllGraphs()
virtual size_t GetGraphsCount() const
virtual void Render(CGlPane &pane)
virtual bool AddGraph(TGraph *graph, bool front=false)
ELayoutPolicy m_LayoutPolicy
virtual TVPPoint PreferredSize()
CHistogramGraph.
void SetProperties(const SProperties &props)
virtual void SetDataSource(IHistogramGraphDS *ds)
CMappedFeat –.
Definition: mapped_feat.hpp:59
Storage for multiple mapping ranges.
bool IntersectingWith(const TRange &r) const
Definition: range_coll.hpp:187
TModelRect m_ModelRect
class CRgbaColor provides a simple abstraction for managing colors.
Definition: rgba_color.hpp:58
CScope –.
Definition: scope.hpp:92
ESubtype GetSubtype(void) const
static const CFeatList * GetFeatList()
@ eSubtype_bad
These no longer need to match the FEATDEF values in the C toolkit's objfdef.h.
list< CRef< CSeqGlyph > > TObjects
Definition: seq_glyph.hpp:85
namespace ncbi::objects::
Definition: Seq_feat.hpp:58
Seq-loc iterator class – iterates all intervals from a seq-loc in the correct order.
Definition: Seq_loc.hpp:453
CSeq_loc_Mapper –.
static CSeq_id_Handle GetSeq_id_Handle(const const_iterator &iter)
IAlignRowHandle provides an abstract way to access alignment row data.
Definition: alnmulti_ds.hpp:59
virtual TSignedSeqPos GetSeqAlnStart() const =0
virtual const objects::CBioseq_Handle & GetBioseqHandle() const =0
virtual TSignedSeqPos GetSeqPosFromAlnPos(TSeqPos aln_pos, IAlnExplorer::ESearchDirection dir=IAlnExplorer::eNone, bool try_reverse_dir=true) const =0
virtual TSignedSeqPos GetSeqAlnStop() const =0
virtual IAlnSegmentIterator * CreateSegmentIterator(const IAlnExplorer::TSignedRange &range, IAlnSegmentIterator::EFlags flags) const =0
@ eRight
Towards higher aln coord (always to the right)
@ eLeft
Towards lower aln coord (always to the left)
IAlnRowGraphProperties.
Alignment segment iterator interface.
@ eSkipInserts
Iterate segments where at least some rows are aligned (including gap segments)
Alignment segment interface.
virtual const TSignedRange & GetRange(void) const =0
Get the selected row range.
bool IsReversed(void) const
bool IsAligned(void) const
virtual const TSignedRange & GetAlnRange(void) const =0
Get alignment range for the segment.
IAppJobError.
Definition: app_job.hpp:65
IRenderable class IRenderable defines an abstract interface required for rendering graphical panels i...
Definition: irenderable.hpp:50
virtual void SetModelRect(const TModelRect &rc)=0
virtual void SetVPRect(const TVPRect &rc)=0
virtual TVPPoint PreferredSize()=0
void erase(iterator pos)
Definition: map.hpp:167
const_iterator end() const
Definition: map.hpp:152
bool empty() const
Definition: map.hpp:149
void clear()
Definition: map.hpp:169
const_iterator find(const key_type &key) const
Definition: map.hpp:153
Definition: map.hpp:338
iterator_bool insert(const value_type &val)
Definition: set.hpp:149
bool empty() const
Definition: set.hpp:133
const_iterator find(const key_type &key) const
Definition: set.hpp:137
const_iterator end() const
Definition: set.hpp:136
Include a standard set of the NCBI C++ Toolkit most basic headers.
static const int kBins
ON_EVENT(CAppJobNotification, CAppJobNotification::eStateChanged, &CFeatureGraph::OnAJNotification) TVPPoint CFeatureGraph
CRgbaColor & GetColor(CSeqFeatData::ESubtype subtype)
USING_SCOPE(objects)
static const int kLayerOffY
CRgbaColor GetRandomColor(int i_color)
CRange< TSeqPos > TFeatRange
static const int kGradColors
CFeatureGraph.
pair< size_t, TSeqPos > TIndexLenPair
static bool s_ILPLonger(const TIndexLenPair &p1, const TIndexLenPair &p2)
static const int kLayerH
CAlignedFeatureGraph.
static bool s_FRPLPLonger(const CAlignedFeatureGraph::TFeatRecPtrLenPair &p1, const CAlignedFeatureGraph::TFeatRecPtrLenPair &p2)
static const int kTextOff
static const int kTootipPix
#define false
Definition: bool.h:36
static DLIST_TYPE *DLIST_NAME() first(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:46
int offset
Definition: replacements.h:160
char data[12]
Definition: iconv.c:80
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
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
Definition: ncbimisc.hpp:822
void swap(NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair1, NCBI_NS_NCBI::pair_base_member< T1, T2 > &pair2)
Definition: ncbimisc.hpp:1508
string
Definition: cgiapp.hpp:687
#define NULL
Definition: ncbistd.hpp:225
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
Definition: ncbidiag.hpp:186
#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
static objects::SAnnotSelector GetAnnotSelector(TAnnotFlags flags=0)
request an annotation selector for a given type
Definition: utils.cpp:167
GLdouble TModelUnit
Definition: gltypes.hpp:48
virtual void Enable(GLenum glstate)=0
bool OpenOrtho()
Definition: glpane.hpp:427
virtual void Begin(GLenum mode)=0
Start rendering.
CGlPoint< TVPUnit > TVPPoint
Definition: gltypes.hpp:50
void SetBottom(T bottom)
Definition: glrect.hpp:113
T Top() const
Definition: glrect.hpp:84
virtual void BlendFunc(GLenum sfactor, GLenum dfactor)=0
Options to be used when GL_BLEND is enabled.
T Bottom() const
Definition: glrect.hpp:82
T Width() const
Definition: glrect.hpp:86
bool OpenPixels()
Definition: glpane.hpp:432
void Color3d(GLdouble r, GLdouble g, GLdouble b)
Definition: irender.hpp:100
IRender & GetGl()
convenience function for getting current render manager
void RectC(const TVPRect &rc)
Definition: irender.hpp:197
void Vertex2d(GLdouble x, GLdouble y)
Definition: irender.hpp:185
T Right() const
Definition: glrect.hpp:83
TModelUnit GetOffsetY() const
Definition: glpane.hpp:415
void Color4d(GLdouble r, GLdouble g, GLdouble b, GLdouble a)
Definition: irender.hpp:102
TModelUnit UnProjectX(TVPUnit m_x) const
Definition: glpane.cpp:706
T Left() const
Definition: glrect.hpp:81
T Y() const
Definition: glpoint.hpp:60
bool PtInRect(T x, T y) const
Definition: glrect.hpp:154
virtual void End()=0
Finish rendering (create buffer and send to renderer)
void Inflate(T d_x, T d_y)
Definition: glrect.hpp:178
void Close(void)
Definition: glpane.cpp:178
virtual void PolygonMode(GLenum face, GLenum mode)=0
Set the polygon rasterization mode.
int TVPUnit
Definition: gltypes.hpp:47
void SetVert(T bottom, T top)
Definition: glrect.hpp:123
virtual TModelUnit TextHeight(void) const
virtual void TextOut(const char *text) const
TextOut interface Write the specified text and set up state and transformation as needed.
TModelRect & GetVisibleRect(void)
Definition: glpane.hpp:357
TModelUnit GetScaleX(void) const
Definition: glpane.cpp:118
TModelUnit GetOffsetX() const
Definition: glpane.hpp:410
virtual void ColorC(const CRgbaColor &c)=0
Set current color (glColor{3,4}{f,d}{v,})
void Rectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2)
Definition: irender.hpp:193
@ eAlign_Left
Definition: glfont.hpp:102
CConstIRef< IAppJobError > GetError() const
returns non-null pointer only if job Failed
static CRgbaColor RotateColor(const CRgbaColor &c, float degrees)
Rotate the hue of the color by degrees.
static void GetLabel(const CObject &obj, string *label, ELabelType type=eDefault)
Definition: label.cpp:140
static CAppJobDispatcher & GetInstance()
CRef< CObject > GetResult() const
returns non-null pointer only if Completed or Running and has temporary results available
virtual bool IsCanceled() const override
bool DeleteJob(TJobID job_id)
when a Job is deleted the listener is not notified
EJobState
Job states (describe FSM)
Definition: app_job.hpp:86
TJobID StartJob(IAppJob &job, const string &engine_name, IEngineParams *params=NULL)
Starts a Job on the specified engine in "passive mode" - no notifications or progress reports will be...
#define END_EVENT_MAP()
Ends definition of Command Map.
#define BEGIN_EVENT_MAP(thisClass, baseClass)
Begins definition of Command Map for CEventHandler-derived class.
TJobState GetState() const
virtual bool Send(CEvent *evt, EDispatch disp_how=eDispatch_Default, int pool_name=ePool_Default)
Sends an event synchronously.
@ eEngine_UnknownJob
the job is not registered in the Engine
@ eUnknownJob
Job record lost.
@ eCanceled
Definition: app_job.hpp:91
@ eCompleted
Definition: app_job.hpp:89
@ eRunning
Definition: app_job.hpp:88
@ eFailed
Definition: app_job.hpp:90
@ eContent
Definition: label.hpp:62
@ eDescription
Definition: label.hpp:68
string GetLabel(const CSeq_id &id)
TRange GetTotalRange(void) const
Definition: Seq_loc.hpp:913
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
void GetMrnasForGene(const CMappedFeat &gene_feat, list< CMappedFeat > &mrna_feats, CFeatTree *feat_tree=0, const SAnnotSelector *base_sel=0)
Definition: feature.cpp:3384
void GetCdssForGene(const CMappedFeat &gene_feat, list< CMappedFeat > &cds_feats, CFeatTree *feat_tree=0, const SAnnotSelector *base_sel=0)
Definition: feature.cpp:3409
CMappedFeat GetBestCdsForMrna(const CMappedFeat &mrna_feat, CFeatTree *feat_tree=0, const SAnnotSelector *base_sel=0)
Definition: feature.cpp:3360
@ fFGL_Content
Include its content if there is any.
Definition: feature.hpp:73
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.
@ eGetId_Canonical
Definition: sequence.hpp:114
CRef< CSeq_loc > Map(const CSeq_loc &src_loc)
Map seq-loc.
void AddConversion(CRef< CMappingRange > cvt)
Add new mapping range to the proper place.
CConstRef< CSynonymsSet > GetSynonyms(const CSeq_id &id)
Get bioseq synonyms, resolving to the bioseq in this scope.
Definition: scope.cpp:486
TSeqPos GetBioseqLength(void) const
CConstRef< CSeq_id > GetSeqId(void) const
Get id which can be used to access this bioseq handle Throws an exception if none is available.
SAnnotSelector & IncludeFeatSubtype(TFeatSubtype subtype)
Include feature subtype in the search.
const CSeq_feat & GetMappedFeature(void) const
Feature mapped to the master sequence.
SAnnotSelector & AddNamedAnnots(const CAnnotName &name)
Add named annot to set of annots names to look for.
SAnnotSelector & ExcludeNamedAnnots(const CAnnotName &name)
Add named annot to set of annots names to exclude.
TObjectType * GetPointer(void) const THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:1684
TObjectType * GetPointer(void) THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:998
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
position_type GetLength(void) const
Definition: range.hpp:158
TThisType & CombineWith(const TThisType &r)
Definition: range.hpp:345
position_type GetToOpen(void) const
Definition: range.hpp:138
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
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5084
#define NcbiEmptyString
Definition: ncbistr.hpp:122
@ fWithCommas
Use commas as thousands separator.
Definition: ncbistr.hpp:254
static const char label[]
void SetFrom(TFrom value)
Assign a value to From data member.
Definition: Range_.hpp:231
TFrom GetFrom(void) const
Get the From member data.
Definition: Range_.hpp:222
const TLocation & GetLocation(void) const
Get the Location member data.
Definition: Seq_feat_.hpp:1117
const TData & GetData(void) const
Get the Data member data.
Definition: Seq_feat_.hpp:925
const TProduct & GetProduct(void) const
Get the Product member data.
Definition: Seq_feat_.hpp:1096
bool IsSetProduct(void) const
product of process Check if a value has been assigned to Product data member.
Definition: Seq_feat_.hpp:1084
bool IsEmpty(void) const
Check if variant Empty is selected.
Definition: Seq_loc_.hpp:516
ENa_strand
strand of nucleic acid
Definition: Na_strand_.hpp:64
bool IsInt(void) const
Check if variant Int is selected.
Definition: Seq_loc_.hpp:528
bool IsNull(void) const
Check if variant Null is selected.
Definition: Seq_loc_.hpp:504
bool IsPnt(void) const
Check if variant Pnt is selected.
Definition: Seq_loc_.hpp:540
@ eNa_strand_plus
Definition: Na_strand_.hpp:66
@ eNa_strand_minus
Definition: Na_strand_.hpp:67
n background color
static int input()
int i
yy_size_t n
int len
range(_Ty, _Ty) -> range< _Ty >
double value_type
The numeric datatype used by the parser.
Definition: muParserDef.h:228
const struct ncbi::grid::netcache::search::fields::SIZE size
EIPRangeType t
Definition: ncbi_localip.c:101
T positive(T x_)
T max(T x_, T y_)
T min(T x_, T y_)
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
void copy(Njn::Matrix< S > *matrix_, const Njn::Matrix< T > &matrix0_)
Definition: njn_matrix.hpp:613
double f(double x_, const double &y_)
Definition: njn_root.hpp:188
const objects::CSeq_loc & GetLocation(void) const
const objects::CSeq_feat & GetFeature(void) const
SAnnotSelector –.
#define _ASSERT
else result
Definition: token2.c:20
Modified on Fri Apr 26 16:29:02 2024 by modify_doxy.py rev. 669887