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

Go to the SVN repository for this file.

1 /* $Id: gene_finder.cpp 95791 2021-12-23 15:35:42Z stakhovv $
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 * Author: Aaron Ucko, NCBI
27 * Mati Shomrat
28 * Maintainer: Frank Ludwig, Michael Kornbluh
29 *
30 * File Description:
31 * Public API for finding the gene(s) on a given feature using the same
32 * criteria as the flatfile generator.
33 *
34 * ===========================================================================
35 */
36 
37 #include <ncbi_pch.hpp>
41 #include <objmgr/blob_id.hpp>
43 #include <objmgr/seq_map_ci.hpp>
44 
47 
48 using namespace sequence;
49 
51  const CSeq_loc &location,
52  CScope & scope,
53  const CGene_ref* filtering_gene_xref )
54  : m_Loc_original_strand(eNa_strand_other),
55  m_Filtering_gene_xref(filtering_gene_xref),
56  m_Scope(&scope)
57 {
58  ITERATE( CSeq_loc, loc_iter, location ) {
59  const CSeq_id *seq_id = loc_iter.GetRangeAsSeq_loc()->GetId();
60  if( seq_id != NULL ) {
62  if( m_BioseqHandle ) {
63  break;
64  }
65  }
66  }
67 }
68 
70  SAnnotSelector &sel )
71 {
72  sel.SetIgnoreStrand();
73  sel.SetIgnoreFarLocationsForSorting( m_BioseqHandle );
74 }
75 
77  CBioseq_Handle &ignored_bioseq_handle,
78  unique_ptr<CFeat_CI> &feat_ci,
79  TSeqPos circular_length,
81  const CSeq_loc& loc,
82  SAnnotSelector &sel,
83  CScope &scope,
84  ENa_strand &strand )
85 {
86  if ( m_BioseqHandle ) {
87  // if we're circular, we may need to split our range into two pieces
88  if( ( circular_length != kInvalidSeqPos ) &&
89  ( range.GetFrom() > range.GetTo() ))
90  {
91  // For circular locations, the "from" is greater than the "to", which
92  // would not work properly if given to CFeat_CI.
93  // So, as a work around, we transform the range
94  // into a mix location of the form "join(0..to, from..MAXINT)"
95 
96  CRef<CSeq_loc> new_loc( new CSeq_loc );
97  new_loc->SetInt().SetFrom( 0 );
98  new_loc->SetInt().SetTo( range.GetTo() );
99 
100  CRef<CSeq_loc> otherHalfOfRange( new CSeq_loc );
101  otherHalfOfRange->SetInt().SetFrom( range.GetFrom() );
102  otherHalfOfRange->SetInt().SetTo( kMax_Int );
103 
104  new_loc->Add( *otherHalfOfRange );
105 
106  new_loc->SetStrand( loc.GetStrand() );
107  new_loc->SetId( *loc.GetId() );
108 
109  feat_ci.reset( new CFeat_CI(scope, *new_loc, sel) );
110  } else {
111  // remove far parts, if necessary
112  bool loc_change_needed = false;
113  ITERATE( CSeq_loc, loc_iter, loc ) {
114  if( ! m_BioseqHandle.IsSynonym( loc_iter.GetSeq_id() ) ) {
115  loc_change_needed = true;
116  break;
117  }
118  }
119  if( loc_change_needed ) {
120  CRef<CSeq_loc> new_loc( new CSeq_loc );
121  ITERATE( CSeq_loc, loc_iter, loc ) {
122  if( m_BioseqHandle.IsSynonym( loc_iter.GetSeq_id() ) ) {
123  new_loc->Add( *loc_iter.GetRangeAsSeq_loc() );
124  }
125  }
126  feat_ci.reset( new CFeat_CI(scope, *new_loc, sel) );
127  } else {
128  feat_ci.reset( new CFeat_CI(scope, loc, sel) );
129  }
130  }
131  } else {
132  feat_ci.reset( new CFeat_CI(scope, loc, sel) );
133  }
134 }
135 
137  CBioseq_Handle &ignored_bioseq_handle,
138  CRef<CSeq_loc> &loc,
139  TSeqPos circular_length )
140 {
141  m_Loc_original_strand = GeneSearchNormalizeLoc( m_BioseqHandle, loc, circular_length );
142 }
143 
145  bool &shouldContinueToNextIteration,
146  CRef<CSeq_loc> &cleaned_loc_this_iteration,
147  CRef<CSeq_loc> &candidate_feat_loc,
148  sequence::EOverlapType &overlap_type_this_iteration,
149  bool &revert_locations_this_iteration,
150  CBioseq_Handle &ignored_bioseq_handle,
151  const CMappedFeat &feat,
152  TSeqPos circular_length,
153  SAnnotSelector::EOverlapType annot_overlap_type )
154 {
155  // check if given candidate feat matches the filter
156  if( m_Filtering_gene_xref != NULL &&
157  feat.GetOriginalFeature().IsSetData() &&
158  feat.GetOriginalFeature().GetData().IsGene() )
159  {
160  if( ! GeneMatchesXref( &feat.GetOriginalFeature().GetData().GetGene(), &*m_Filtering_gene_xref ) ) {
161  shouldContinueToNextIteration = true;
162  return;
163  }
164  }
165 
166  // determine if the candidate feat location is mixed-strand
167 
168  ENa_strand candidate_feat_original_strand = eNa_strand_other;
169 
170  const bool candidate_feat_is_mixed = IsMixedStrand( m_BioseqHandle, *candidate_feat_loc );
171 
172  const bool candidate_feat_bad_order = BadSeqLocSortOrderCStyle( m_BioseqHandle, *candidate_feat_loc );
173 
174  const TGeneSearchLocOpt norm_opt = ( (overlap_type_this_iteration == eOverlap_Contained) ?
176  0 );
177  candidate_feat_original_strand = GeneSearchNormalizeLoc( m_BioseqHandle, candidate_feat_loc,
178  circular_length, norm_opt ) ;
179 
180  if( (norm_opt & fGeneSearchLocOpt_RemoveFar) != 0 ) {
181  GeneSearchNormalizeLoc( m_BioseqHandle,
182  cleaned_loc_this_iteration, circular_length, norm_opt );
183  }
184 
185  if( ( candidate_feat_bad_order || candidate_feat_is_mixed ) &&
186  annot_overlap_type == SAnnotSelector::eOverlap_TotalRange )
187  {
188  if( overlap_type_this_iteration == eOverlap_Contained ) {
189  overlap_type_this_iteration = eOverlap_SubsetRev;
190  revert_locations_this_iteration = true;
191  }
192  }
193 
194  if( (candidate_feat_bad_order || candidate_feat_is_mixed) &&
195  feat.IsSetExcept_text() && feat.GetExcept_text() == "trans-splicing" )
196  {
197  // strand matching is done piecewise if we're trans-spliced
198  shouldContinueToNextIteration = true;
199 
200  CSeq_loc_CI candidate_feat_loc_iter( feat.GetLocation() );
201  for( ; candidate_feat_loc_iter; ++candidate_feat_loc_iter ) {
202  // any piece that's in cleaned_loc_this_iteration, must have a matching strand
203  sequence::ECompare piece_comparison = sequence::Compare(
204  *candidate_feat_loc_iter.GetRangeAsSeq_loc(),
205  *cleaned_loc_this_iteration,
207  if( piece_comparison != sequence::eNoOverlap )
208  {
209  if( x_StrandsMatch( m_Loc_original_strand, candidate_feat_loc_iter.GetStrand() ) ) {
210  // matching strands; don't skip this feature
211  shouldContinueToNextIteration = false;
212  break;
213  }
214  }
215  }
216 
217  if( x_StrandsMatch( m_Loc_original_strand, candidate_feat_original_strand ) ) {
218  // matching strands; don't skip this feature
219  shouldContinueToNextIteration = false;
220  }
221  } else {
222  if( ! x_StrandsMatch( m_Loc_original_strand, candidate_feat_original_strand ) ) {
223  // mismatched strands; skip this feature
224  shouldContinueToNextIteration = true;
225  }
226  }
227 }
228 
230  Int8 &cur_diff,
231  CRef<CSeq_loc> &cleaned_loc,
232  CRef<CSeq_loc> &candidate_feat_loc,
233  CScope &scope,
234  SAnnotSelector &sel,
235  TSeqPos circular_length )
236 {
237  if( cur_diff < 0 ) {
238  return;
239  }
240 
241  // for, e.g. AL596104
243  cur_diff = sequence::GetLength( *candidate_feat_loc, &scope );
244  } else {
245  const int start = (int)sequence::GetStart(*candidate_feat_loc, &scope, eExtreme_Positional);
246  const int stop = (int)sequence::GetStop(*candidate_feat_loc, &scope, eExtreme_Positional);
247  if( (start > stop) && (circular_length > 0) &&
248  (circular_length != kInvalidSeqPos) )
249  {
250  cur_diff = circular_length - abs( start - stop );
251  } else {
252  cur_diff = abs( start - stop );
253  }
254  }
255 }
256 
258  ENa_strand feat_strand, ENa_strand candidate_feat_original_strand )
259 {
260  return ( candidate_feat_original_strand == feat_strand
261  || ( candidate_feat_original_strand == eNa_strand_both && feat_strand != eNa_strand_minus )
262  || feat_strand == eNa_strand_both
263  || (candidate_feat_original_strand == eNa_strand_unknown && feat_strand != eNa_strand_minus)
264  || (feat_strand == eNa_strand_unknown && candidate_feat_original_strand != eNa_strand_minus) );
265 }
266 
267 // ----------------------------------------------------------------------------
268 // static
270  const CSeq_feat_Handle & in_feat,
272  const CConstRef<CSeq_loc> & feat_loc,
273  CConstRef<CGene_ref> & out_suppression_check_gene_ref,
274  const CGene_ref*& out_g_ref, // out: gene ref
275  CConstRef<CSeq_feat>& out_s_feat, // out: gene seq feat
276  const CSeq_feat_Handle & in_parent_feat )
277  // CConstRef<CFeatureItem> parentFeatureItem )
278 //
279 // Find the feature's related gene information. The association is established
280 // through dbxref if it exists and through best overlap otherwise.
281 //
282 // Note: Any of the two outs may be invalid if the corresponding information
283 // could not be found.
284 // ----------------------------------------------------------------------------
285 {
286  out_s_feat.Reset();
287  out_g_ref = NULL;
288 
289  // guard against suppressed gene xrefs
290  out_suppression_check_gene_ref = GetSuppressionCheckGeneRef(in_feat);
291  if( out_suppression_check_gene_ref &&
292  out_suppression_check_gene_ref->IsSuppressed() )
293  {
294  return;
295  }
296 
297  // Try to resolve the gene directly
298  CConstRef<CSeq_feat> resolved_feat =
300  if( resolved_feat ) {
301  out_s_feat = resolved_feat;
302  out_g_ref = &out_s_feat->GetData().GetGene();
303  return;
304  }
305 
306  // this will point to the gene xref inside the feature, if any
307  const CGene_ref *xref_g_ref = in_feat.GetGeneXref();
308  string xref_label;
309  if( xref_g_ref ) {
310  xref_g_ref->GetLabel(&xref_label);
311  }
312 
313  if( xref_label.empty() ) {
314  xref_g_ref = NULL;
315  }
316 
317  bool also_look_at_parent_CDS = false;
318 
319  // special cases for some subtypes
320  switch( in_feat.GetFeatSubtype() ) {
329  also_look_at_parent_CDS = true;
330  break;
331  default:
332  break;
333  }
334 
335  CConstRef<CGene_ref> pParentDecidingGeneRef = GetSuppressionCheckGeneRef(in_parent_feat);
336 
337  // always use CDS's ref if xref_g_ref directly if it's set (e.g. AB280922)
338  if( also_look_at_parent_CDS &&
339  pParentDecidingGeneRef &&
340  (! pParentDecidingGeneRef->IsSuppressed()) )
341  {
342  out_g_ref = pParentDecidingGeneRef;
343  out_s_feat.ReleaseOrNull();
344  return;
345  }
346 
347  // always use xref_g_ref directly if it's set, but CDS's xref isn't (e.g. NP_041400)
348  if( also_look_at_parent_CDS && NULL != xref_g_ref ) {
349  out_g_ref = xref_g_ref;
350  out_s_feat.ReleaseOrNull();
351  return;
352  }
353 
354  // For primer_bind, we get genes only by xref, not by overlap
356  CSeq_id_Handle id1 = sequence::GetId(ctx.GetHandle(),
359  &ctx.GetScope());
360 
361  if (sequence::IsSameBioseq(id1, id2, &ctx.GetScope())) {
363  ctx, in_feat.GetFeatType(), in_feat.GetFeatSubtype(), in_feat.GetLocation(), CSeqFeatData::e_Gene, xref_g_ref );
364  }
365  else if (ctx.IsProt() && in_feat.GetData().IsCdregion()) {
366  /// genpept report; we need to do something different
367  CMappedFeat cds = GetMappedCDSForProduct(ctx.GetHandle());
368  if (cds) {
370  ctx, cds.GetFeatType(), cds.GetFeatSubtype(), cds.GetLocation(), CSeqFeatData::e_Gene, xref_g_ref );
371  }
372  }
373  else {
375  ctx, in_feat.GetFeatType(), in_feat.GetFeatSubtype(), *feat_loc, CSeqFeatData::e_Gene, xref_g_ref );
376  }
377 
378  // special cases for some subtypes
379  if( also_look_at_parent_CDS ) {
380 
381  // remove gene if bad match
382  bool ownGeneIsOkay = false;
383  if( out_s_feat ) {
384  const CSeq_loc &gene_loc = out_s_feat->GetLocation();
385  if( sequence::Compare(gene_loc, *feat_loc, &ctx.GetScope(), sequence::fCompareOverlapping) == sequence::eSame ) {
386  ownGeneIsOkay = true;
387  }
388  }
389 
390  // Priority order for finding the peptide's gene
391  // 1. Use parent CDS's gene xref (from the .asn)
392  // 2. Use the feature's own gene but only
393  // if it *exactly* overlaps it.
394  // 3. Use the parent CDS's gene (found via overlap)
395  if( pParentDecidingGeneRef ) {
396  // get the parent CDS's gene
397  out_s_feat.Reset();
398  if( ! pParentDecidingGeneRef->IsSuppressed() ) {
399  out_g_ref = pParentDecidingGeneRef;
400  xref_g_ref = NULL; // TODO: is it right to ignore mat_peptide gene xrefs?
401  }
402  } else if( ownGeneIsOkay ) {
403  // do nothing; it's already set
404  } else {
405  if( in_parent_feat ) {
406  CConstRef<CSeq_loc> pParentLocation( &in_parent_feat.GetLocation() );
409  *pParentLocation, CSeqFeatData::e_Gene, xref_g_ref );
410  } else {
412  ctx, in_feat.GetFeatType(), in_feat.GetFeatSubtype(), *feat_loc, CSeqFeatData::e_Cdregion, xref_g_ref );
413  if( cds_feat ) {
416  cds_feat->GetLocation(), CSeqFeatData::e_Gene, xref_g_ref );
417  }
418  }
419  }
420  } // end: if( also_look_at_parent_CDS )
421  }
422 
423  if ( in_feat && NULL == xref_g_ref ) {
424  if (out_s_feat) {
425  out_g_ref = &( out_s_feat->GetData().GetGene() );
426  }
427  }
428  else {
429 
430  // if we used an xref to a gene, but the new gene doesn't equal the xref,
431  // then override it (example accession where this issue crops up:
432  // AF231993.1 )
433 
434  if (out_s_feat) {
435  out_g_ref = &out_s_feat->GetData().GetGene();
436  }
437 
438  // find a gene match using the xref (e.g. match by locus or whatever)
439  if( NULL != xref_g_ref && ! GeneMatchesXref( out_g_ref, xref_g_ref ) )
440  {
441  out_g_ref = NULL;
442  out_s_feat.Reset();
443 
444  CSeq_feat_Handle feat = ResolveGeneXref( xref_g_ref, ctx.GetTopLevelEntry() );
445  if( feat ) {
446  const CGene_ref& other_ref = feat.GetData().GetGene();
447 
448  out_s_feat.Reset( &*feat.GetSeq_feat() );
449  out_g_ref = &other_ref;
450  }
451  }
452 
453  // we found no match for the gene, but we can fall back on the xref
454  // itself (e.g. K03223.1)
455  if( NULL == out_g_ref ) {
456  out_g_ref = xref_g_ref;
457  }
458  }
459 }
460 
461 // static
463  const CGene_ref *xref_g_ref,
464  const CSeq_entry_Handle &top_level_seq_entry )
465 {
466  // Allow locus to match locus-tag or vice versa, but favor proper
467  // locus-to-locus or tag-to-tag matches.
468  enum ERGX_MatchQuality {
469  eRGX_NoMatch,
470  eRGX_MatchedTagForLocus,
471  eRGX_MatchedLocusForTag,
472  eRGX_MatchedAsIs
473  };
474  CSeq_feat_Handle feat;
475 
476  if( xref_g_ref == NULL ) {
477  return feat;
478  }
479 
480  if( top_level_seq_entry ) {
481  CTSE_Handle::TSeq_feat_Handles possible_feats;
482  set<CTSE_Handle> tried;
484  ERGX_MatchQuality match_quality = eRGX_NoMatch;
485  bool found_near_match = false;
486  for (CBioseq_CI bs(top_level_seq_entry);
487  !found_near_match && bs;
488  ++bs) {
489  for (CSeqMap_CI it(*bs, sel); it; ++it) {
490  const CTSE_Handle& tse_handle = it.GetUsingTSE();
491  if (tried.find(tse_handle) != tried.end()) {
492  continue;
493  }
494  tried.insert(tse_handle);
495 
496  ERGX_MatchQuality new_quality = eRGX_NoMatch;
497 
498  CTSE_Handle::TSeq_feat_Handles new_possibilities
499  = tse_handle.GetGenesByRef(*xref_g_ref);
500  if ( !new_possibilities.empty() ) {
501  new_quality = eRGX_MatchedAsIs;
502  }
503  if (new_quality == eRGX_NoMatch
504  && match_quality <= eRGX_MatchedLocusForTag
505  && xref_g_ref->IsSetLocus_tag()) {
506  new_possibilities = tse_handle.GetGenesWithLocus
507  (xref_g_ref->GetLocus_tag(), false);
508  if ( !new_possibilities.empty() ) {
509  new_quality = eRGX_MatchedLocusForTag;
510  }
511  }
512  if (new_quality == eRGX_NoMatch
513  && match_quality <= eRGX_MatchedTagForLocus
514  && xref_g_ref->IsSetLocus()) {
515  new_possibilities = tse_handle.GetGenesWithLocus
516  (xref_g_ref->GetLocus(), true);
517  if ( !new_possibilities.empty() ) {
518  new_quality = eRGX_MatchedTagForLocus;
519  }
520  }
521 
522  if (new_quality > match_quality) {
523  possible_feats = new_possibilities;
524  match_quality = new_quality;
525  } else if (new_quality == match_quality) {
526  possible_feats.insert(possible_feats.end(),
527  new_possibilities.begin(),
528  new_possibilities.end());
529  } else {
530  _ASSERT(new_quality == eRGX_NoMatch);
531  }
532 
533  if (match_quality != eRGX_NoMatch
534  && tse_handle == top_level_seq_entry.GetTSE_Handle()) {
535  found_near_match = true;
536  break;
537  }
538  }
539  }
540 
541  if (match_quality != eRGX_NoMatch) {
542  int best_score = INT_MAX;
543  NON_CONST_ITERATE( CTSE_Handle::TSeq_feat_Handles, feat_iter, possible_feats) {
544  CSeq_feat_Handle a_possible_feat = *feat_iter;
545  const int this_feats_score = sequence::GetLength( a_possible_feat.GetLocation(), &top_level_seq_entry.GetScope() );
546  if( this_feats_score < best_score ) {
547  feat = a_possible_feat;
548  best_score = this_feats_score;
549  }
550  }
551  }
552  }
553 
554  return feat;
555 }
556 
557 
558 // static
561 {
562  CConstRef<CGene_ref> answer;
563  if( ! feat ) {
564  return answer;
565  }
566 
567  if (feat.IsSetXref()) {
568  ITERATE (CSeq_feat::TXref, it, feat.GetXref()) {
569  const CSeqFeatXref& xref = **it;
570  if (xref.IsSetData() && xref.GetData().IsGene() ) {
571  answer.Reset( &xref.GetData().GetGene() ) ;
572  if( xref.GetData().GetGene().IsSuppressed()) {
573  return answer;
574  }
575  }
576  }
577  }
578 
579  return answer;
580 }
581 
582 // static
584 {
585  // disallowed if mixed strand
587  return false;
588  }
589 
590  // disallowed if bad order inside seqloc
591  // if( sequence::BadSeqLocSortOrder( ctx.GetHandle(), location ) ) { // TODO: one day switch to this.
592  // We use BadSeqLocSortOrderCStyle to match C's behavior, even though it's not strictly correct.
593  if( BadSeqLocSortOrderCStyle( ctx.GetHandle(), location ) ) {
594  return false;
595  }
596 
597  if( ctx.IsSegmented() || ctx.IsEMBL() || ctx.IsDDBJ() ) {
598  return true;
599  }
600 
601  if( ctx.CanGetMaster() ) {
602  const bool isSegmented = (ctx.GetMaster().GetNumParts() > 1);
603  if( isSegmented ) {
604  return true;
605  }
606  }
607 
608  // allow for old-style accessions (1 letter + 5 digits)
609  // chop off the decimal point and anything after it, if necessary
610  string::size_type length_before_decimal_point = ctx.GetAccession().find( '.' );
611  if( length_before_decimal_point == string::npos ) {
612  // no decimal point
613  length_before_decimal_point = ctx.GetAccession().length();
614  }
615  if( length_before_decimal_point == 6 ) {
616  return true;
617  }
618 
619  return false;
620 }
621 
622 // static
626  CSeqFeatData::ESubtype feat_subtype,
627  const CSeq_loc &location, CSeqFeatData::E_Choice sought_type,
628  const CGene_ref* filtering_gene_xref )
629 {
630  CRef<CSeq_loc> cleaned_location( new CSeq_loc );
631  cleaned_location->Assign( location );
632 
633  CScope *scope = &ctx.GetScope();
634 
635  // special case for variation
636  if( feat_type == CSeqFeatData::e_Variation ||
637  ( feat_type == CSeqFeatData::e_Imp &&
638  ( feat_subtype == CSeqFeatData::eSubtype_variation ||
639  feat_subtype == CSeqFeatData::eSubtype_variation_ref )))
640  {
641  const ENa_strand first_strand_to_try = (
642  location.GetStrand() == eNa_strand_minus ?
644  eNa_strand_plus );
645 
646  // try one strand first
647  cleaned_location->SetStrand( first_strand_to_try );
649  CGeneSearchPlugin plugin( *cleaned_location, *scope, filtering_gene_xref );
651  ( *cleaned_location,
652  sought_type,
654  *scope,
655  0,
656  &plugin );
657  if( feat ) {
658  return feat;
659  }
660 
661  // if that fails, try the other strand
662  if( first_strand_to_try == eNa_strand_plus ) {
663  cleaned_location->SetStrand( eNa_strand_minus );
664  } else {
665  cleaned_location->SetStrand( eNa_strand_plus );
666  }
667  CGeneSearchPlugin plugin2( *cleaned_location, *scope, filtering_gene_xref );
669  ( *cleaned_location,
670  sought_type,
672  *scope,
673  0,
674  &plugin2 );
675  }
676 
677  // normal case
678  return GetFeatViaSubsetThenExtremesIfPossible_Helper( ctx, scope, *cleaned_location, sought_type, filtering_gene_xref );
679 }
680 
681 SAFE_CONST_STATIC_STRING(kGbLoader, "GBLOADER");
682 
683 // static
686  CBioseqContext& ctx, CScope *scope, const CSeq_loc &location, CSeqFeatData::E_Choice sought_type,
687  const CGene_ref* filtering_gene_xref)
688 {
689  // holds reference to temporary scope if it's used
690  CRef<CScope> temp_scope;
691 
692  bool needToAddGbLoaderBack = false;
693  if( scope && ( ctx.IsEMBL() || ctx.IsDDBJ() ) &&
694  scope->GetObjectManager().FindDataLoader(*kGbLoader) )
695  {
696  // try to remove the GBLOADER temporarily
697  try {
698  scope->RemoveDataLoader(*kGbLoader);
699  needToAddGbLoaderBack = true;
700  } catch(...) {
701  // we couldn't remove the GBLOADER temporarily, so we make a temporary substitute CScope
702  scope = NULL;
703  }
704  }
705 
706  if (scope == NULL) {
707  // TODO: check if this call is fast
708  temp_scope.Reset(new CScope(*CObjectManager::GetInstance()));
709  temp_scope->AddDefaults();
710  temp_scope->RemoveDataLoader(*kGbLoader);
711  scope = temp_scope.GetPointer();
712  }
713 
716  ctx, scope, location, sought_type,
717  filtering_gene_xref );
718  if( ! feat && CanUseExtremesToFindGene(ctx, location) ) {
720  ctx, scope, location, sought_type,
721  filtering_gene_xref );
722  }
723 
724  if( needToAddGbLoaderBack ) {
725  scope->AddDataLoader(*kGbLoader);
726  }
727 
728  return feat;
729 }
730 
731 // static
734  CBioseqContext& ctx, CScope *scope, const CSeq_loc &location, CSeqFeatData::E_Choice sought_type,
735  const CGene_ref* filtering_gene_xref )
736 {
737  CGeneSearchPlugin plugin( location, *scope, filtering_gene_xref );
739  ( location,
740  sought_type,
742  *scope,
743  0,
744  &plugin );
745 }
746 
747 // static
750  CBioseqContext& ctx, CScope *scope, const CSeq_loc &location, CSeqFeatData::E_Choice sought_type,
751  const CGene_ref* filtering_gene_xref )
752 {
753  CGeneSearchPlugin plugin( location, *scope, filtering_gene_xref );
755  ( location,
756  sought_type,
758  *scope,
759  0,
760  &plugin );
761 }
762 
763 // static
766  const CSeq_feat_Handle &feat,
767  int recursion_depth )
768 {
769  const static CConstRef<CSeq_feat> kNullRef;
770 
771  // prevent infinite loop due to circular references
772  if( recursion_depth > 10 ) {
773  return kNullRef;
774  }
775 
776  if (feat.IsSetXref()) {
777  ITERATE (CSeq_feat::TXref, it, feat.GetXref()) {
778  const CSeqFeatXref& xref = **it;
779  if (xref.IsSetData() && xref.GetData().IsGene() ) {
780  if( xref.GetData().GetGene().IsSuppressed()) {
781  return kNullRef;
782  }
783  // TODO: in the future, we should handle non-local references, too
784  if( xref.IsSetId() ) {
785  if( xref.GetId().IsLocal() ) {
786  const CObject_id &obj_id = xref.GetId().GetLocal();
787  SAnnotSelector sel;
788  sel.SetLimitTSE( ctx.GetHandle().GetTSE_Handle() );
789  CFeat_CI feat_ci( ctx.GetHandle().GetTSE_Handle(), sel, obj_id );
790  if( feat_ci ) {
791  const CSeq_feat &feat = feat_ci->GetOriginalFeature();
792  if( feat.IsSetData() && feat.GetData().IsGene() ) {
793  return CConstRef<CSeq_feat>( &feat );
794  } else {
795  // we resolved to a non-gene, so try to resolve to that feature's gene
796  return CGeneFinder::ResolveGeneObjectId( ctx, *feat_ci, recursion_depth+1 );
797  }
798  }
799  }
800  }
801  }
802  }
803  }
804 
805  return kNullRef;
806 }
807 
808 // ----------------------------------------------------------------------------
809 // static
811  const CGene_ref * other_ref,
812  const CGene_ref * xref )
813 {
814  if( NULL == other_ref || NULL == xref ) {
815  return false;
816  }
817 
818  // in case we get a weird xref with nothing useful set
819  if( ! xref->IsSetLocus() && ! xref->IsSetLocus_tag() && ! xref->IsSetSyn() ) {
820  return false;
821  }
822 
823  if( xref->IsSetLocus() ) {
824  if( (! other_ref->IsSetLocus() || other_ref->GetLocus() != xref->GetLocus()) &&
825  (! other_ref->IsSetLocus_tag() || other_ref->GetLocus_tag() != xref->GetLocus()) )
826  {
827  return false;
828  }
829  }
830 
831  if( xref->IsSetLocus_tag() ) {
832  if( ! other_ref->IsSetLocus_tag() || other_ref->GetLocus_tag() != xref->GetLocus_tag() ) {
833  return false;
834  }
835  }
836 
837  if( xref->IsSetSyn() ) {
838  // make sure all syns in the xref are also set in the gene (other_ref)
839  if( ! other_ref->IsSetSyn() ) {
840  return false;
841  }
842 
843  // get set of gene syns so we can quickly check if the gene has the ref'd syns
844  set<string> gene_syns;
845  const CGene_ref::TSyn & gene_syns_list = xref->GetSyn();
846  copy( gene_syns_list.begin(), gene_syns_list.end(),
847  inserter(gene_syns, gene_syns.begin()) );
848 
849  const CGene_ref::TSyn & ref_syns = xref->GetSyn();
850  ITERATE( CGene_ref::TSyn, syn_iter, ref_syns ) {
851  if( gene_syns.find(*syn_iter) == gene_syns.end() ) {
852  return false;
853  }
854  }
855  }
856 
857  return true;
858 }
859 
860 // matches C's behavior, even though it's not strictly correct.
861 // In the future, we may prefer to use sequence::BadSeqLocSortOrder
862 bool CGeneFinder::BadSeqLocSortOrderCStyle( CBioseq_Handle &bioseq_handle, const CSeq_loc &location )
863 {
864  CSeq_loc_CI previous_loc;
865 
866  ITERATE( CSeq_loc, loc_iter, location ) {
867  if( ! previous_loc ) {
868  previous_loc = loc_iter;
869  continue;
870  }
871  if ( previous_loc.GetSeq_id().Equals( loc_iter.GetSeq_id() ) ) {
872  const int prev_to = previous_loc.GetRange().GetTo();
873  const int this_to = loc_iter.GetRange().GetTo();
874  if ( loc_iter.GetStrand() == eNa_strand_minus ) {
875  if ( prev_to < this_to) {
876  return true;
877  }
878  } else {
879  if (prev_to > this_to) {
880  return true;
881  }
882  }
883  }
884  previous_loc = loc_iter;
885  }
886 
887  return false;
888 }
889 
890 // static
892  CBioseq_Handle top_bioseq_handle,
893  CRef<CSeq_loc> &loc, const TSeqPos circular_length,
894  TGeneSearchLocOpt opt )
895 {
896  // remove far parts first, if requested
897  if( top_bioseq_handle && (opt & fGeneSearchLocOpt_RemoveFar) != 0 ) {
898  CRef<CSeq_loc> new_loc( new CSeq_loc );
899  CSeq_loc_mix::Tdata &new_loc_parts = new_loc->SetMix().Set();
900 
901  CSeq_loc_CI loc_iter( *loc, CSeq_loc_CI::eEmpty_Skip, CSeq_loc_CI::eOrder_Biological );
902  for( ; loc_iter; ++loc_iter ) {
903  const CSeq_id& loc_id = loc_iter.GetSeq_id();
904  if( top_bioseq_handle.IsSynonym(loc_id) ) {
905  CRef<CSeq_loc> new_part( new CSeq_loc );
906  new_part->Assign( *loc_iter.GetRangeAsSeq_loc() );
907  new_loc_parts.push_back( new_part );
908  }
909  }
910  loc = new_loc;
911  }
912 
913  CRef<CSeq_loc> new_loc( new CSeq_loc );
914  CSeq_loc_mix::Tdata &new_loc_parts = new_loc->SetMix().Set();
915 
916  ENa_strand original_strand = eNa_strand_other;
917 
918  CSeq_loc_CI loc_iter( *loc, CSeq_loc_CI::eEmpty_Skip, CSeq_loc_CI::eOrder_Positional );
919  for( ; loc_iter; ++loc_iter ) {
920  // parts that are on far bioseqs don't count as part of strandedness (e.g. as in X17229)
921  // ( CR956646 is another good test case since its near parts
922  // are minus strand and far are plus on the "GNAS" gene )
923  if( top_bioseq_handle && (opt & fGeneSearchLocOpt_RemoveFar) == 0 ) {
924  const CSeq_id& loc_id = loc_iter.GetSeq_id();
925  if( top_bioseq_handle.IsSynonym(loc_id) ) {
926  if( original_strand == eNa_strand_other) {
927  // strand should have strandedness of first near part
928  original_strand = loc_iter.GetStrand();
929  }
930  }
931  } else {
932  if( original_strand == eNa_strand_other) {
933  // strand should have strandedness of first near part
934  original_strand = loc_iter.GetStrand();
935  }
936  }
937  // new_loc->Add( * );
938  CRef<CSeq_loc> new_part( new CSeq_loc );
939  new_part->Assign( *loc_iter.GetRangeAsSeq_loc() );
940  new_loc_parts.push_back( new_part );
941  }
942  new_loc->SetStrand( eNa_strand_plus );
943  loc = new_loc;
944 
945  // If location is from multiple seq-id's we can't
946  // really determine the strand. (e.g. AL022339)
947  if( ! top_bioseq_handle ) {
948  original_strand = eNa_strand_unknown;
949  }
950 
951  return original_strand;
952 }
953 
954 // static
956  CBioseq_Handle bioseq_handle, const CSeq_loc &loc )
957 {
958  bool plus_seen = false;
959  bool minus_seen = false;
960 
961  ITERATE( CSeq_loc, loc_iter, loc ) {
962  if( loc_iter.IsEmpty() ) {
963  continue;
964  }
965  // far parts don't count as part of strandedness
966  if( bioseq_handle ) {
967  const CSeq_id& loc_id = loc_iter.GetSeq_id();
968  if( ! bioseq_handle.IsSynonym(loc_id) ) {
969  continue;
970  }
971  }
972  switch( loc_iter.GetStrand() ) {
973  case eNa_strand_unknown:
974  case eNa_strand_plus:
975  plus_seen = true;
976  break;
977  case eNa_strand_minus:
978  minus_seen = true;
979  break;
980  default:
981  break;
982  }
983  }
984 
985  return ( plus_seen && minus_seen );
986 }
987 
990 
static CRef< CScope > m_Scope
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.
CBioseq_CI –.
Definition: bioseq_ci.hpp:69
CBioseq_Handle –.
CFeat_CI –.
Definition: feat_ci.hpp:64
bool x_StrandsMatch(ENa_strand feat_strand, ENa_strand candidate_feat_original_strand)
void processSAnnotSelector(SAnnotSelector &sel)
Definition: gene_finder.cpp:69
CGeneSearchPlugin(const CSeq_loc &location, CScope &scope, const CGene_ref *filtering_gene_xref)
Definition: gene_finder.cpp:50
void setUpFeatureIterator(CBioseq_Handle &ignored_bioseq_handle, unique_ptr< CFeat_CI > &feat_ci, TSeqPos circular_length, CRange< TSeqPos > &range, const CSeq_loc &loc, SAnnotSelector &sel, CScope &scope, ENa_strand &strand)
Definition: gene_finder.cpp:76
void processMainLoop(bool &shouldContinueToNextIteration, CRef< CSeq_loc > &cleaned_loc_this_iteration, CRef< CSeq_loc > &candidate_feat_loc, sequence::EOverlapType &overlap_type_this_iteration, bool &revert_locations_this_iteration, CBioseq_Handle &ignored_bioseq_handle, const CMappedFeat &feat, TSeqPos circular_length, SAnnotSelector::EOverlapType annot_overlap_type)
void postProcessDiffAmount(Int8 &cur_diff, CRef< CSeq_loc > &cleaned_loc, CRef< CSeq_loc > &candidate_feat_loc, CScope &scope, SAnnotSelector &sel, TSeqPos circular_length)
void processLoc(CBioseq_Handle &ignored_bioseq_handle, CRef< CSeq_loc > &loc, TSeqPos circular_length)
static ENa_strand GeneSearchNormalizeLoc(CBioseq_Handle top_bioseq_handle, CRef< CSeq_loc > &loc, const TSeqPos circular_length, TGeneSearchLocOpt opt=0)
static CConstRef< CSeq_feat > GetFeatViaSubsetThenExtremesIfPossible_Helper_subset(CBioseqContext &ctx, CScope *scope, const CSeq_loc &location, CSeqFeatData::E_Choice sought_type, const CGene_ref *filtering_gene_xref)
static CConstRef< CGene_ref > GetSuppressionCheckGeneRef(const CSeq_feat_Handle &feat)
static CSeq_feat_Handle ResolveGeneXref(const CGene_ref *xref_g_ref, const CSeq_entry_Handle &top_level_seq_entry)
This does plain, simple resolution of a CGene_ref to its gene.
static CConstRef< CSeq_feat > ResolveGeneObjectId(CBioseqContext &ctx, const CSeq_feat_Handle &feat, int recursion_depth=0)
static CConstRef< CSeq_feat > GetFeatViaSubsetThenExtremesIfPossible_Helper(CBioseqContext &ctx, CScope *scope, const CSeq_loc &location, CSeqFeatData::E_Choice sought_type, const CGene_ref *filtering_gene_xref)
static bool GeneMatchesXref(const CGene_ref *other_ref, const CGene_ref *xref)
static CConstRef< CSeq_feat > GetFeatViaSubsetThenExtremesIfPossible_Helper_extremes(CBioseqContext &ctx, CScope *scope, const CSeq_loc &location, CSeqFeatData::E_Choice sought_type, const CGene_ref *filtering_gene_xref)
static CConstRef< CSeq_feat > GetFeatViaSubsetThenExtremesIfPossible(CBioseqContext &ctx, CSeqFeatData::E_Choice feat_type, CSeqFeatData::ESubtype feat_subtype, const CSeq_loc &location, CSeqFeatData::E_Choice sought_type, const CGene_ref *filtering_gene_xref)
static void GetAssociatedGeneInfo(const CSeq_feat_Handle &in_feat, CBioseqContext &ctx, const CConstRef< CSeq_loc > &feat_loc, CConstRef< CGene_ref > &out_suppression_check_gene_ref, const CGene_ref *&out_g_ref, CConstRef< CSeq_feat > &out_s_feat, const CSeq_feat_Handle &in_parent_feat)
Find the gene associated with the given feature.
static bool CanUseExtremesToFindGene(CBioseqContext &ctx, const CSeq_loc &location)
int TGeneSearchLocOpt
static bool BadSeqLocSortOrderCStyle(CBioseq_Handle &bioseq_handle, const CSeq_loc &location)
static bool IsMixedStrand(CBioseq_Handle bioseq_handle, const CSeq_loc &loc)
@ fGeneSearchLocOpt_RemoveFar
void GetLabel(string *label) const
Definition: Gene_ref.cpp:57
bool IsSuppressed(void) const
Definition: Gene_ref.cpp:75
CMappedFeat –.
Definition: mapped_feat.hpp:59
CScope –.
Definition: scope.hpp:92
ESubtype GetSubtype(void) const
@ eSubtype_transit_peptide_aa
CSeqFeatXref –.
Definition: SeqFeatXref.hpp:66
Iterator over CSeqMap.
Definition: seq_map_ci.hpp:252
CSeq_entry_Handle –.
CSeq_feat_Handle –.
namespace ncbi::objects::
Definition: Seq_feat.hpp:58
TSeq_feat_Handles GetGenesWithLocus(const string &locus, bool tag) const
Definition: tse_handle.cpp:861
vector< CSeq_feat_Handle > TSeq_feat_Handles
Definition: tse_handle.hpp:167
TSeq_feat_Handles GetGenesByRef(const CGene_ref &ref) const
Definition: tse_handle.cpp:901
Definition: set.hpp:45
iterator_bool insert(const value_type &val)
Definition: set.hpp:149
const_iterator begin() const
Definition: set.hpp:135
const_iterator find(const key_type &key) const
Definition: set.hpp:137
const_iterator end() const
Definition: set.hpp:136
static const char location[]
Definition: config.c:97
CS_CONTEXT * ctx
Definition: t0006.c:12
SAFE_CONST_STATIC_STRING(kGbLoader, "GBLOADER")
Public API for finding the gene(s) on a given feature using the same criteria as the flatfile generat...
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
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
Definition: ncbimisc.hpp:822
const TSeqPos kInvalidSeqPos
Define special value for invalid sequence position.
Definition: ncbimisc.hpp:878
#define NULL
Definition: ncbistd.hpp:225
void SetMix(TMix &v)
Definition: Seq_loc.hpp:987
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
void SetInt(TInt &v)
Definition: Seq_loc.hpp:983
void Add(const CSeq_loc &other)
Simple adding of seq-locs.
Definition: Seq_loc.cpp:3875
void SetStrand(ENa_strand strand)
Set the strand for all of the location's ranges.
Definition: Seq_loc.cpp:5196
@ eOrder_Biological
Iterate sub-locations in positional order.
Definition: Seq_loc.hpp:462
@ eOrder_Positional
Definition: Seq_loc.hpp:461
CMappedFeat GetBestOverlappingFeat(const CMappedFeat &feat, CSeqFeatData::ESubtype need_subtype, sequence::EOverlapType overlap_type, CFeatTree *feat_tree=0, const SAnnotSelector *base_sel=0)
Definition: feature.cpp:3653
TSeqPos GetStop(const CSeq_loc &loc, CScope *scope, ESeqLocExtremes ext=eExtreme_Positional)
If only one CBioseq is represented by CSeq_loc, returns the position at the stop of the location.
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.
EOverlapType
TSeqPos GetStart(const CSeq_loc &loc, CScope *scope, ESeqLocExtremes ext=eExtreme_Positional)
If only one CBioseq is represented by CSeq_loc, returns the position at the start of the location.
sequence::ECompare Compare(const CSeq_loc &loc1, const CSeq_loc &loc2, CScope *scope)
Returns the sequence::ECompare containment relationship between CSeq_locs.
CSeq_id_Handle GetIdHandle(const CSeq_loc &loc, CScope *scope)
ECompare
bool IsSameBioseq(const CSeq_id &id1, const CSeq_id &id2, CScope *scope, CScope::EGetBioseqFlag get_flag=CScope::eGetBioseq_All)
Determines if two CSeq_ids represent the same CBioseq.
@ fCompareOverlapping
Check if seq-locs are overlapping.
@ eOverlap_SubsetRev
1st is a subset of 2nd ranges
@ eOverlap_Contained
2nd contained within 1st extremes
@ eSame
CSeq_locs contain each other.
@ eNoOverlap
CSeq_locs do not overlap or abut.
CMappedFeat GetMappedCDSForProduct(const CBioseq_Handle &product)
Definition: sequence.cpp:2568
@ eGetId_Canonical
Definition: sequence.hpp:114
void AddDataLoader(const string &loader_name, TPriority pri=kPriority_Default)
Add data loader by name.
Definition: scope.cpp:510
static CRef< CObjectManager > GetInstance(void)
Return the existing object manager or create one.
CBioseq_Handle GetBioseqHandle(const CSeq_id &id)
Get bioseq handle by seq-id.
Definition: scope.cpp:95
void AddDefaults(TPriority pri=kPriority_Default)
Add default data loaders from object manager.
Definition: scope.cpp:504
CDataLoader * FindDataLoader(const string &loader_name) const
Try to find a registered data loader by name.
CObjectManager & GetObjectManager(void)
Get object manager controlling this scope.
Definition: scope.cpp:89
void RemoveDataLoader(const string &loader_name, EActionIfLocked action=eThrowIfLocked)
Revoke data loader from the scope.
Definition: scope.cpp:369
const CSeq_feat::TXref & GetXref(void) const
virtual CConstRef< CSeq_feat > GetSeq_feat(void) const
const CSeqFeatData & GetData(void) const
bool IsSetXref(void) const
const CTSE_Handle & GetTSE_Handle(void) const
bool IsSetExcept_text(void) const
virtual const CSeq_loc & GetLocation(void) const
const string & GetExcept_text(void) const
CScope & GetScope(void) const
Get scope this handle belongs to.
CSeqFeatData::ESubtype GetFeatSubtype(void) const
CSeqFeatData::E_Choice GetFeatType(void) const
const CGene_ref * GetGeneXref(void) const
get gene (if present) from Seq-feat.xref list
bool IsSynonym(const CSeq_id &id) const
Check if this id can be used to obtain this bioseq handle.
const CSeq_loc & GetLocation(void) const
const CSeq_feat & GetOriginalFeature(void) const
Get original feature with unmapped location/product.
SAnnotSelector & SetIgnoreFarLocationsForSorting(const CBioseq_Handle &handle)
Set handle used for determining what locations are "near".
EOverlapType GetOverlapType(void) const
Get the selected overlap type.
EOverlapType
Flag to indicate location overlapping method.
SAnnotSelector & SetLimitTSE(const CTSE_Handle &limit)
Limit annotations to those from the TSE only.
SAnnotSelector & SetIgnoreStrand(bool value=true)
Ignore strand when testing for range overlap.
@ eOverlap_Intervals
default - overlapping of individual intervals
@ eOverlap_TotalRange
overlapping of total ranges only
@ fFindAny
Definition: seq_map.hpp:138
TObjectType * ReleaseOrNull(void)
Release a reference to the object and return a pointer to the object.
Definition: ncbiobj.hpp:1482
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
static const SAutoMax kMax_Auto
Generic stand-in for type-specific kMax_* constants from ncbi_limits.h, useful in any context with ex...
#define kMax_Int
Definition: ncbi_limits.h:184
int64_t Int8
8-byte (64-bit) signed integer
Definition: ncbitype.h:104
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define END_SCOPE(ns)
End the previously defined scope.
Definition: ncbistl.hpp:75
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
#define BEGIN_SCOPE(ns)
Define a new scope.
Definition: ncbistl.hpp:72
bool IsSetSyn(void) const
synonyms for locus Check if a value has been assigned to Syn data member.
Definition: Gene_ref_.hpp:756
const TSyn & GetSyn(void) const
Get the Syn member data.
Definition: Gene_ref_.hpp:768
bool IsSetLocus_tag(void) const
systematic gene name (e.g., MI0001, ORF0069) Check if a value has been assigned to Locus_tag data mem...
Definition: Gene_ref_.hpp:781
bool IsSetLocus(void) const
Official gene symbol Check if a value has been assigned to Locus data member.
Definition: Gene_ref_.hpp:493
const TLocus_tag & GetLocus_tag(void) const
Get the Locus_tag member data.
Definition: Gene_ref_.hpp:793
list< string > TSyn
Definition: Gene_ref_.hpp:102
const TLocus & GetLocus(void) const
Get the Locus member data.
Definition: Gene_ref_.hpp:505
const TData & GetData(void) const
Get the Data member data.
bool IsSetData(void) const
the specific data Check if a value has been assigned to Data data member.
Definition: Seq_feat_.hpp:913
bool IsCdregion(void) const
Check if variant Cdregion is selected.
const TLocal & GetLocal(void) const
Get the variant data.
Definition: Feat_id_.cpp:134
const TLocation & GetLocation(void) const
Get the Location member data.
Definition: Seq_feat_.hpp:1117
E_Choice
Choice variants.
bool IsLocal(void) const
Check if variant Local is selected.
Definition: Feat_id_.hpp:353
const TId & GetId(void) const
Get the Id member data.
bool IsGene(void) const
Check if variant Gene is selected.
const TData & GetData(void) const
Get the Data member data.
Definition: Seq_feat_.hpp:925
bool IsSetData(void) const
the specific data Check if a value has been assigned to Data data member.
const TGene & GetGene(void) const
Get the variant data.
bool IsSetId(void) const
the feature copied Check if a value has been assigned to Id data member.
vector< CRef< CSeqFeatXref > > TXref
Definition: Seq_feat_.hpp:122
ENa_strand
strand of nucleic acid
Definition: Na_strand_.hpp:64
list< CRef< CSeq_loc > > Tdata
@ 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_unknown
Definition: Na_strand_.hpp:65
@ eNa_strand_both
in forward orientation
Definition: Na_strand_.hpp:68
unsigned int
A callback function used to compare two keys in a database.
Definition: types.hpp:1210
range(_Ty, _Ty) -> range< _Ty >
#define abs(a)
Definition: ncbi_heapmgr.c:130
void copy(Njn::Matrix< S > *matrix_, const Njn::Matrix< T > &matrix0_)
Definition: njn_matrix.hpp:613
The Object manager core.
SAnnotSelector –.
Selector used in CSeqMap methods returning iterators.
Definition: seq_map_ci.hpp:113
#define _ASSERT
Modified on Mon Sep 25 00:50:17 2023 by modify_doxy.py rev. 669887