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

Go to the SVN repository for this file.

1 /* $Id: na_utils.cpp 47296 2022-12-30 03:01:50Z evgeniev $
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: Liangshou Wu, Dmitry Rudnev
27 *
28 * File Description:
29 * Name annotation utility class
30 */
31 
32 #include <ncbi_pch.hpp>
34 #include <gui/objutils/utils.hpp>
35 
36 #include <objmgr/scope.hpp>
38 #include <objmgr/align_ci.hpp>
39 #include <objmgr/annot_ci.hpp>
40 #include <objmgr/util/sequence.hpp>
46 
47 // needed for NAA meta data processing
50 
51 
54 
55 static const int kRetMax = 5000;
56 static const char* kSnpSubtypeStr = "variation_snp";
57 
58 DEFINE_CLASS_STATIC_FAST_MUTEX(CNAUtils::sm_NAAtoUidCacheMutex);
60 
61 DEFINE_CLASS_STATIC_FAST_MUTEX(CNAUtils::sm_UidtoMetaDataCacheMutex);
63 
64 DEFINE_CLASS_STATIC_FAST_MUTEX(CNAUtils::sm_UidtoGiCacheMutex);
66 
67 
68 enum EAlignType {
69  fAlign_DNA = 0x01,
71  fAlign_Mixed = 0x04,
72  fAlign_Invalid = 0x80000000
73 };
74 
75 
76 
78  CScope& scope)
79 {
80  string aln_type = kEmptyStr;
81  int num_row = 0;
82  try {
83  num_row = align.CheckNumRows();
84  }
85  catch (const CException&) {
86  }
87 
88  if (num_row < 2) return aln_type;
89 
90  // check align type
92  for (int row = 0; row < num_row; ++row) {
93  EAlignType this_type = fAlign_Mixed;
94  CBioseq_Handle handle = scope.GetBioseqHandle(align.GetSeq_id(row));
95  if ( !handle ) continue;
96 
97  switch (handle.GetBioseqCore()->GetInst().GetMol())
98  {
100  case CSeq_inst::eMol_rna:
101  case CSeq_inst::eMol_na:
102  this_type = fAlign_DNA;
103  break;
104 
105  case CSeq_inst::eMol_aa:
106  this_type = fAlign_Protein;
107  break;
108 
109  default:
110  break;
111  }
112 
113  if (this_type == fAlign_Mixed) {
114  type = this_type;
115  break;
116  }
117 
118  if (row == 0) {
119  type = this_type;
120  } else if (this_type != type) {
121  type = fAlign_Mixed;
122  break;
123  }
124  }
125  switch (type) {
126  case fAlign_Protein:
127  aln_type = "protein";
128  break;
129  case fAlign_Mixed:
130  aln_type = "protein-to-nucleotide";
131  break;
132  case fAlign_DNA:
133  default:
134  aln_type = "nucleotide";
135  break;
136  }
137  return aln_type;
138 }
139 
140 
141 inline
142 static string s_GetFeatSubtypeStr(int subtype)
143 {
144  const CFeatList& feats(*CSeqFeatData::GetFeatList());
145  if (subtype == (int)CSeqFeatData::eSubtype_variation) {
146  return kSnpSubtypeStr;
147  }
148  return feats.GetStoragekey(subtype);
149 }
150 
151 
153  set<string>& subtypes)
154 {
155  if ( !annot.GetData().IsFtable() ) return;
156 
157  subtypes.clear();
158  ITERATE (CSeq_annot::TData::TFtable, feat_it, annot.GetData().GetFtable()) {
159  int f_subtype = (*feat_it)->GetData().GetSubtype();
160  subtypes.insert(s_GetFeatSubtypeStr(f_subtype));
161  }
162 }
163 
164 
166  const CSeq_annot& annot)
167 {
168  if ( !annot.IsSeq_table() ) return;
169 
170  const CSeq_table::TColumns& cols =
171  annot.GetData().GetSeq_table().GetColumns();
172  const CEnumeratedTypeValues* type_val =
173  CSeqTable_column_info::GetTypeInfo_enum_EField_id();
174 
175  ITERATE(CSeq_table::TColumns, iter, cols) {
176  const CSeqTable_column::THeader& header = (*iter)->GetHeader();
177  if (header.CanGetField_name()) {
178  headers.insert(header.GetField_name());
179  } else if (header.CanGetField_id() && type_val) {
180  headers.insert(type_val->FindName(header.GetField_id(), true));
181  }
182  }
183 }
184 
185 
186 // This function used in filtering out gene model features from all
187 // the other feature type. If you modify it, modify gene model also
188 // at src/gui/widgets/seq_graphic/gene_model_track.cpp
189 // CGeneModelTrack::x_AdjustSelector
191 {
192  return (subtype == CSeqFeatData::eSubtype_exon ||
193  subtype == CSeqFeatData::eSubtype_misc_RNA ||
194  subtype == CSeqFeatData::eSubtype_C_region ||
198 // Temporary moved back out of gene model track, see SV-2107
199 // subtype == CSeqFeatData::eSubtype_enhancer ||
203 }
204 
205 
207  const set<string>& feat_subtypes)
208 {
209  const CFeatList& feats(*CSeqFeatData::GetFeatList());
210  string gene_subtype = feats.GetStoragekey(CSeqFeatData::e_Gene);
211 
212  set<string> temp_types = feat_subtypes;
213  set<string>::iterator type_iter = temp_types.find(gene_subtype);
214  if (type_iter != temp_types.end()) {
215  subtypes.insert("gene_model");
216  temp_types.erase(type_iter);
217  // It contains genes, so we treat it as a gene model track.
218  // All other RNA, CDS and Exon features will be shown in
219  // the same track.
220  ITERATE (CFeatList, subtype_iter, feats) {
221  if (IsGeneModelFeature(subtype_iter->GetType(), subtype_iter->GetSubtype())) {
222  type_iter = temp_types.find(subtype_iter->GetStoragekey());
223  if (type_iter != temp_types.end()) {
224  temp_types.erase(type_iter);
225  }
226  }
227  }
228  }
229  ITERATE(set<string>, iter, temp_types) {
230  if (*iter == "variation") {
231  subtypes.insert("dbVar");
232  } else if (*iter == kSnpSubtypeStr) {
233  subtypes.insert("dbSNP");
234  } else {
235  subtypes.insert(*iter);
236  }
237  }
238 }
239 
240 
241 static bool s_MatchHeaders(const char** header_names,
242  const set<string>& headers)
243 {
244  for ( ; header_names && *header_names; ++header_names) {
245  if (headers.count(string(*header_names)) == 0) {
246  return false;
247  }
248  }
249  return true;
250 }
251 
252 
254 {
255  static const char* graph_headers[] = {
256  "location-from", "span", "values", NULL
257  };
258  if (s_MatchHeaders(graph_headers, headers)) {
259  return "graph";
260  }
261 
262  static const char* bins_headers[] = {
263  "pos", "pvalue", "trait", "pmids", "reportedGenes",
264  "mappedGenes", "snpId", "trackType", "clinSigID", NULL
265  };
266  if (s_MatchHeaders(bins_headers, headers)) {
267  return "SNP_bins";
268  }
269 
270  static const char* GWAS_headers[] = {
271  "pos", "pvalue", "trackType", NULL
272  };
273  if (s_MatchHeaders(GWAS_headers, headers)) {
274  return "SNP_bins";
275  }
276 
277  static const char* HapMap_headers[] = {
278  "pos", "value", "trackType", NULL
279  };
280  if (s_MatchHeaders(HapMap_headers, headers)) {
281  return "HapMap";
282  }
283 
284  return kEmptyStr;
285 }
286 
287 
290 {
291  CTrackInfo::TTrackInfoList info_list;
292  CConstRef<CSeq_annot> annot = annot_handle.GetCompleteSeq_annot();
293  if (annot) {
294  info_list = GetTrackInfo(*annot, annot_handle.GetScope());
295  }
296  return info_list;
297 }
298 
299 
301  CDataTrackUtils::GetTrackInfo(const CSeq_annot& annot, CScope& scope)
302 {
303  CTrackInfo::TTrackInfoList info_list;
304 
306 
307  info->m_DataId = CSeqUtils::GetUnnamedAnnot();
308  if (annot.IsSetDesc()) {
309  ITERATE (CAnnot_descr::Tdata, descrIter, annot.GetDesc().Get()) {
310  if ((*descrIter)->IsName()) {
311  info->m_DataId = (*descrIter)->GetName();
312  break;
313  }
314  }
315  }
316 // {
317 // unique_ptr<CObjectOStream> dump(CObjectOStream::Open(eSerial_AsnText, "track-annot-" + info->m_DataId + ".asn1"));
318 // *dump << annot;
319 // }
320 
321  info->m_Title = CSeqUtils::GetAnnotName(annot);
322  info->m_Descr = CSeqUtils::GetAnnotComment(annot);
323  info->m_AnnotType = CSeq_annot::TData::SelectionName(annot.GetData().Which());
324 
325  info->m_Show = CSeqUtils::GetAnnotShown(annot);
326  if (annot.IsFtable()) {
327  set<string> feat_subtypes;
328  GetFeatSubtypes(annot, feat_subtypes);
329  set<string> subtypes;
330  FeatSubtypes2TrackSubtypes(subtypes, feat_subtypes);
331  ITERATE (set<string>, subtype_iter, subtypes) {
332  CRef<CTrackInfo> feat_info(new CTrackInfo(*info));
333  feat_info->m_Subtype = *subtype_iter;
334  info_list.push_back(feat_info);
335  }
336  } else if (annot.IsAlign()) {
337  const CSeq_annot::TData::TAlign& aligns = annot.GetData().GetAlign();
338  if ( !aligns.empty() ) {
339  string aln_type =
340  CDataTrackUtils::GetAlignType(*aligns.front(), scope);
341  if ( !aln_type.empty() ) {
342  info->m_Subtype = aln_type;
343  info_list.push_back(info);
344  }
345  }
346  } else if (annot.IsGraph()) {
347  info->m_Subtype = "graph";
348  info_list.push_back(info);
349  } else if (annot.IsSeq_table()) {
350  if (annot.GetData().GetSeq_table().IsSetFeat_subtype() &&
351  annot.GetData().GetSeq_table().GetFeat_subtype() != 0) {
352  int f_subtype = annot.GetData().GetSeq_table().GetFeat_subtype();
353  set<string> subtypes;
354  set<string> feat_subtypes;
355  feat_subtypes.insert(s_GetFeatSubtypeStr(f_subtype));
356  FeatSubtypes2TrackSubtypes(subtypes, feat_subtypes);
357  if ( !subtypes.empty() ) {
358  info->m_Subtype = *subtypes.begin();
359  info_list.push_back(info);
360  }
361  } else {
362  set<string> headers;
363  CDataTrackUtils::GetColumnHeader(headers, annot);
364  info->m_Subtype = CDataTrackUtils::GetSeqTableSubtype(headers);
365  if ( !info->m_Subtype.empty() ) {
366  info_list.push_back(info);
367  }
368  }
369  }
370 
371  return info_list;
372 }
373 
374 
375 void CDataTrackUtils::DataType2TrackType(const string& annot_type,
376  const string& subtype,
377  string& track_key,
378  string& subkey)
379 {
380  string ftable =
382  string align =
384  string seq_table =
386  string graph =
388 
389  if (annot_type == align) {
390  track_key = "alignment_track";
391  subkey = subtype;
392  } else if (annot_type == ftable) {
393  if (subtype == "gene_model") {
394  track_key = "gene_model_track";
395  } else if (subtype == "dbVar") {
396  track_key = "dbvar_track";
397  } else if (subtype == "dbSNP") {
398  track_key = "SNP_track";
399  } else {
400  track_key = "feature_track";
401  subkey = subtype;
402  }
403  } else if (annot_type == graph) {
404  if (subtype == "graph") {
405  track_key = "graph_track";
406  } else if (subtype == "GWAS") {
407  track_key = "SNP_Bins_track";
408  }
409  } else if (annot_type == seq_table) {
410  if (subtype == "GWAS") {
411  track_key = "SNP_Bins_track";
412  } else if (subtype == "HapMap") {
413  track_key = "HapMapRR_track";
414  } else if (subtype == "SNP_bins") {
415  track_key = "SNP_bins_track";
416  } else if (subtype == "graph") {
417  track_key = "graph_track";
418  } else {
419  track_key = "feature_track";
420  subkey = subtype;
421  }
422  } else {
423  if (subtype == "sequence") {
424  track_key = "sequence_track";
425  } else if (subtype == "six_frame") {
426  track_key = "six_frames_translation";
427  } else if (subtype == "segment_map") {
428  track_key = "segment_map_track";
429  }
430  }
431 }
432 
433 
434 /// help class for iterating through the NA DocSum one by one.
436 {
437 public:
438  CNADocSumIterator(const CNAUtils::TEntrezIds &uids, const int max_nas)
439  : m_Valid(false)
440  {
441  if ( uids.empty() )
442  return;
443 
444  // prepare eSummary request
445  CGuiEutilsClient ecli;
446  ecli.SetMaxReturn(max_nas);
447  m_Doc.reset(new xml::document());
448 
449  // Get and show the results
450  try {
451  ecli.Summary("seqannot", uids, *m_Doc);
452  }
453  catch (const CException& e) {
454  LOG_POST(Error << "Get error when trying to retrieve NA meta-data. Error: " << e.GetMsg());
455  return;
456  }
457 
458  xml::node& root = m_Doc->get_root_node();
459  m_DocSumRoot = root.find("DocumentSummarySet", root.begin());
460  if (m_DocSumRoot != root.end()) {
461  m_Valid = true;
463  }
464 
465  }
466 
467  bool is_valid() const
468  {
469  return m_Valid && m_Iter != m_DocSumRoot->end();
470  }
471 
472  operator bool() const
473  {
474  return is_valid();
475  }
476 
477  void operator++()
478  {
479  // please do check the validity before call this method
480  _ASSERT(this->is_valid());
481  ++m_Iter;
482  }
483 
484  const xml::node& operator*() const
485  {
486  // please do check the validity before call this method
487  _ASSERT(this->is_valid());
488  return *m_Iter;
489  }
490 
492  {
493  // please do check the validity before call this method
494  _ASSERT(this->is_valid());
495  return m_Iter;
496  }
497 
498 private:
499  unique_ptr<xml::document> m_Doc;
502  bool m_Valid;
503 };
504 
505 
507 {
508  x_Init();
509 }
510 
511 
512 CNAUtils::CNAUtils(const CSeq_id& id)
513  : m_TargetSeq(&id)
514 {
516  m_Scope->AddDefaults();
517  x_Init();
518 }
519 
520 
521 CNAUtils::CNAUtils(const CSeq_id& id, CScope& scope)
522  : m_TargetSeq(&id)
523  , m_Scope(&scope)
524 {
525  x_Init();
526 }
527 
528 
529 void CNAUtils::GetAllNAAs(TNAAs& naas, const string& context) const
530 {
531  naas.clear();
532  TEntrezIds uids;
533  x_GetNAIds(uids, context);
534  x_GetNAAs(naas, uids);
535 }
536 
538  const string& na,
539  bool filtering,
540  EMetaDataSource* pMDSource,
541  EUidsSource* pUidsSource,
542  bool isGetLinks) const
543 {
544  if (na.empty()) {
545  if(pUidsSource) {
546  *pUidsSource = EUidsSource_EmptyRequest;
547  }
548  return;
549  }
550 
551  md_set.clear();
552  TEntrezIds uids;
553  TNAAs naas;
554  naas.push_back(na);
555  GetNAMetaData(md_set, naas, filtering, pMDSource, pUidsSource, isGetLinks);
556 }
557 
558 
560  const TNAAs& naas,
561  bool filtering,
562  EMetaDataSource* pMDSource,
563  EUidsSource* pUidsSource,
564  bool isGetLinks) const
565 {
566  // LOG_POST("<<<<");
567  if (naas.empty()) {
568  if(pUidsSource) {
569  *pUidsSource = EUidsSource_EmptyRequest;
570  }
571  return;
572  }
573 
574  md_set.clear();
575  TEntrezIds uids;
576  x_SearchNAIds(uids, naas, filtering, pUidsSource);
577  if(uids.empty()) {
578  if(pMDSource) {
580  }
581  return;
582  }
583  x_GetNAMetaData(md_set, uids, isGetLinks, pMDSource);
584  // LOG_POST(">>>>");
585 }
586 
587 const size_t kChunkSize = 256;
588 
590  TNAMetaDataSet& md_set,
591  const string& context,
592  ICanceled* canceledCallback) const
593 {
594  TEntrezIds uids;
595  x_GetNAIds(uids, context);
596  for (TEntrezIds::const_iterator it = uids.begin(); it != uids.end();) {
597  TEntrezIds tmp;
598  for (size_t i = kChunkSize; i != 0 && it != uids.end(); ++it, --i)
599  tmp.push_back(*it);
600  if (canceledCallback && canceledCallback->IsCanceled())
601  break;
602  x_GetNAMetaData(md_set, tmp, false);
603  }
604 }
605 
606 
608  const string& naa) const
609 {
610  TNAMetaDataSet md_set;
611  GetNAMetaData(md_set, naa);
612  GetNATrackInfo(track_info, naa, md_set);
613 }
614 
615 
617  const string& naa,
618  const TNAMetaDataSet& md_set) const
619 {
620  if (md_set.empty()) return;
621 
622  TNAMetaDataSet::const_iterator iter = md_set.find(naa);
623  if (iter != md_set.end()) {
624  string ftable =
626  string align =
628  string seq_table =
630  string graph =
632 
633  const CAnnotMetaData& data = *iter->second;
635  info->m_DataId = data.m_Name;
636  info->m_Title = data.m_Title;
637  info->m_Descr = data.m_Descr;
638  info->m_Group = data.m_xClass;
639  info->m_Dbname = "SADB";
640  info->m_AnnotType = data.m_AnnotType;
641 
642  if (data.m_AnnotType == ftable) {
643  set<string> subtypes;
645  ITERATE (set<string>, subtype_iter, subtypes) {
646  CRef<CTrackInfo> feat_info(new CTrackInfo(*info));
647  feat_info->m_Subtype = *subtype_iter;
648  track_info.push_back(feat_info);
649  }
650  } else if (data.m_AnnotType == align) {
651  if (data.m_Subtypes.empty()) {
652  // try to see if we could find out what type
653  // of alignments it contains
654  if (m_TargetSeq) {
655  if (m_BioseqHandle) {
656  SAnnotSelector sel;
658  sel.SetMaxSize(1);
659  sel.SetCollectNames(false);
660  sel.AddNamedAnnots(data.m_Name);
661  sel.IncludeNamedAnnotAccession(data.m_Name);
662  CAlign_CI aln_iter(m_BioseqHandle, TSeqRange::GetWhole(), sel);
663  if (aln_iter) {
664  string aln_type =
665  CDataTrackUtils::GetAlignType(*aln_iter, const_cast<CScope&>(*m_Scope));
666  if ( !aln_type.empty() ) {
667  info->m_Subtype = aln_type;
668  track_info.push_back(info);
669  }
670  }
671  }
672  }
673  } else if (data.m_Subtypes.size() == 1) {
674  info->m_Subtype = *data.m_Subtypes.begin();
675  track_info.push_back(info);
676  }
677  // otherwise, too many subtype, give up
678  } else if (data.m_AnnotType == graph && data.m_Subtypes.size() < 2) {
679  if (data.m_Subtypes.empty()) {
680  info->m_Subtype = "graph";
681  } else {
682  info->m_Subtype = *data.m_Subtypes.begin();
683  }
684  track_info.push_back(info);
685  } else if (data.m_AnnotType == seq_table) {
686  if (data.m_Subtypes.size() == 1) {
687  info->m_Subtype = *data.m_Subtypes.begin();
688  track_info.push_back(info);
689  } else if (data.m_Subtypes.empty() && m_TargetSeq && m_BioseqHandle) {
690  SAnnotSelector sel;
692  sel.SetMaxSize(1);
693  sel.SetCollectNames(false);
694  sel.AddNamedAnnots(data.m_Name);
695  sel.IncludeNamedAnnotAccession(data.m_Name);
696  CAnnot_CI annot_iter(m_BioseqHandle, sel);
697  if (annot_iter) {
698  const CSeq_annot& annot = *annot_iter->GetCompleteSeq_annot();
699  // check if it stores features
700  if (annot.GetData().GetSeq_table().IsSetFeat_subtype() &&
701  annot.GetData().GetSeq_table().GetFeat_subtype() != 0) {
702  int f_subtype = annot.GetData().GetSeq_table().GetFeat_subtype();
703  info->m_Subtype = s_GetFeatSubtypeStr(f_subtype);
704 
705  set<string> subtypes;
706  set<string> feat_subtypes;
707  feat_subtypes.insert(s_GetFeatSubtypeStr(f_subtype));
708  CDataTrackUtils::FeatSubtypes2TrackSubtypes(subtypes, feat_subtypes);
709  if ( !subtypes.empty() ) {
710  info->m_Subtype = *subtypes.begin();
711  track_info.push_back(info);
712  }
713  } else {
714  set<string> headers;
715  CDataTrackUtils::GetColumnHeader(headers, annot);
716  info->m_Subtype = CDataTrackUtils::GetSeqTableSubtype(headers);
717  if ( !info->m_Subtype.empty() ) {
718  track_info.push_back(info);
719  }
720  }
721  }
722  }
723  }
724  }
725 }
726 
727 
729  const TNAAs& naas) const
730 {
731  TNAMetaDataSet md_set;
732  GetNAMetaData(md_set, naas);
733  GetNATrackInfo(track_info, naas, md_set);
734 }
735 
736 
738  const TNAAs& naas,
739  const TNAMetaDataSet& md_set) const
740 {
741  if (md_set.empty()) return;
742 
743  ITERATE(TNAAs, iter, naas) {
744  GetNATrackInfo(track_info, *iter, md_set);
745  }
746 }
747 
748 
750 {
751  if (size > 0) {
752  m_MaxNAMeta = size;
753  }
754 }
755 
757 {
758  switch(eedb) {
760  return "nucleotide";
762  return "protein";
763  default:
764  ;
765  }
766  return "";
767 }
768 
770 {
771  m_Gi = ZERO_GI;
772 
774 
775  if (m_TargetSeq) {
776  m_BioseqHandle = m_Scope->GetBioseqHandle(*m_TargetSeq);
777  m_SeqIdHandle = m_BioseqHandle.GetAccessSeq_id_Handle();
779  if (shdl) {
780  m_Gi = shdl.GetGi();
781  }
783  }
784 }
785 
786 
787 void CNAUtils::x_GetNAIds(TEntrezIds &uids, const string& context) const
788 {
789  uids.clear();
790  if (!m_BioseqHandle)
791  return;
792 
793  list<string> ids;
794  if (context.empty() || NStr::EqualNocase(context, "all")) {
795  x_GetAllNAIds(uids);
796  } else {
797  // Get NAA ids based on a viewer context
798  // Related JIRA tickets: ID-544 and SV-831
800  }
801 }
802 
803 
805 {
806  CSeqUtils::TSeqIdHandles uids_from;
807  uids_from.push_back(m_SeqIdHandle);
808 
809  try {
810  CStopWatch sw;
811  sw.Start();
812  CSeqUtils::ELinkQuery(s_EEDBToString(m_SeqDB), "seqannot", uids_from, uids);
813  sw.Stop();
814  string info = "Timing: " + sw.AsSmartString(CTimeSpan::eSSP_Millisecond)
815  + ". elink.fcgi query from " + s_EEDBToString(m_SeqDB) + " db. Seq-Annots for ";
816  bool first = true;
817  for (auto i : uids_from) {
818  if (first) first = false;
819  else info += ", ";
820  info += i.AsString();
821  }
822  info += ".";
823 // LOG_POST(Info << info);
824  }
825  catch (const CException& e) {
826  LOG_POST(Error << "Get error when trying to get NA ids for seq-id: " << m_SeqIdHandle.AsString() << ". Error: " << e.GetMsg());
827  }
828 }
829 
830 
831 void CNAUtils::x_GetAllNAIdsWithContext(TEntrezIds &uids, const string& context) const
832 {
833  CSeqUtils::TSeqIdHandles uids_from;
834  uids_from.push_back(m_SeqIdHandle);
835 
836  xml::document linkset;
837 
838  try {
839  CSeqUtils::ELinkQuery(s_EEDBToString(m_SeqDB), "seqannot", uids_from, linkset, "neighbor_history");
840  }
841  catch (const CException& e) {
842  LOG_POST(Error << "Got error when trying to get NA list for seq-id: " << m_SeqIdHandle.AsString() << " and context: " << context << ". Error: " << e.GetMsg());
843  return;
844  }
845 
846  xml::node_set nodes ( linkset.get_root_node().run_xpath_query("//LinkSetDbHistory/QueryKey/text()") );
847  if (nodes.empty())
848  return;
849  string query_key_str = nodes.begin()->get_content();
850 
851  nodes = linkset.get_root_node().run_xpath_query("//WebEnv/text()");
852  if (nodes.empty())
853  return;
854  string web_env = nodes.begin()->get_content();
855  if (query_key_str.empty() || web_env.empty())
856  return;
857 
858  // Get NA ids using esearch
859  size_t count(0);
860  try {
861  CSeqUtils::ESearchQuery("seqannot", context + "[viewer_context]", web_env, query_key_str, uids, count);
862  }
863  catch (const CException& e) {
864  LOG_POST(Error << "Got error when trying to get NA id list for viewer_context: " << context << " and query_key: " << query_key_str << ". Error: " << e.GetMsg());
865  }
866 }
867 
868 
869 void CNAUtils::x_GetNAAs(TNAAs& naas, const TEntrezIds &uids) const
870 {
871  CNADocSumIterator ds_iter(uids, m_MaxNAMeta);
872  for (; ds_iter; ++ds_iter) {
873  xml::node::const_iterator c_i = ds_iter->find("Caption", ds_iter->begin());
874  xml::node::const_iterator sum_i = ds_iter->find("ExpXml", ds_iter->begin());
875  if (c_i != ds_iter->end() && sum_i != ds_iter->end()) {
876  string naa(c_i->get_content());
877  naas.push_back(naa);
878  }
879  }
880 }
881 
882 
884  const TEntrezIds &uids,
885  bool isGetLinks,
886  EMetaDataSource* pSource) const
887 {
888  // LOG_POST("<<<<");
889  if(uids.size() == 0) {
890  if(pSource) {
891  *pSource = EMetaDataSource_EmptyRequest;
892  }
893  return;
894  }
895  // first check the cache and get information from it for those uids that are cached
896  // set aside uids that are not in the cache and later retrieve them using eutils
897  TEntrezIds non_cached_uids;
898  {
899  CFastMutexGuard lock(sm_UidtoMetaDataCacheMutex);
900  ITERATE(TEntrezIds, iuids, uids) {
902  if(iCacheHit != sm_UidtoMetaDataCache.end()) {
903  // LOG_POST(Trace << "CNAUtils::x_GetNAMetaData() cache hit on uid: " << *iuids);
904  md_set[iCacheHit->second->m_Name] = iCacheHit->second;
905  } else {
906  // LOG_POST(Trace << "CNAUtils::x_GetNAMetaData() cache miss on uid: " << *iuids);
907  non_cached_uids.push_back(*iuids);
908  }
909  }
910  }
911  if(pSource) {
912  if(uids.size() == 0) {
913  *pSource = EMetaDataSource_EmptyRequest;
914  }
915  if(non_cached_uids.size() > 0) {
916  if(non_cached_uids.size() == uids.size()) {
917  *pSource = EMetaDataSource_Eutils;
918  } else {
919  *pSource = EMetaDataSource_Mixed;
920  }
921  } else {
922  *pSource = EMetaDataSource_Cache;
923  }
924  }
925  if (non_cached_uids.size() > 0) {
926  CStopWatch sw;
927  sw.Start();
928  CNADocSumIterator ds_iter(non_cached_uids, m_MaxNAMeta);
929  sw.Stop();
930  string info = "Timing: " + sw.AsSmartString(CTimeSpan::eSSP_Millisecond)
931  + ". esummary.fcgi query for ";
932  bool first = true;
933  for (auto i : non_cached_uids) {
934  if (first) first = false;
935  else info += ", ";
937  }
938  info += ".";
939 // LOG_POST(Info << info);
940 
941  for (; ds_iter; ++ds_iter) {
942  xml::node::const_iterator c_i = ds_iter->find("Caption", ds_iter->begin());
943  xml::node::const_iterator sum_i = ds_iter->find("ExpXml", ds_iter->begin());
944  if (c_i != ds_iter->end() && sum_i != ds_iter->end()) {
946  data->m_Name = c_i->get_content();
947 
948  ITERATE(xml::attributes, a_i, ds_iter->get_attributes()) {
949  if (NStr::Equal(a_i->get_name(), "uid")) {
950  data->m_Id = a_i->get_value();
951  break;
952  }
953  }
954 
955  try {
956  x_ParseNAMetaData(*data, sum_i->get_content());
957  // always get links so they can be cached even when the are not requested by caller
958  md_set[data->m_Name] = data;
959  if (!data->m_Id.empty())
960  {
961  TEntrezId uid(NStr::StringToNumeric<TEntrezId>(data->m_Id));
962  if (!errno) {
963  // add retrieved data to cache
964  CFastMutexGuard lock(sm_UidtoMetaDataCacheMutex);
966  // LOG_POST(Trace << "CNAUtils::x_GetNAMetaData() added to cache uid: " << uid);
967  }
968  }
969  }
970  catch (const CException&) {
971  // ignore this NA
972  }
973  catch (const exception&) {
974  // ignore this NA
975  }
976  }
977  }
978  }
979  // if links are requested, check all prepared entries for presence of links and get them
980  // from eutils if some are missing
981  if (isGetLinks) {
982  NON_CONST_ITERATE(TNAMetaDataSet, i_md_set, md_set) {
983  if (i_md_set->second->m_LinksStatus == CAnnotMetaData::ELinksStatus_Undef) {
984  CRef<CAnnotMetaData> data(i_md_set->second);
986  if (pSource && *pSource == EMetaDataSource_Cache){
987  *pSource = EMetaDataSource_Mixed;
988  }
989  // LOG_POST(Trace << "CNAUtils::x_GetNAMetaData() links added to cache uid: " << (*i_md_set)->m_Id);
990  }
991  }
992  }
993  // LOG_POST(">>>>");
994 }
995 
996 
998  EUidsSource* pUidsSource) const
999 {
1000  // LOG_POST("<<<<");
1001  TEntrezIds filtered_ids;
1002  ITERATE(TEntrezIds, i_uids, uids) {
1003  if(x_NAIdMatchesGI(*i_uids, pUidsSource)) {
1004  filtered_ids.push_back(*i_uids);
1005  }
1006  }
1007  uids.swap(filtered_ids);
1008  // LOG_POST(">>>>");
1009 }
1010 
1011 #define USE_GI_CACHING
1012 #ifdef USE_GI_CACHING
1014  EUidsSource* pUidsSource) const
1015 {
1016  // LOG_POST("<<<<" << uid);
1017  bool isMatch(false);
1018  if(m_Gi != ZERO_GI) {
1019  TGis gis;
1020  x_GetAllGIs(uid, gis, pUidsSource);
1021  isMatch = (gis.find(m_Gi) != gis.end());
1022  } else {
1023  // if a target sequence was not given, it's always a match
1024  // otherwise, it looks like a GI-less sequence and is always a mismatch (at least for now, while eutils can't truly work with
1025  // GI-less accessions, EU-2741)
1026  isMatch = !m_TargetSeq;
1027  }
1028  // LOG_POST(">>>>" << isMatch);
1029  return isMatch;
1030 }
1031 
1032 #else
1033 
1034 // Use XPath request that does not return large result set
1035 // The drawback - hard to implement GIs caching
1037  EUidsSource* pUidsSource) const
1038 {
1039  TEntrezIds uids_from;
1040  uids_from.push_back(uid);
1041  CSeqUtils::TGis gis_to;
1042 
1043  if(m_Gi != ZERO_GI) {
1044  try {
1045  // LOG_POST("Calling eutils to get all GI IDs for NA Id " << uid);
1046  if(pUidsSource) {
1047  *pUidsSource = (*pUidsSource == EUidsSource_Cache || *pUidsSource == EUidsSource_Mixed) ? EUidsSource_Mixed : EUidsSource_Eutils;
1048  }
1049  CSeqUtils::ELinkQuery("seqannot", s_EEDBToString(m_SeqDB), uids_from, gis_to, "neighbor",
1050  "/eLinkResult/LinkSet/LinkSetDb/Link[Id=" + NStr::IntToString(m_Gi) + "]/Id/text()");
1051  // LOG_POST("Calling eutils done");
1052  return !gis_to.empty() && gis_to[0] == m_Gi;
1053  }
1054  catch (const CException& e) {
1055  LOG_POST(Error << "Get error when trying to get GIs for NA uid: " << uid << ". Error: " << e.GetMsg());
1056  return false;
1057  }
1058  } else {
1059  // if a target sequence was not given, it's always a match
1060  // otherwise, it looks like a GI-less sequence and is always a mismatch (at least for now, while eutils can't truly work with
1061  // GI-less accessions, EU-2741)
1062  return !m_TargetSeq
1063  }
1064 }
1065 
1066 #endif
1067 
1068 void CNAUtils::GetAllGIs(const TNAA& naa, EEntrezDB eedb, TGis& gis,
1069  EUidsSource* pUidsSource)
1070 {
1071  TEntrezId na_uid;
1072 
1073  if(!x_GetNAId(na_uid, naa, pUidsSource)) {
1074  return;
1075  }
1076  if(eedb == EEDB_All) {
1077  x_GetAllGIs(na_uid, EEDB_Nucleotide, gis, pUidsSource);
1078  x_GetAllGIs(na_uid, EEDB_Protein, gis, pUidsSource, true);
1079  } else {
1080  x_GetAllGIs(na_uid, eedb, gis, pUidsSource);
1081  }
1082 }
1083 
1084 
1086  EUidsSource* pUidsSource) const
1087 {
1088  x_GetAllGIs(uid, m_SeqDB, gis, pUidsSource);
1089 }
1090 
1092 {
1093  return NStr::NumericToString(uid) + "|" + s_EEDBToString(eedb);
1094 }
1095 
1097  EUidsSource* pUidsSource,
1098  bool isIncremental)
1099 {
1100  // LOG_POST("<<<<");
1101  if(!isIncremental) {
1102  gis.clear();
1103  }
1104  NCBI_ASSERT(eedb != EEDB_Undef, "Entrez database not defined!");
1105  {
1106  // first check the cache
1107  CFastMutexGuard lock(sm_UidtoGiCacheMutex);
1109  if(iCacheHit != sm_UidtoGiCache.end()) {
1110  gis.insert(iCacheHit->second.begin(), iCacheHit->second.end());
1111  // LOG_POST(Trace << "CNAUtils::x_GetAllGIs() cache hit on uid: " << uid);
1112  if(pUidsSource) {
1113  *pUidsSource = (*pUidsSource == EUidsSource_Eutils || *pUidsSource == EUidsSource_Mixed) ? EUidsSource_Mixed : EUidsSource_Cache;
1114  }
1115  return;
1116  }
1117  }
1118  // LOG_POST(Trace << "CNAUtils::x_GetAllGIs() cache miss on uid: " << uid);
1119  TEntrezIds uids_from;
1120  uids_from.push_back(uid);
1121  CSeqUtils::TGis gis_to;
1122 
1123  try {
1124  // LOG_POST("Calling eutils to get all GI IDs for NA Id " << uid);
1125  if(pUidsSource) {
1126  *pUidsSource = (*pUidsSource == EUidsSource_Cache || *pUidsSource == EUidsSource_Mixed) ? EUidsSource_Mixed : EUidsSource_Eutils;
1127  }
1128 #if 0
1129  // This call uses XPath inside and appears to be very slow, in the order of
1130  // minutes if the result set is in tens of thousands of entries. It is deficiency
1131  // of XPath library - extremely inefficient sorting of result set which,
1132  // in addition sorts incorrectly
1133  CSeqUtils::ELinkQuery("seqannot", s_EEDBToString(eedb), uids_from, gis_to);
1134  // More efficient query
1135 // CSeqUtils::ELinkQuery("seqannot", s_EEDBToString(m_SeqDB), uids_from, gis_to, "neighbor",
1136 // "/eLinkResult/LinkSet/LinkSetDb/Link/Id/text()");
1137 
1138 // DEBUG
1139 // CNcbiOfstream ofs;
1140 // ofs.open("debug_xpath_expression.txt", std::ofstream::out);
1141 // ITERATE(CSeqUtils::TGis, i_gis_to, gis_to) {
1142 // ofs << NStr::NumericToString<TGi>(*i_gis_to) << endl;
1143 // }
1144 // ofs.close();
1145 // gis_to.clear();
1146 #else
1147 
1148  // Run "/eLinkResult/LinkSet/LinkSetDb/Link/Id/text()" manually
1149 
1150  xml::document xmldoc;
1151  CSeqUtils::ELinkQuery("seqannot", s_EEDBToString(eedb), uids_from, xmldoc);
1152 
1153  // LOG_POST("XML doc for " << uid << " " << xmldoc);
1154 
1155  string container_path[] = { "eLinkResult", "LinkSet", "LinkSetDb" };
1156  const int container_path_length = 3;
1157  string content_path[] = { "Link", "Id" };
1158  const int content_path_length = 2;
1159 
1160  const xml::node *container = &xmldoc.get_root_node();
1161  // Find actual container
1162  bool found = false;
1163  // Check the root for name match
1164  int cp = 0;
1165  xml::node::const_iterator it, it1, it2;
1166  if (container->get_name() == container_path[cp++]) {
1167  // LOG_POST("XDoc root matched eLinkResult");
1168  for (; cp < container_path_length; ++cp) {
1169  found = false;
1170  for (it = container->begin(); it != container->end(); ++it) {
1171  if (!it->is_text() && it->get_name() == container_path[cp]) {
1172  // Found container path part
1173  found = true;
1174  container = &*it;
1175  break;
1176  }
1177  }
1178  if (!found) break;
1179  }
1180  }
1181  if (found) {
1182  // LOG_POST(container->get_name() << " found");
1183  for (it1 = container->begin(); it1 != container->end(); ++it1) {
1184  if (it1->is_text()) continue;
1185 
1186  const xml::node *content = &*it1;
1187  bool found = false;
1188  // Check the node for name match
1189  int cp = 0;
1190  if (content->get_name() == content_path[cp++]) {
1191  // LOG_POST("Verified node root as " << content->get_name());
1192  for (; cp < content_path_length; ++cp) {
1193  found = false;
1194  for (it2 = content->begin(); it2 != content->end(); ++it2) {
1195  if (!it2->is_text() && it2->get_name() == content_path[cp]) {
1196  // Found container path part
1197  found = true;
1198  content = &*it2;
1199  break;
1200  }
1201  }
1202  if (!found) break;
1203  }
1204  }
1205  if (found) {
1206  // LOG_POST("content found \"" << *content << '"');
1207  string id(content->get_content());
1208  if (!id.empty()) {
1209  gis_to.push_back(NStr::StringToNumeric<TGi>(id));
1210  }
1211  }
1212  }
1213  }
1214  std::sort(gis_to.begin(), gis_to.end());
1215 
1216 // DEBUG dump
1217 // CNcbiOfstream ofs;
1218 // ofs.open("debug_" + NStr::IntToString(uid) + "_manual.txt", std::ofstream::out);
1219 // ITERATE(CSeqUtils::TGis, i_gis_to, gis_to) {
1220 // ofs << *i_gis_to << endl;
1221 // }
1222 // ofs.close();
1223 #endif
1224  // LOG_POST("Calling eutils done");
1225  }
1226  catch (const CException& e) {
1227  LOG_POST(Error << "Get error when trying to get GIs for uid: " << uid << ". Error: " << e.GetMsg());
1228  }
1229  {
1230  // LOG_POST(Trace << "CNAUtils::x_GetAllGIs() added to cache uid: " << uid);
1231  // update the cache and return the values
1232  CFastMutexGuard lock(sm_UidtoGiCacheMutex);
1233 
1234  // create a map element even if a list of GIs is empty
1235  TGis& cached_gis(sm_UidtoGiCache[s_MakeUidtoGiCacheKey(uid, eedb)]);
1236 
1237  ITERATE(CSeqUtils::TGis, i_gis_to, gis_to) {
1238  gis.insert(*i_gis_to);
1239  cached_gis.insert(*i_gis_to);
1240  }
1241  }
1242  // LOG_POST(">>>>");
1243 }
1244 
1245 
1246 void CNAUtils::x_SearchNAIds(TEntrezIds &uids, const TNAAs& naas, bool filtering,
1247  EUidsSource* pUidsSource) const
1248 {
1249  ITERATE(TNAAs, inaas, naas) {
1250  TEntrezId uid;
1251  if(x_GetNAId(uid, *inaas, pUidsSource)) {
1252  uids.push_back(uid);
1253  }
1254  }
1255  if(filtering && m_BioseqHandle) {
1256  // getting all NA IDs for a molecule proved to be extremely slow
1257  // doing the inverse -- check GIs for each of all presented NA IDs and select the ones that have matching GIs
1258  x_FilterNAIds(uids, pUidsSource);
1259  }
1260 }
1261 
1262 bool CNAUtils::x_GetNAId(TEntrezId &uid, const string& naa, EUidsSource* pUidsSource)
1263 {
1264  // LOG_POST("<<<<");
1265  // check for presence of a given naa in cache
1266  {
1267  CFastMutexGuard lock(sm_NAAtoUidCacheMutex);
1269  if(iCacheHit != sm_NAAtoUidCache.end()) {
1270  uid = iCacheHit->second;
1271  // LOG_POST(Trace << "CNAUtils::x_GetNAId() cache hit on NAA: " << naa);
1272  if(pUidsSource) {
1273  *pUidsSource = (*pUidsSource == EUidsSource_Eutils || *pUidsSource == EUidsSource_Mixed) ? EUidsSource_Mixed : EUidsSource_Cache;
1274  }
1275  return true;
1276  }
1277  }
1278  // LOG_POST(Trace << "CNAUtils::x_GetNAId() cache miss on NAA: " << naa);
1279  // prepare eSearch request
1280  CGuiEutilsClient ecli;
1281  // should normally be one, so using a dynamic setting does not make sense hier
1282  ecli.SetMaxReturn(kRetMax);
1283  TEntrezIds uids;
1284 
1285  try {
1286  // LOG_POST("Calling eutils with term " << term);
1287  if(pUidsSource) {
1288  *pUidsSource = (*pUidsSource == EUidsSource_Cache || *pUidsSource == EUidsSource_Mixed) ? EUidsSource_Mixed : EUidsSource_Eutils;
1289  }
1290  ecli.Search("seqannot", naa, uids);
1291  // LOG_POST("eutils call done");
1292  }
1293  catch (const CException& e) {
1294  LOG_POST(Error << "Get error when trying to search NAAs for: " << naa << ". Error: " << e.GetMsg());
1295  return false;
1296  }
1297  // if found by eutils, update the cache and return the value
1298  if(uids.size()) {
1299  NCBI_ASSERT(uids.size() == 1, "More that one uid is returned for NAA");
1300  uid = uids[0];
1301  // LOG_POST(Trace << "CNAUtils::x_GetNAId() added to cache NAA: " << naa);
1302  CFastMutexGuard lock(sm_NAAtoUidCacheMutex);
1303  sm_NAAtoUidCache[naa] = uid;
1304  return true;
1305  }
1306  return false;
1307  // LOG_POST(">>>>");
1308 }
1309 
1310 
1311 // child node 'Descriptor'
1312 // child node 'Provider'
1313 // child node 'XClass'
1314 // child node 'Content'
1315 // child node 'Properties'
1316 
1317 void CNAUtils::x_ParseNAMetaData(CAnnotMetaData& data, const char* xml_str) const
1318 {
1319  xml::document doc(xml_str, strlen(xml_str), NULL);
1320  xml::node& root = doc.get_root_node();
1322  // parse descriptor
1323  ITERATE (xml::node, i, root) {
1324  if (NStr::Equal(i->get_name(), "Algorithm-List")) continue;
1325 
1326  string node_name = i->get_name();
1327  if (node_name == "Descriptor") {
1328  ITERATE (xml::node, e_i, *i) {
1329  if (NStr::Equal(e_i->get_name(), "Title")) {
1330  data.m_Title = e_i->get_content();
1331  } else if (NStr::Equal(e_i->get_name(), "Comment")) {
1332  string tmp_str = e_i->get_content();
1333  tmp_str = NStr::Replace(tmp_str, "&amp;", "&");
1334  tmp_str = NStr::Replace(tmp_str, "&#xA;", "\n");
1335  tmp_str = NStr::Replace(tmp_str, "&#xa;", "\n");
1336  data.m_Descr = tmp_str;
1337  }
1338  }
1339  ITERATE (xml::attributes, a_i, i->get_attributes()) {
1340  if (NStr::Equal(a_i->get_name(), "name")) {
1341  data.m_OtherName = a_i->get_value();
1342  } else if (NStr::Equal(a_i->get_name(), "scope")) {
1343  data.m_Scope = a_i->get_value();
1344  }
1345  }
1346  if (data.m_Title.empty()) {
1347  data.m_Title = data.m_OtherName;
1348  }
1349  }
1350  else if (node_name == "Provider") {
1351  ITERATE(xml::node, e_i, *i) {
1352  if (!NStr::Equal(e_i->get_name(), "Annot-chain"))
1353  continue;
1354  data.m_AnnotChain = e_i->get_content();
1355  break;
1356  }
1357  } else if (node_name == "XClass") {
1358  ITERATE (xml::attributes, a_i, i->get_attributes()) {
1359  if (NStr::Equal(a_i->get_name(), "type")) {
1360  data.m_xClass = a_i->get_value();
1361  }
1362  }
1363 
1364  } else if (node_name == "Properties") {
1365  string keywords = kEmptyStr;
1366  ITERATE (xml::node, e_i, *i) {
1367  string e_name = e_i->get_name();
1368  if (e_name == "TargetAssembly") {
1369  ITERATE (xml::attributes, a_i, e_i->get_attributes()) {
1370  if (NStr::Equal(a_i->get_name(), "idstr")) {
1371  data.m_AssmAcc = a_i->get_value();
1372  }
1373  }
1374  } else if (e_name == "LinkList") {
1375  ITERATE (xml::node, ln_i, *e_i) {
1376  if ( !NStr::Equal(ln_i->get_name(), "Link") ) {
1377  continue;
1378  }
1379  ITERATE (xml::node, url_entrez_i, *ln_i) {
1380  string label, url;
1381  if (NStr::Equal(url_entrez_i->get_name(), "URL_Link")) {
1382  ITERATE (xml::node, lln_i, *url_entrez_i) {
1383  if (NStr::Equal(lln_i->get_name(), "Label")) {
1384  label = lln_i->get_content();
1385  } else if (NStr::Equal(lln_i->get_name(), "URL")) {
1386  url = lln_i->get_content();
1387  }
1388  }
1389  } else if (NStr::Equal(url_entrez_i->get_name(), "Entrez_Link")) {
1390  // we shouldn't retrieve Entrez links from NAA's meta-data since
1391  // they might not be up-to-date. Instead, we will retrieve them
1392  // through elink.fcgi.
1393  ITERATE (xml::node, lln_i, *url_entrez_i) {
1394  if (NStr::Equal(lln_i->get_name(), "DB")) {
1395  label = lln_i->get_content();
1396  } else if (NStr::Equal(lln_i->get_name(), "ID")) {
1397  url = lln_i->get_content();
1398  }
1399  }
1400  if ( !label.empty() && !url.empty() ) {
1401  url = "https://www.ncbi.nlm.nih.gov/" +
1402  label + "/" + url;
1403  }
1404  }
1405  if ( !label.empty() && !url.empty() ) {
1406  data.m_Links[label] = url;
1407  }
1408  }
1409  }
1410  }
1411  }
1412 
1413  } else if (node_name == "Content") {
1414  // It is possible there are more than one annotation types
1415  // and feature (sub)types set in meta-data. We need to
1416  // collect them all
1417  set<string> annot_types;
1418  ITERATE (xml::node, e_i, *i) {
1419  string e_name = e_i->get_name();
1420  if (e_name == "Annot") {
1421  ITERATE (xml::attributes, a_i, e_i->get_attributes()) {
1422  if (NStr::Equal(a_i->get_name(), "type")) {
1423  annot_types.insert(a_i->get_value());
1424  }
1425  }
1426  ITERATE (xml::node, t_i, *e_i) {
1427  if (NStr::Equal(t_i->get_name(), "Feature")) {
1428  ITERATE (xml::attributes, a_i, t_i->get_attributes()) {
1429  if (NStr::Equal(a_i->get_name(), "type") &&
1430  !NStr::Equal(a_i->get_value(), "bad")) {
1431  data.m_Subtypes.insert(string(a_i->get_value()));
1432  }
1433  }
1434  }
1435  }
1436  }
1437  }
1438 
1439  if ( !data.m_Subtypes.empty() ) {
1440  // It is feature table
1441  // We will use all feature subtypes
1442  string ftable =
1444  data.m_AnnotType = ftable;
1445  } else {
1446  vector<string> priorytized_types;
1447  priorytized_types.push_back(
1449  priorytized_types.push_back(
1451  priorytized_types.push_back(
1453 
1454  ITERATE(vector<string>, type_iter, priorytized_types) {
1455  set<string>::const_iterator at_iter = annot_types.find(*type_iter);
1456  if (at_iter != annot_types.end()) {
1457  data.m_AnnotType = *type_iter;
1458  break;
1459  }
1460  }
1461  }
1462  }
1463  }
1464 }
1465 
1466 
1468 {
1469  // LOG_POST("<<<<");
1470  TEntrezIds uids_from;
1471  uids_from.push_back(NStr::StringToNumeric<TEntrezId>(data.m_Id));
1472 
1473  xml::document linkset;
1474 
1475  data.m_LinksStatus = CAnnotMetaData::ELinksStatus_Absent;
1476  try {
1477  // LOG_POST("Calling eutils for linkset/acheck");
1478  CSeqUtils::ELinkQuery("seqannot", "all", uids_from, linkset, "acheck");
1479  // LOG_POST("Call done");
1480  }
1481  catch (const CException& e) {
1482  LOG_POST(Error << "Get error when trying to get Entrez links for NA id: " << data.m_Id << ". Error: " << e.GetMsg());
1483  return;
1484  }
1485 
1486  xml::node_set::const_iterator itLinkInfo;
1487  xml::node_set nodes ( linkset.get_root_node().run_xpath_query("//LinkInfo[DbTo/text()!=\"\"][LinkName/text()!=\"\"][HtmlTag/text()!=\"\"]") );
1488  for (itLinkInfo = nodes.begin(); itLinkInfo != nodes.end(); ++itLinkInfo) {
1489  const string html_tag(itLinkInfo->find("HtmlTag")->get_content());
1490  const string db_to(itLinkInfo->find("DbTo")->get_content());
1491  const string link_name(itLinkInfo->find("LinkName")->get_content());
1492 
1493  if (db_to == "nuccore")
1494  continue;
1495 
1496  TEntrezIds uids;
1497  try {
1498  // LOG_POST("Calling eutils for linkset in db_to: " << db_to << ", html_tag: " << html_tag << ", link_name: " << link_name);
1499  CSeqUtils::ELinkQuery("seqannot", db_to, uids_from, uids);
1500  // LOG_POST("Call done");
1501  }
1502  catch (const CException& e) {
1503  LOG_POST(Error << "Get error when trying to get Entrez links for link name: " << link_name << ". Error: " << e.GetMsg());
1504  continue;
1505  }
1506 
1507  string link("https://www.ncbi.nlm.nih.gov/");
1508  // Generate a link from all UIDs
1509  link += db_to + "/" + CSeqUtils::CreateIdStr(uids);
1510  NON_CONST_ITERATE(CAnnotMetaData::TLinks, c_link, data.m_Links) {
1511  if (c_link->second == link) {
1512  data.m_Links.erase(c_link);
1513  break;
1514  }
1515  }
1516  data.m_Links[html_tag] = link;
1518  }
1519  // LOG_POST(">>>>");
1520 }
1521 
1522 
static CRef< CScope > m_Scope
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
CAlign_CI –.
Definition: align_ci.hpp:63
Data structure for holding meta information for an annotaion.
Definition: annot_info.hpp:85
CAnnot_CI –.
Definition: annot_ci.hpp:59
CBioseq_Handle –.
void SetMaxReturn(int ret_max)
Uint8 Search(const string &db, const string &term, vector< objects::CSeq_id_Handle > &uids, const string &xml_path=kEmptyStr)
void Summary(const string &db, const vector< objects::CSeq_id_Handle > &uids, xml::document &docsums, const string &version="")
CConfigurableItems - a static list of items that can be configured.
string GetStoragekey(int type, int subtype) const
Get the key used to store this type of feature.
help class for iterating through the NA DocSum one by one.
Definition: na_utils.cpp:436
CNADocSumIterator(const CNAUtils::TEntrezIds &uids, const int max_nas)
Definition: na_utils.cpp:438
xml::node::const_iterator operator->() const
Definition: na_utils.cpp:491
xml::node::const_iterator m_Iter
Definition: na_utils.cpp:500
unique_ptr< xml::document > m_Doc
Definition: na_utils.cpp:499
bool is_valid() const
Definition: na_utils.cpp:467
xml::node::const_iterator m_DocSumRoot
Definition: na_utils.cpp:501
const xml::node & operator*() const
Definition: na_utils.cpp:484
CRef –.
Definition: ncbiobj.hpp:618
CScope –.
Definition: scope.hpp:92
static const CFeatList * GetFeatList()
TDim CheckNumRows(void) const
Validatiors.
Definition: Seq_align.cpp:73
const CSeq_id & GetSeq_id(TDim row) const
Get seq-id (the first one if segments have different ids).
Definition: Seq_align.cpp:317
CSeq_annot_Handle –.
bool IsGraph(void) const
Definition: Seq_annot.cpp:187
bool IsAlign(void) const
Definition: Seq_annot.cpp:182
bool IsSeq_table(void) const
Definition: Seq_annot.cpp:202
bool IsFtable(void) const
Definition: Seq_annot.cpp:177
CStopWatch –.
Definition: ncbitime.hpp:1937
Data structure for holding basic data track information.
Definition: annot_info.hpp:54
Interface for testing cancellation request in a long lasting operation.
Definition: icanceled.hpp:51
container_type::const_iterator const_iterator
Definition: map.hpp:53
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
const_iterator begin() const
Definition: set.hpp:135
void clear()
Definition: set.hpp:153
bool empty() const
Definition: set.hpp:133
const_iterator find(const key_type &key) const
Definition: set.hpp:137
void erase(iterator pos)
Definition: set.hpp:151
const_iterator end() const
Definition: set.hpp:136
The xml::attributes class is used to access all the attributes of one xml::node.
Definition: attributes.hpp:78
The xml::document class is used to hold the XML tree and various bits of information about it.
Definition: document.hpp:80
const node & get_root_node(void) const
Get a reference to the root node of this document.
Definition: document.cpp:539
The xml::node::const_iterator provides a way to access children nodes similar to a standard C++ conta...
Definition: node.hpp:746
The xml::node_set::const_iterator class is used to iterate over nodes in a node set.
Definition: node_set.hpp:226
The xml::node_set class is used to store xpath query result set.
Definition: node_set.hpp:68
iterator begin()
Get an iterator that points to the beginning of the xpath query result node set.
Definition: node_set.cpp:173
bool empty() const
Inform if the xpath query result node set is empty.
Definition: node_set.cpp:160
iterator end()
Get an iterator that points one past the last node in the xpath query result node set.
Definition: node_set.cpp:185
The xml::node class is used to hold information about one XML node.
Definition: node.hpp:106
bool is_text(void) const
Find out if this node is a text node or sometiming like a text node, CDATA for example.
Definition: node.cpp:1189
const char * get_name(void) const
Get the name of this xml::node.
Definition: node.cpp:769
iterator end(void)
Get an iterator that points one past the last child for this node.
Definition: node.hpp:835
iterator find(const char *name, const ns *nspace=NULL)
Find the first child node that has the given name and namespace.
Definition: node.cpp:1258
iterator begin(void)
Get an iterator that points to the beginning of this node's children.
Definition: node.cpp:1217
node_set run_xpath_query(const xpath_expression &expr)
Run the given XPath query.
Definition: node.cpp:1292
const char * get_content(void) const
Get the content for this text node.
Definition: node.cpp:797
#define false
Definition: bool.h:36
#define bool
Definition: bool.h:34
static DLIST_TYPE *DLIST_NAME() first(DLIST_LIST_TYPE *list)
Definition: dlist.tmpl.h:46
static char tmp[3200]
Definition: utf8.c:42
char data[12]
Definition: iconv.c:80
SStrictId_Entrez::TId TEntrezId
TEntrezId type for entrez ids which require the same strictness as TGi.
Definition: ncbimisc.hpp:1041
#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
#define ZERO_GI
Definition: ncbimisc.hpp:1088
#define NULL
Definition: ncbistd.hpp:225
#define NCBI_ASSERT(expr, mess)
Definition: ncbidbg.hpp:130
#define LOG_POST(message)
This macro is deprecated and it's strongly recomended to move in all projects (except tests) to macro...
Definition: ncbidiag.hpp:226
void Error(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1197
const string & GetMsg(void) const
Get message string.
Definition: ncbiexpt.cpp:461
const string & FindName(TEnumValueType value, bool allowBadValue) const
Find name of the enum by its numeric value.
Definition: enumerated.cpp:146
void x_SearchNAIds(TEntrezIds &uids, const TNAAs &naas, bool filtering, EUidsSource *pUidsSource=NULL) const
Search all NAAs for a given term.
Definition: na_utils.cpp:1246
static void GetColumnHeader(set< string > &headers, const objects::CSeq_annot &annot)
Collect all column header names for a given seq-table.
Definition: na_utils.cpp:165
static void ELinkQuery(const string &db_from, const string &db_to, const TEntrezIds &uids_from, TEntrezIds &uids_to, const string &cmd="neighbor", const string &xpath="//Link/Id/text()")
Queries elink.fcgi with a vector of uids/seq-ids (seq-ids preferred for future compatibility) and ret...
Definition: utils.cpp:1613
list< TNAA > TNAAs
Definition: na_utils.hpp:120
TGi m_Gi
GI of m_TargetSeq; it may be ZERO_GI for one of two reasons: either a target seq is not given at all ...
Definition: na_utils.hpp:314
CTrackInfo::TTrackInfoList TTrackInfoList
Definition: na_utils.hpp:122
objects::CBioseq_Handle m_BioseqHandle
Derived values which make sense only if m_TargetSeq is set.
Definition: na_utils.hpp:312
static TNAAtoUidCache sm_NAAtoUidCache
Definition: na_utils.hpp:326
static void ESearchQuery(const string &db, const string &term, TEntrezIds &uids, size_t &count, const int ret_max, const string &xpath="//IdList/Id/text()")
Queries esearch.fcgi and returns a vector of uids/seq-ids (seq-ids preferred for future compatibility...
Definition: utils.cpp:1680
void x_FilterNAIds(TEntrezIds &uids, EUidsSource *pUidsSource=NULL) const
filter a given list of NA uids and keep only the ones that are related to a given gi (m_GI)
Definition: na_utils.cpp:997
EMetaDataSource
source of obtained NA metadata were internal caches hit, partially hit or totally missed during some ...
Definition: na_utils.hpp:134
EEntrezDB m_SeqDB
Entrez db name for m_TargetSeq: nucleotide/protein or Undef if no TargetSeq is given.
Definition: na_utils.hpp:316
void x_GetAllNAIdsWithContext(TEntrezIds &uids, const string &context) const
get all available NA ids applied to a viewer context for a given gi.
Definition: na_utils.cpp:831
static void GetAllGIs(const TNAA &naa, EEntrezDB eedb, TGis &gis, EUidsSource *pUidsSource=NULL)
Definition: na_utils.cpp:1068
string TNAA
typedefs for NAA meta-data
Definition: na_utils.hpp:119
void x_GetNAIds(TEntrezIds &uids, const string &context="") const
Get all available NA uids w/wo a context.
Definition: na_utils.cpp:787
void GetNAMetaData(TNAMetaDataSet &md_set, const string &na, bool filtering=false, EMetaDataSource *pMDSource=NULL, EUidsSource *pUidsSource=NULL, bool isGetLinks=true) const
Get meta-data for a specific NA.
Definition: na_utils.cpp:537
vector< objects::CSeq_id_Handle > TSeqIdHandles
Definition: utils.hpp:128
static TEntrezIdtoGiCache sm_UidtoGiCache
Definition: na_utils.hpp:338
static string GetAnnotName(const objects::CSeq_annot_Handle &annot_handle)
CRef< objects::CScope > m_Scope
Scope helping resolve sequences and retrieve annotations.
Definition: na_utils.hpp:309
void x_Init()
Initialize some internal states.
Definition: na_utils.cpp:769
static string GetAlignType(const objects::CSeq_align &align, objects::CScope &scope)
Get alignment type.
Definition: na_utils.cpp:77
void GetAllNAMetaData(TNAMetaDataSet &md_set, const string &context="", ICanceled *canceledCallback=0) const
Get meta-data for a given NAA associated with seq_id.
Definition: na_utils.cpp:589
void x_GetNAMetaData(TNAMetaDataSet &md_set, const TEntrezIds &uids, bool isGetLinks, EMetaDataSource *pSource=NULL) const
Retrieve NA meta data for a list of NA uids.
Definition: na_utils.cpp:883
static void FeatSubtypes2TrackSubtypes(set< string > &subtypes, const set< string > &feat_subtypes)
Convert feature subtypes to track subtypes.
Definition: na_utils.cpp:206
static const string & GetUnnamedAnnot()
Get the commonly used symbol representing a unnnamed annotation.
Definition: utils.hpp:531
void x_GetAllNAIds(TEntrezIds &uids) const
get all available NA uids for a given gi.
Definition: na_utils.cpp:804
static string GetSeqTableSubtype(const set< string > &headers)
Guess the track subtype based on seq-table headers.
Definition: na_utils.cpp:253
static bool IsGeneModelFeature(int type, int subtype)
Does feature belong to gene model track Gene, RNA, cdregion, exon, C_region, and VDJ segments.
Definition: na_utils.cpp:190
static string CreateIdStr(const vector< T > &uids)
Convert a list of ids into a comma-delimited string.
Definition: utils.hpp:552
static string GetAnnotComment(const objects::CSeq_annot_Handle &annot_handle)
static void DataType2TrackType(const string &annot_type, const string &subtype, string &track_key, string &subkey)
Map data type to track type.
Definition: na_utils.cpp:375
objects::CSeq_id_Handle m_SeqIdHandle
sequence handles
Definition: na_utils.hpp:313
static bool GetAnnotShown(const objects::CSeq_annot &annot)
Definition: utils.cpp:2385
static CTrackInfo::TTrackInfoList GetTrackInfo(objects::CSeq_annot_Handle annot_handle)
Get data track information from a seq-annot.
static bool x_GetNAId(TEntrezId &uid, const string &naa, EUidsSource *pUidsSource=NULL)
get an id for a given NAA string returns false if no id is found
Definition: na_utils.cpp:1262
void x_GetNAEntrezLinks(CAnnotMetaData &data) const
Retrieve Entrez links for a given NA.
Definition: na_utils.cpp:1467
void SetMaxNAs(int size)
Definition: na_utils.cpp:749
CSeqUtils::TEntrezIds TEntrezIds
Definition: na_utils.hpp:123
int m_MaxNAMeta
maximal number of NAAs for retrieving meta-data.
Definition: na_utils.hpp:319
static TEntrezIdtoMetaDataCache sm_UidtoMetaDataCache
Definition: na_utils.hpp:332
void GetNATrackInfo(TTrackInfoList &track_info, const string &naa) const
Do data track discovery for a given NA.
Definition: na_utils.cpp:607
bool x_NAIdMatchesGI(TEntrezId uid, EUidsSource *pUidsSource=NULL) const
returns true if an uid is related to a given gi (m_GI) or GI is ZERO_GI
Definition: na_utils.cpp:1013
void x_GetNAAs(TNAAs &naas, const TEntrezIds &uids) const
Retrieve NAAs for a list of NA uids.
Definition: na_utils.cpp:869
vector< TGi > TGis
Definition: utils.hpp:127
EEntrezDB
eutils databases that can be used
Definition: na_utils.hpp:126
static void x_GetAllGIs(TEntrezId uid, EEntrezDB eedb, TGis &gis, EUidsSource *pUidsSource=NULL, bool isIncremental=false)
get all GIs for a given uid this needs a given database where to search for GIs
Definition: na_utils.cpp:1096
static void GetFeatSubtypes(const objects::CSeq_annot &annot, set< string > &subtypes)
Collect unique list of feature subtypes for all features in a seq-annot.
Definition: na_utils.cpp:152
list< CRef< CTrackInfo > > TTrackInfoList
Definition: annot_info.hpp:60
void GetAllNAAs(TNAAs &naas, const string &context="") const
Get a list of NAAs associated with the target sequence.
Definition: na_utils.cpp:529
CNAUtils()
Default ctor.
Definition: na_utils.cpp:506
CConstRef< objects::CSeq_id > m_TargetSeq
The target sequence associating with the NAAs.
Definition: na_utils.hpp:305
void x_ParseNAMetaData(CAnnotMetaData &data, const char *xml_str) const
Parse the meta-data xml DocSum.
Definition: na_utils.cpp:1317
@ EUidsSource_Mixed
Definition: na_utils.hpp:146
@ EUidsSource_EmptyRequest
Definition: na_utils.hpp:148
@ EUidsSource_Eutils
Definition: na_utils.hpp:147
@ EUidsSource_Cache
Definition: na_utils.hpp:145
@ EMetaDataSource_EmptyRequest
Definition: na_utils.hpp:139
@ EMetaDataSource_Cache
Definition: na_utils.hpp:136
@ EMetaDataSource_Mixed
Definition: na_utils.hpp:137
@ EMetaDataSource_EmptyAfterFilteringRequest
Definition: na_utils.hpp:140
@ EMetaDataSource_Eutils
Definition: na_utils.hpp:138
@ EEDB_Protein
Definition: na_utils.hpp:129
@ EEDB_Undef
Definition: na_utils.hpp:127
@ EEDB_Nucleotide
Definition: na_utils.hpp:128
@ EEDB_All
try both nucleotide and protein databases, merge results
Definition: na_utils.hpp:130
TGi GetGi(void) const
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,...
@ eGetId_ForceGi
return only a gi-based seq-id
Definition: sequence.hpp:99
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
TBioseqCore GetBioseqCore(void) const
Get bioseq core structure.
CConstRef< CSeq_annot > GetCompleteSeq_annot(void) const
Complete and return const reference to the current seq-annot.
CScope & GetScope(void) const
Get scope this handle belongs to.
SAnnotSelector & IncludeNamedAnnotAccession(const string &acc, int zoom_level=0)
SAnnotSelector & SetCollectNames(bool value=true)
Collect available annot names rather than annots.
SAnnotSelector & IncludeAnnotType(TAnnotType type)
Include annotation type in the search.
SAnnotSelector & SetMaxSize(TMaxSize max_size)
Set maximum number of annotations to find.
SAnnotSelector & AddNamedAnnots(const CAnnotName &name)
Add named annot to set of annots names to look for.
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
static TThisType GetWhole(void)
Definition: range.hpp:272
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
virtual bool IsCanceled(void) const =0
#define kEmptyStr
Definition: ncbistr.hpp:123
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:5084
static string & Replace(const string &src, const string &search, const string &replace, string &dst, SIZE_TYPE start_pos=0, SIZE_TYPE max_replace=0, SIZE_TYPE *num_replace=0)
Replace occurrences of a substring within a string.
Definition: ncbistr.cpp:3314
static bool EqualNocase(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2)
Case-insensitive equality of a substring with another string.
Definition: ncbistr.hpp:5353
static enable_if< is_arithmetic< TNumeric >::value||is_convertible< TNumeric, Int8 >::value, string >::type NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
Definition: ncbistr.hpp:673
static bool Equal(const CTempString s1, SIZE_TYPE pos, SIZE_TYPE n, const char *s2, ECase use_case=eCase)
Test for equality of a substring with another string.
Definition: ncbistr.hpp:5384
void Stop(void)
Suspend the timer.
Definition: ncbitime.hpp:2792
string AsSmartString(CTimeSpan::ESmartStringPrecision precision, ERound rounding, CTimeSpan::ESmartStringZeroMode zero_mode=CTimeSpan::eSSZ_SkipZero) const
Transform elapsed time to "smart" string.
Definition: ncbitime.hpp:2850
void Start(void)
Start the timer.
Definition: ncbitime.hpp:2764
@ eSSP_Millisecond
Definition: ncbitime.hpp:1511
static const char label[]
TField_id GetField_id(void) const
Get the Field_id member data.
const TColumns & GetColumns(void) const
Get the Columns member data.
Definition: Seq_table_.hpp:433
bool IsSetFeat_subtype(void) const
subtype of features in this table, defined in header SeqFeatData.hpp Check if a value has been assign...
Definition: Seq_table_.hpp:327
bool CanGetField_name(void) const
Check if it is safe to call GetField_name method.
TFeat_subtype GetFeat_subtype(void) const
Get the Feat_subtype member data.
Definition: Seq_table_.hpp:346
vector< CRef< CSeqTable_column > > TColumns
Definition: Seq_table_.hpp:92
const TField_name & GetField_name(void) const
Get the Field_name member data.
bool CanGetField_id(void) const
Check if it is safe to call GetField_id method.
const Tdata & Get(void) const
Get the member data.
const TInst & GetInst(void) const
Get the Inst member data.
Definition: Bioseq_.hpp:336
list< CRef< CSeq_align > > TAlign
Definition: Seq_annot_.hpp:194
const TDesc & GetDesc(void) const
Get the Desc member data.
Definition: Seq_annot_.hpp:852
bool IsSetDesc(void) const
used only for stand alone Seq-annots Check if a value has been assigned to Desc data member.
Definition: Seq_annot_.hpp:840
TMol GetMol(void) const
Get the Mol member data.
Definition: Seq_inst_.hpp:612
const TAlign & GetAlign(void) const
Get the variant data.
Definition: Seq_annot_.hpp:641
static string SelectionName(E_Choice index)
Retrieve selection name (for diagnostic purposes).
Definition: Seq_annot_.cpp:143
const TSeq_table & GetSeq_table(void) const
Get the variant data.
Definition: Seq_annot_.cpp:153
const TFtable & GetFtable(void) const
Get the variant data.
Definition: Seq_annot_.hpp:621
list< CRef< CSeq_feat > > TFtable
Definition: Seq_annot_.hpp:193
bool IsFtable(void) const
Check if variant Ftable is selected.
Definition: Seq_annot_.hpp:615
const TData & GetData(void) const
Get the Data member data.
Definition: Seq_annot_.hpp:873
E_Choice Which(void) const
Which variant is currently selected.
Definition: Seq_annot_.hpp:586
list< CRef< CAnnotdesc > > Tdata
@ eMol_na
just a nucleic acid
Definition: Seq_inst_.hpp:113
static CStopWatch sw
int i
static MDB_envinfo info
Definition: mdb_load.c:37
const size_t kChunkSize
Definition: na_utils.cpp:587
USING_SCOPE(objects)
EAlignType
Definition: na_utils.cpp:68
@ fAlign_DNA
Definition: na_utils.cpp:69
@ fAlign_Protein
Definition: na_utils.cpp:70
@ fAlign_Mixed
Definition: na_utils.cpp:71
@ fAlign_Invalid
Definition: na_utils.cpp:72
static const int kRetMax
Definition: na_utils.cpp:55
DEFINE_CLASS_STATIC_FAST_MUTEX(CNAUtils::sm_NAAtoUidCacheMutex)
static string s_MakeUidtoGiCacheKey(TEntrezId uid, CNAUtils::EEntrezDB eedb)
Definition: na_utils.cpp:1091
static const char * kSnpSubtypeStr
Definition: na_utils.cpp:56
static string s_EEDBToString(CNAUtils::EEntrezDB eedb)
Definition: na_utils.cpp:756
static bool s_MatchHeaders(const char **header_names, const set< string > &headers)
Definition: na_utils.cpp:241
static string s_GetFeatSubtypeStr(int subtype)
Definition: na_utils.cpp:142
constexpr auto sort(_Init &&init)
constexpr bool empty(list< Ts... >) noexcept
const struct ncbi::grid::netcache::search::fields::SIZE size
const struct ncbi::grid::netcache::search::fields::SUBKEY subkey
The Object manager core.
#define row(bind, expected)
Definition: string_bind.c:73
SAnnotSelector –.
Definition: type.c:6
#define _ASSERT
#define ftable
Definition: utilfeat.h:37
static CS_CONTEXT * context
Definition: will_convert.c:21
Modified on Mon May 13 04:32:18 2024 by modify_doxy.py rev. 669887