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 101721 2024-01-31 15:37:52Z 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) {
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 &&
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 = nullptr;
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 = nullptr;
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 && 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 = nullptr; // 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 && ! 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 (xref_g_ref && ! GeneMatchesXref(out_g_ref, xref_g_ref)) {
440  out_g_ref = nullptr;
441  out_s_feat.Reset();
442 
443  CSeq_feat_Handle feat = ResolveGeneXref( xref_g_ref, ctx.GetTopLevelEntry() );
444  if( feat ) {
445  const CGene_ref& other_ref = feat.GetData().GetGene();
446 
447  out_s_feat.Reset( &*feat.GetSeq_feat() );
448  out_g_ref = &other_ref;
449  }
450  }
451 
452  // we found no match for the gene, but we can fall back on the xref
453  // itself (e.g. K03223.1)
454  if (! out_g_ref) {
455  out_g_ref = xref_g_ref;
456  }
457  }
458 }
459 
460 // static
462  const CGene_ref *xref_g_ref,
463  const CSeq_entry_Handle &top_level_seq_entry )
464 {
465  // Allow locus to match locus-tag or vice versa, but favor proper
466  // locus-to-locus or tag-to-tag matches.
467  enum ERGX_MatchQuality {
468  eRGX_NoMatch,
469  eRGX_MatchedTagForLocus,
470  eRGX_MatchedLocusForTag,
471  eRGX_MatchedAsIs
472  };
473  CSeq_feat_Handle feat;
474 
475  if (! xref_g_ref) {
476  return feat;
477  }
478 
479  if( top_level_seq_entry ) {
480  CTSE_Handle::TSeq_feat_Handles possible_feats;
481  set<CTSE_Handle> tried;
483  ERGX_MatchQuality match_quality = eRGX_NoMatch;
484  bool found_near_match = false;
485  for (CBioseq_CI bs(top_level_seq_entry);
486  !found_near_match && bs;
487  ++bs) {
488  for (CSeqMap_CI it(*bs, sel); it; ++it) {
489  const CTSE_Handle& tse_handle = it.GetUsingTSE();
490  if (tried.find(tse_handle) != tried.end()) {
491  continue;
492  }
493  tried.insert(tse_handle);
494 
495  ERGX_MatchQuality new_quality = eRGX_NoMatch;
496 
497  CTSE_Handle::TSeq_feat_Handles new_possibilities
498  = tse_handle.GetGenesByRef(*xref_g_ref);
499  if ( !new_possibilities.empty() ) {
500  new_quality = eRGX_MatchedAsIs;
501  }
502  if (new_quality == eRGX_NoMatch
503  && match_quality <= eRGX_MatchedLocusForTag
504  && xref_g_ref->IsSetLocus_tag()) {
505  new_possibilities = tse_handle.GetGenesWithLocus
506  (xref_g_ref->GetLocus_tag(), false);
507  if ( !new_possibilities.empty() ) {
508  new_quality = eRGX_MatchedLocusForTag;
509  }
510  }
511  if (new_quality == eRGX_NoMatch
512  && match_quality <= eRGX_MatchedTagForLocus
513  && xref_g_ref->IsSetLocus()) {
514  new_possibilities = tse_handle.GetGenesWithLocus
515  (xref_g_ref->GetLocus(), true);
516  if ( !new_possibilities.empty() ) {
517  new_quality = eRGX_MatchedTagForLocus;
518  }
519  }
520 
521  if (new_quality > match_quality) {
522  possible_feats = new_possibilities;
523  match_quality = new_quality;
524  } else if (new_quality == match_quality) {
525  possible_feats.insert(possible_feats.end(),
526  new_possibilities.begin(),
527  new_possibilities.end());
528  } else {
529  _ASSERT(new_quality == eRGX_NoMatch);
530  }
531 
532  if (match_quality != eRGX_NoMatch
533  && tse_handle == top_level_seq_entry.GetTSE_Handle()) {
534  found_near_match = true;
535  break;
536  }
537  }
538  }
539 
540  if (match_quality != eRGX_NoMatch) {
541  int best_score = INT_MAX;
542  NON_CONST_ITERATE( CTSE_Handle::TSeq_feat_Handles, feat_iter, possible_feats) {
543  CSeq_feat_Handle a_possible_feat = *feat_iter;
544  const int this_feats_score = sequence::GetLength( a_possible_feat.GetLocation(), &top_level_seq_entry.GetScope() );
545  if( this_feats_score < best_score ) {
546  feat = a_possible_feat;
547  best_score = this_feats_score;
548  }
549  }
550  }
551  }
552 
553  return feat;
554 }
555 
556 
557 // static
560 {
561  CConstRef<CGene_ref> answer;
562  if( ! feat ) {
563  return answer;
564  }
565 
566  if (feat.IsSetXref()) {
567  ITERATE (CSeq_feat::TXref, it, feat.GetXref()) {
568  const CSeqFeatXref& xref = **it;
569  if (xref.IsSetData() && xref.GetData().IsGene() ) {
570  answer.Reset( &xref.GetData().GetGene() ) ;
571  if( xref.GetData().GetGene().IsSuppressed()) {
572  return answer;
573  }
574  }
575  }
576  }
577 
578  return answer;
579 }
580 
581 // static
583 {
584  // disallowed if mixed strand
586  return false;
587  }
588 
589  // disallowed if bad order inside seqloc
590  // if( sequence::BadSeqLocSortOrder( ctx.GetHandle(), location ) ) { // TODO: one day switch to this.
591  // We use BadSeqLocSortOrderCStyle to match C's behavior, even though it's not strictly correct.
592  if( BadSeqLocSortOrderCStyle( ctx.GetHandle(), location ) ) {
593  return false;
594  }
595 
596  if( ctx.IsSegmented() || ctx.IsEMBL() || ctx.IsDDBJ() ) {
597  return true;
598  }
599 
600  if( ctx.CanGetMaster() ) {
601  const bool isSegmented = (ctx.GetMaster().GetNumParts() > 1);
602  if( isSegmented ) {
603  return true;
604  }
605  }
606 
607  // allow for old-style accessions (1 letter + 5 digits)
608  // chop off the decimal point and anything after it, if necessary
609  string::size_type length_before_decimal_point = ctx.GetAccession().find( '.' );
610  if( length_before_decimal_point == string::npos ) {
611  // no decimal point
612  length_before_decimal_point = ctx.GetAccession().length();
613  }
614  if( length_before_decimal_point == 6 ) {
615  return true;
616  }
617 
618  return false;
619 }
620 
621 // static
625  CSeqFeatData::ESubtype feat_subtype,
626  const CSeq_loc &location, CSeqFeatData::E_Choice sought_type,
627  const CGene_ref* filtering_gene_xref )
628 {
629  CRef<CSeq_loc> cleaned_location( new CSeq_loc );
630  cleaned_location->Assign( location );
631 
632  CScope *scope = &ctx.GetScope();
633 
634  // special case for variation
635  if( feat_type == CSeqFeatData::e_Variation ||
636  ( feat_type == CSeqFeatData::e_Imp &&
637  ( feat_subtype == CSeqFeatData::eSubtype_variation ||
638  feat_subtype == CSeqFeatData::eSubtype_variation_ref )))
639  {
640  const ENa_strand first_strand_to_try = (
641  location.GetStrand() == eNa_strand_minus ?
643  eNa_strand_plus );
644 
645  // try one strand first
646  cleaned_location->SetStrand( first_strand_to_try );
648  CGeneSearchPlugin plugin( *cleaned_location, *scope, filtering_gene_xref );
650  ( *cleaned_location,
651  sought_type,
653  *scope,
654  0,
655  &plugin );
656  if( feat ) {
657  return feat;
658  }
659 
660  // if that fails, try the other strand
661  if( first_strand_to_try == eNa_strand_plus ) {
662  cleaned_location->SetStrand( eNa_strand_minus );
663  } else {
664  cleaned_location->SetStrand( eNa_strand_plus );
665  }
666  CGeneSearchPlugin plugin2( *cleaned_location, *scope, filtering_gene_xref );
668  ( *cleaned_location,
669  sought_type,
671  *scope,
672  0,
673  &plugin2 );
674  }
675 
676  // normal case
677  return GetFeatViaSubsetThenExtremesIfPossible_Helper( ctx, scope, *cleaned_location, sought_type, filtering_gene_xref );
678 }
679 
680 SAFE_CONST_STATIC_STRING(kGbLoader, "GBLOADER");
681 
682 // static
685  CBioseqContext& ctx, CScope *scope, const CSeq_loc &location, CSeqFeatData::E_Choice sought_type,
686  const CGene_ref* filtering_gene_xref)
687 {
688  // holds reference to temporary scope if it's used
689  CRef<CScope> temp_scope;
690 
691  bool needToAddGbLoaderBack = false;
692  if( scope && ( ctx.IsEMBL() || ctx.IsDDBJ() ) &&
693  scope->GetObjectManager().FindDataLoader(*kGbLoader) )
694  {
695  // try to remove the GBLOADER temporarily
696  try {
697  scope->RemoveDataLoader(*kGbLoader);
698  needToAddGbLoaderBack = true;
699  } catch(...) {
700  // we couldn't remove the GBLOADER temporarily, so we make a temporary substitute CScope
701  scope = nullptr;
702  }
703  }
704 
705  if (! scope) {
706  // TODO: check if this call is fast
707  temp_scope.Reset(new CScope(*CObjectManager::GetInstance()));
708  temp_scope->AddDefaults();
709  temp_scope->RemoveDataLoader(*kGbLoader);
710  scope = temp_scope.GetPointer();
711  }
712 
715  ctx, scope, location, sought_type,
716  filtering_gene_xref );
717  if( ! feat && CanUseExtremesToFindGene(ctx, location) ) {
719  ctx, scope, location, sought_type,
720  filtering_gene_xref );
721  }
722 
723  if( needToAddGbLoaderBack ) {
724  scope->AddDataLoader(*kGbLoader);
725  }
726 
727  return feat;
728 }
729 
730 // static
733  CBioseqContext& ctx, CScope *scope, const CSeq_loc &location, CSeqFeatData::E_Choice sought_type,
734  const CGene_ref* filtering_gene_xref )
735 {
736  CGeneSearchPlugin plugin( location, *scope, filtering_gene_xref );
738  ( location,
739  sought_type,
741  *scope,
742  0,
743  &plugin );
744 }
745 
746 // static
749  CBioseqContext& ctx, CScope *scope, const CSeq_loc &location, CSeqFeatData::E_Choice sought_type,
750  const CGene_ref* filtering_gene_xref )
751 {
752  CGeneSearchPlugin plugin( location, *scope, filtering_gene_xref );
754  ( location,
755  sought_type,
757  *scope,
758  0,
759  &plugin );
760 }
761 
762 // static
765  const CSeq_feat_Handle &feat,
766  int recursion_depth )
767 {
768  const static CConstRef<CSeq_feat> kNullRef;
769 
770  // prevent infinite loop due to circular references
771  if( recursion_depth > 10 ) {
772  return kNullRef;
773  }
774 
775  if (feat.IsSetXref()) {
776  ITERATE (CSeq_feat::TXref, it, feat.GetXref()) {
777  const CSeqFeatXref& xref = **it;
778  if (xref.IsSetData() && xref.GetData().IsGene() ) {
779  if( xref.GetData().GetGene().IsSuppressed()) {
780  return kNullRef;
781  }
782  // TODO: in the future, we should handle non-local references, too
783  if( xref.IsSetId() ) {
784  if( xref.GetId().IsLocal() ) {
785  const CObject_id &obj_id = xref.GetId().GetLocal();
786  SAnnotSelector sel;
787  sel.SetLimitTSE( ctx.GetHandle().GetTSE_Handle() );
788  CFeat_CI feat_ci( ctx.GetHandle().GetTSE_Handle(), sel, obj_id );
789  if( feat_ci ) {
790  const CSeq_feat &feat = feat_ci->GetOriginalFeature();
791  if( feat.IsSetData() && feat.GetData().IsGene() ) {
792  return CConstRef<CSeq_feat>( &feat );
793  } else {
794  // we resolved to a non-gene, so try to resolve to that feature's gene
795  return CGeneFinder::ResolveGeneObjectId( ctx, *feat_ci, recursion_depth+1 );
796  }
797  }
798  }
799  }
800  }
801  }
802  }
803 
804  return kNullRef;
805 }
806 
807 // ----------------------------------------------------------------------------
808 // static
810  const CGene_ref * other_ref,
811  const CGene_ref * xref )
812 {
813  if (! other_ref || ! xref) {
814  return false;
815  }
816 
817  // in case we get a weird xref with nothing useful set
818  if( ! xref->IsSetLocus() && ! xref->IsSetLocus_tag() && ! xref->IsSetSyn() ) {
819  return false;
820  }
821 
822  if( xref->IsSetLocus() ) {
823  if( (! other_ref->IsSetLocus() || other_ref->GetLocus() != xref->GetLocus()) &&
824  (! other_ref->IsSetLocus_tag() || other_ref->GetLocus_tag() != xref->GetLocus()) )
825  {
826  return false;
827  }
828  }
829 
830  if( xref->IsSetLocus_tag() ) {
831  if( ! other_ref->IsSetLocus_tag() || other_ref->GetLocus_tag() != xref->GetLocus_tag() ) {
832  return false;
833  }
834  }
835 
836  if( xref->IsSetSyn() ) {
837  // make sure all syns in the xref are also set in the gene (other_ref)
838  if( ! other_ref->IsSetSyn() ) {
839  return false;
840  }
841 
842  // get set of gene syns so we can quickly check if the gene has the ref'd syns
843  set<string> gene_syns;
844  const CGene_ref::TSyn & gene_syns_list = xref->GetSyn();
845  copy( gene_syns_list.begin(), gene_syns_list.end(),
846  inserter(gene_syns, gene_syns.begin()) );
847 
848  const CGene_ref::TSyn & ref_syns = xref->GetSyn();
849  ITERATE( CGene_ref::TSyn, syn_iter, ref_syns ) {
850  if( gene_syns.find(*syn_iter) == gene_syns.end() ) {
851  return false;
852  }
853  }
854  }
855 
856  return true;
857 }
858 
859 // matches C's behavior, even though it's not strictly correct.
860 // In the future, we may prefer to use sequence::BadSeqLocSortOrder
861 bool CGeneFinder::BadSeqLocSortOrderCStyle( CBioseq_Handle &bioseq_handle, const CSeq_loc &location )
862 {
863  CSeq_loc_CI previous_loc;
864 
865  ITERATE( CSeq_loc, loc_iter, location ) {
866  if( ! previous_loc ) {
867  previous_loc = loc_iter;
868  continue;
869  }
870  if ( previous_loc.GetSeq_id().Equals( loc_iter.GetSeq_id() ) ) {
871  const int prev_to = previous_loc.GetRange().GetTo();
872  const int this_to = loc_iter.GetRange().GetTo();
873  if ( loc_iter.GetStrand() == eNa_strand_minus ) {
874  if ( prev_to < this_to) {
875  return true;
876  }
877  } else {
878  if (prev_to > this_to) {
879  return true;
880  }
881  }
882  }
883  previous_loc = loc_iter;
884  }
885 
886  return false;
887 }
888 
889 // static
891  CBioseq_Handle top_bioseq_handle,
892  CRef<CSeq_loc> &loc, const TSeqPos circular_length,
893  TGeneSearchLocOpt opt )
894 {
895  // remove far parts first, if requested
896  if( top_bioseq_handle && (opt & fGeneSearchLocOpt_RemoveFar) != 0 ) {
897  CRef<CSeq_loc> new_loc( new CSeq_loc );
898  CSeq_loc_mix::Tdata &new_loc_parts = new_loc->SetMix().Set();
899 
900  CSeq_loc_CI loc_iter( *loc, CSeq_loc_CI::eEmpty_Skip, CSeq_loc_CI::eOrder_Biological );
901  for( ; loc_iter; ++loc_iter ) {
902  const CSeq_id& loc_id = loc_iter.GetSeq_id();
903  if( top_bioseq_handle.IsSynonym(loc_id) ) {
904  CRef<CSeq_loc> new_part( new CSeq_loc );
905  new_part->Assign( *loc_iter.GetRangeAsSeq_loc() );
906  new_loc_parts.push_back( new_part );
907  }
908  }
909  loc = new_loc;
910  }
911 
912  CRef<CSeq_loc> new_loc( new CSeq_loc );
913  CSeq_loc_mix::Tdata &new_loc_parts = new_loc->SetMix().Set();
914 
915  ENa_strand original_strand = eNa_strand_other;
916 
917  CSeq_loc_CI loc_iter( *loc, CSeq_loc_CI::eEmpty_Skip, CSeq_loc_CI::eOrder_Positional );
918  for( ; loc_iter; ++loc_iter ) {
919  // parts that are on far bioseqs don't count as part of strandedness (e.g. as in X17229)
920  // ( CR956646 is another good test case since its near parts
921  // are minus strand and far are plus on the "GNAS" gene )
922  if( top_bioseq_handle && (opt & fGeneSearchLocOpt_RemoveFar) == 0 ) {
923  const CSeq_id& loc_id = loc_iter.GetSeq_id();
924  if( top_bioseq_handle.IsSynonym(loc_id) ) {
925  if( original_strand == eNa_strand_other) {
926  // strand should have strandedness of first near part
927  original_strand = loc_iter.GetStrand();
928  }
929  }
930  } else {
931  if( original_strand == eNa_strand_other) {
932  // strand should have strandedness of first near part
933  original_strand = loc_iter.GetStrand();
934  }
935  }
936  // new_loc->Add( * );
937  CRef<CSeq_loc> new_part( new CSeq_loc );
938  new_part->Assign( *loc_iter.GetRangeAsSeq_loc() );
939  new_loc_parts.push_back( new_part );
940  }
941  new_loc->SetStrand( eNa_strand_plus );
942  loc = new_loc;
943 
944  // If location is from multiple seq-id's we can't
945  // really determine the strand. (e.g. AL022339)
946  if( ! top_bioseq_handle ) {
947  original_strand = eNa_strand_unknown;
948  }
949 
950  return original_strand;
951 }
952 
953 // static
955  CBioseq_Handle bioseq_handle, const CSeq_loc &loc )
956 {
957  bool plus_seen = false;
958  bool minus_seen = false;
959 
960  ITERATE( CSeq_loc, loc_iter, loc ) {
961  if( loc_iter.IsEmpty() ) {
962  continue;
963  }
964  // far parts don't count as part of strandedness
965  if( bioseq_handle ) {
966  const CSeq_id& loc_id = loc_iter.GetSeq_id();
967  if( ! bioseq_handle.IsSynonym(loc_id) ) {
968  continue;
969  }
970  }
971  switch( loc_iter.GetStrand() ) {
972  case eNa_strand_unknown:
973  case eNa_strand_plus:
974  plus_seen = true;
975  break;
976  case eNa_strand_minus:
977  minus_seen = true;
978  break;
979  default:
980  break;
981  }
982  }
983 
984  return ( plus_seen && minus_seen );
985 }
986 
989 
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
CS_CONTEXT * ctx
Definition: t0006.c:12
static const char location[]
Definition: config.c:97
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
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 Tue Apr 23 07:38:32 2024 by modify_doxy.py rev. 669887