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

Go to the SVN repository for this file.

1 /* $Id: taxon1.cpp 99233 2023-03-01 16:19:54Z ucko $
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: Vladimir Soussov, Michael Domrachev
27  *
28  * File Description:
29  * NCBI Taxonomy information retreival library implementation
30  *
31  */
32 
33 #include <ncbi_pch.hpp>
34 #include <corelib/ncbistr.hpp>
38 #include <serial/serial.hpp>
39 #include <serial/enumvalues.hpp>
40 #include <serial/objistr.hpp>
41 #include <serial/objostr.hpp>
42 
43 #include <algorithm>
44 
45 #include "cache.hpp"
46 
47 
48 #define NCBI_USE_ERRCODE_X Objects_Taxonomy
49 
50 
52 BEGIN_objects_SCOPE // namespace ncbi::objects::
53 
54 
55 static const char s_achInvalTaxid[] = "Invalid tax id specified";
56 
57 #define TAXON1_IS_INITED (m_pServer!=NULL)
58 
59 
61  : m_pServer(NULL),
62  m_pOut(NULL),
63  m_pIn(NULL),
64  m_plCache(NULL),
65  m_bWithSynonyms(false)
66 {
67  return;
68 }
69 
70 
72 {
73  Fini();
74 }
75 
76 
77 void
79 {
81  delete m_pIn;
82  delete m_pOut;
83  delete m_pServer;
84  m_pIn = NULL;
85  m_pOut = NULL;
86  m_pServer = NULL;
87  delete m_plCache;
88  m_plCache = NULL;
89 }
90 
91 //---------------------------------------------
92 // Taxon1 server init
93 // Returns: TRUE - OK
94 // FALSE - Can't open connection to taxonomy service
95 ///
96 // default: 10 sec timeout, 5 reconnect attempts,
97 // cache for 1000 org-refs
98 static const STimeout def_timeout = { 10, 0 };
99 
100 bool
102 {
104 }
105 
106 bool
107 CTaxon1::Init(unsigned cache_capacity)
108 {
109  return CTaxon1::Init(&def_timeout, def_reconnect_attempts, cache_capacity);
110 }
111 
112 bool
113 CTaxon1::Init(const STimeout* timeout, unsigned reconnect_attempts, unsigned cache_capacity)
114 {
116  if( TAXON1_IS_INITED ) { // Already inited
117  SetLastError( "ERROR: Init(): Already initialized" );
118  return false;
119  }
120  SConnNetInfo* pNi = NULL;
121 
122  try {
123  // Open connection to Taxonomy service
124  CTaxon1_req req;
125  CTaxon1_resp resp;
126 
127  if ( timeout ) {
128  m_timeout_value = *timeout;
130  } else {
131  m_timeout = 0;
132  }
133 
134  m_nReconnectAttempts = reconnect_attempts;
135  m_pchService = "TaxService4";
136  const char* tmp;
137  if( ( (tmp=getenv("NI_TAXONOMY_SERVICE_NAME")) != NULL ) ||
138  ( (tmp=getenv("NI_SERVICE_NAME_TAXONOMY")) != NULL ) ) {
139  m_pchService = tmp;
140  }
141  unique_ptr<CConn_ServiceStream> pServer;
142  unique_ptr<CObjectOStream> pOut;
143  unique_ptr<CObjectIStream> pIn;
145  if( pNi == NULL ) {
146  SetLastError( "ERROR: Init(): Unable to create net info" );
147  return false;
148  }
149  pNi->max_try = reconnect_attempts + 1;
150  ConnNetInfo_SetTimeout( pNi, timeout );
151 
152  pServer.reset( new CConn_ServiceStream(m_pchService, fSERV_Any,
153  pNi, 0, m_timeout) );
154  ConnNetInfo_Destroy( pNi );
155  pNi = NULL;
156 
157 #ifdef USE_TEXT_ASN
159 #else
161 #endif
162  pOut.reset( CObjectOStream::Open(m_eDataFormat, *pServer) );
163  pIn.reset( CObjectIStream::Open(m_eDataFormat, *pServer) );
164  pOut->FixNonPrint(eFNP_Allow);
165  pIn->FixNonPrint(eFNP_Allow);
166 
167  req.SetInit();
168 
169  m_pServer = pServer.release();
170  m_pIn = pIn.release();
171  m_pOut = pOut.release();
172 
173  if( SendRequest( req, resp ) ) {
174  if( resp.IsInit() ) {
175  // Init is done
176  m_plCache = new COrgRefCache( *this );
177  if( m_plCache->Init( cache_capacity ) ) {
178  return true;
179  }
180  delete m_plCache;
181  m_plCache = NULL;
182  } else { // Set error
183  SetLastError( "INTERNAL: TaxService response type is not Init" );
184  }
185  }
186  } catch( exception& e ) {
187  SetLastError( e.what() );
188  }
189  // Clean up streams
190  delete m_pIn;
191  delete m_pOut;
192  delete m_pServer;
193  m_pIn = NULL;
194  m_pOut = NULL;
195  m_pServer = NULL;
196  if( pNi ) {
197  ConnNetInfo_Destroy( pNi );
198  }
199  return false;
200 }
201 
202 void
204 {
206  if( TAXON1_IS_INITED ) {
207  CTaxon1_req req;
208  CTaxon1_resp resp;
209 
210  req.SetFini();
211 
212  if( SendRequest( req, resp, false ) ) {
213  if( !resp.IsFini() ) {
214  SetLastError( "INTERNAL: TaxService response type is not Fini" );
215  }
216  }
217  }
218  Reset();
219 }
220 
221 //---------------------------------------------
222 // Get organism data (including org-ref) by tax_id
223 // Returns: pointer to Taxon2Data if organism exists
224 // NULL - if tax_id wrong
225 //
226 // NOTE:
227 // Caller gets own copy of Taxon2Data structure.
228 ///
231 {
233  if( !TAXON1_IS_INITED ) {
234  if( !Init() ) {
235  return CRef<CTaxon2_data>(NULL);
236  }
237  }
238  if( tax_id > ZERO_TAX_ID ) {
239  // Check if this taxon is in cache
240  CTaxon2_data* pData = 0;
241  if( m_plCache->LookupAndInsert( tax_id, &pData ) && pData ) {
242  CTaxon2_data* pNewData = new CTaxon2_data();
243 
244  SerialAssign<CTaxon2_data>( *pNewData, *pData );
245 
246  return CRef<CTaxon2_data>(pNewData);
247  }
248  } else {
250  }
251  return CRef<CTaxon2_data>(NULL);
252 }
253 
254 static bool
256 {
257  switch( val.Which() ) {
258  case CObject_id::e_Id:
259  return val.GetId() != 0;
260  case CObject_id::e_Str:
261  try {
262  return NStr::StringToBool( val.GetStr().c_str() );
263  } catch(...) { return false; }
264  default:
265  return false;
266  }
267 }
268 
269 
272 {
273  TOrgRefStatus result = 0;
274  COrg_ref& org = data.SetOrg();
275  // Copy dbtags from org to inp_orgRef
276  for( COrg_ref::TDb::iterator i = org.SetDb().begin(); i != org.SetDb().end(); ) {
277  if( (*i)->GetDb() != "taxon" ) {
278  if( NStr::StartsWith( (*i)->GetDb(), "taxlookup" ) ) {
279  // convert taxlookup to status or refresh flags
280  if( NStr::EndsWith( (*i)->GetDb(), "-changed" ) ) { // refresh flag
281  if( NStr::Equal( (*i)->GetDb(), "taxlookup%status-changed" ) &&
282  (*i)->IsSetTag() && (*i)->GetTag().IsId() ) {
283  result = (*i)->GetTag().GetId();
284  } else {
285  if( NStr::Equal( (*i)->GetDb(), "taxlookup?taxid-changed" ) &&
286  (*i)->IsSetTag() && s_GetBoolValue((*i)->GetTag()) ) {
288  } else if( NStr::Equal( (*i)->GetDb(), "taxlookup?taxname-changed" ) &&
289  (*i)->IsSetTag() && s_GetBoolValue((*i)->GetTag()) ) {
291  } else if( NStr::Equal( (*i)->GetDb(), "taxlookup?common-changed" ) &&
292  (*i)->IsSetTag() && s_GetBoolValue((*i)->GetTag()) ) {
294  } else if( NStr::Equal( (*i)->GetDb(), "taxlookup?orgname-changed" ) &&
295  (*i)->IsSetTag() && s_GetBoolValue((*i)->GetTag()) ) {
297  } else if( NStr::Equal( (*i)->GetDb(), "taxlookup?division-changed" ) &&
298  (*i)->IsSetTag() && s_GetBoolValue((*i)->GetTag()) ) {
300  } else if( NStr::Equal( (*i)->GetDb(), "taxlookup?lineage-changed" ) &&
301  (*i)->IsSetTag() && s_GetBoolValue((*i)->GetTag()) ) {
303  } else if( NStr::Equal( (*i)->GetDb(), "taxlookup?gc-changed" ) &&
304  (*i)->IsSetTag() && s_GetBoolValue((*i)->GetTag()) ) {
306  } else if( NStr::Equal( (*i)->GetDb(), "taxlookup?mgc-changed" ) &&
307  (*i)->IsSetTag() && s_GetBoolValue((*i)->GetTag()) ) {
309  } else if( NStr::Equal( (*i)->GetDb(), "taxlookup?orgmod-changed" ) &&
310  (*i)->IsSetTag() && s_GetBoolValue((*i)->GetTag()) ) {
312  } else if( NStr::Equal( (*i)->GetDb(), "taxlookup?pgc-changed" ) &&
313  (*i)->IsSetTag() && s_GetBoolValue((*i)->GetTag()) ) {
315  } else if( NStr::Equal( (*i)->GetDb(), "taxlookup?orgrefmod-changed" ) &&
316  (*i)->IsSetTag() && s_GetBoolValue((*i)->GetTag()) ) {
318  } else if( NStr::Equal( (*i)->GetDb(), "taxlookup?orgnameattr-changed" ) &&
319  (*i)->IsSetTag() && s_GetBoolValue((*i)->GetTag()) ) {
321  }
322  }
323  } else { // status flag
324  if( NStr::Equal( (*i)->GetDb(), "taxlookup?is_species_level" ) &&
325  (*i)->IsSetTag() ) {
326  data.SetIs_species_level( s_GetBoolValue((*i)->GetTag()) );
327  } else if( NStr::Equal( (*i)->GetDb(), "taxlookup?is_uncultured" ) &&
328  (*i)->IsSetTag() ) {
329  data.SetIs_uncultured( s_GetBoolValue((*i)->GetTag()) );
330  } else if( NStr::EqualNocase( (*i)->GetDb(), "taxlookup$blast_lineage" ) &&
331  (*i)->IsSetTag() && (*i)->GetTag().IsStr() ) {
332  list< string > lBlastNames;
333  NStr::Split( (*i)->GetTag().GetStr(), ";", lBlastNames, NStr::fSplit_Tokenize );
334  NON_CONST_ITERATE( list< string >, i, lBlastNames ) {
336  }
337  lBlastNames.reverse();
338  data.SetBlast_name().insert( data.SetBlast_name().end(),
339  lBlastNames.begin(), lBlastNames.end() );
340  } else {
341  string sPropName = (*i)->GetDb().substr( strlen( "taxlookup?" ) );
342  switch( (*i)->GetTag().Which() ) {
343  case CObject_id::e_Str: data.SetProperty( sPropName, (*i)->GetTag().GetStr() ); break;
344  case CObject_id::e_Id: data.SetProperty( sPropName, (*i)->GetTag().GetId() ); break;
345  default: break; // unknown type
346  }
347  }
348  }
349  i = org.SetDb().erase(i);
350  } else {
351  ++i;
352  }
353  } else {
354  ++i;
355  }
356  }
357 
358  // Set flags to default values if corresponding property is not found
359  if( !data.IsSetIs_uncultured() ) {
360  data.SetIs_uncultured( false );
361  }
362  if( !data.IsSetIs_species_level() ) {
363  data.SetIs_species_level( false );
364  }
365  return result;
366 }
367 
368 //----------------------------------------------
369 // Get organism data by OrgRef
370 // Returns: pointer to Taxon2Data if organism exists
371 // NULL - if no such organism in taxonomy database
372 //
373 // NOTE:
374 // 1. These functions uses the following data from inp_orgRef to find
375 // organism in taxonomy database. It uses taxname first. If no organism
376 // was found (or multiple nodes found) then it tries to find organism
377 // using common name. If nothing found, then it tries to find organism
378 // using synonyms. Lookup never uses tax_id to find organism.
379 // 2. LookupMerge function modifies given OrgRef to correspond to the
380 // found one and returns constant pointer to the Taxon2Data structure
381 // stored internally.
382 ///
384 CTaxon1::Lookup(const COrg_ref& inp_orgRef, string* psLog)
385 {
387  if( !TAXON1_IS_INITED ) {
388  if( !Init() ) {
389  return CRef<CTaxon2_data>(NULL);
390  }
391  }
392  // Check if this taxon is in cache
393  CRef<CTaxon2_data> pData( 0 );
394 
396 
397  CTaxon1_req req;
398  CTaxon1_resp resp;
399 
400  SerialAssign< COrg_ref >( req.SetLookup(), inp_orgRef );
401  // Set version db tag
402  COrgrefProp::SetOrgrefProp( req.SetLookup(), "version", 2 );
403  if( m_bWithSynonyms ) {
405  }
406  if( psLog ) {
407  COrgrefProp::SetOrgrefProp( req.SetLookup(), "log", true );
408  }
409 
410  if( SendRequest( req, resp ) ) {
411  if( resp.IsLookup() ) {
412  // Correct response, return object
413  pData.Reset( new CTaxon2_data() );
414 
415  SerialAssign< COrg_ref >( pData->SetOrg(), resp.GetLookup().GetOrg() );
416  x_ConvertOrgrefProps( *pData );
417  if( psLog ) {
418  pData->GetProperty( "log", *psLog );
419  }
420  } else { // Internal: wrong respond type
421  SetLastError( "INTERNAL: TaxService response type is not Lookup" );
422  }
423  }
424 
425  return pData;
426 }
427 
429 CTaxon1::LookupMerge(COrg_ref& inp_orgRef, string* psLog, TOrgRefStatus* pStatusOut)
430 {
431  //CTaxon2_data* pData = 0;
432 
434  if( !TAXON1_IS_INITED ) {
435  if( !Init() ) {
437  }
438  }
439  // Check if this taxon is in cache
440  CRef<CTaxon2_data> pData( 0 );
441 
443 
444  CTaxon1_req req;
445  CTaxon1_resp resp;
446 
447  SerialAssign< COrg_ref >( req.SetLookup(), inp_orgRef );
448  // Set version db tag
449  COrgrefProp::SetOrgrefProp( req.SetLookup(), "version", 2 );
450  COrgrefProp::SetOrgrefProp( req.SetLookup(), "merge", true );
452  if( psLog ) {
453  COrgrefProp::SetOrgrefProp( req.SetLookup(), "log", true );
454  }
455  if( SendRequest( req, resp ) ) {
456  if( resp.IsLookup() ) {
457  // Correct response, return object
458  pData.Reset( new CTaxon2_data() );
459 
460  SerialAssign< COrg_ref >( pData->SetOrg(), resp.GetLookup().GetOrg() );
461  TOrgRefStatus stat_out = x_ConvertOrgrefProps( *pData );
462  if( pStatusOut ) {
463  *pStatusOut = stat_out;
464  }
465  if( psLog ) {
466  pData->GetProperty( "log", *psLog );
467  }
468  SerialAssign< COrg_ref >( inp_orgRef, pData->GetOrg() );
469 
470  } else { // Internal: wrong respond type
471  SetLastError( "INTERNAL: TaxService response type is not Lookup" );
472  }
473  }
474 
475  return CConstRef<CTaxon2_data>(pData);
476 }
477 
478 //-----------------------------------------------
479 // Get tax_id by OrgRef
480 // Returns: tax_id - if organism found
481 // 0 - no organism found
482 // -1 - error during processing occured
483 // -tax_id - if multiple nodes found
484 // (where tax_id > 1 is id of one of the nodes)
485 // NOTE:
486 // This function uses the same information from inp_orgRef as Lookup
487 ///
488 TTaxId
490 {
492  if( !TAXON1_IS_INITED ) {
493  if( !Init() ) {
494  return INVALID_TAX_ID;
495  }
496  }
497 
498  CTaxon1_req req;
499  CTaxon1_resp resp;
500 
501  SerialAssign< COrg_ref >( req.SetGetidbyorg(), inp_orgRef );
502 
503  if( SendRequest( req, resp ) ) {
504  if( resp.IsGetidbyorg() ) {
505  // Correct response, return object
506  return TAX_ID_FROM(int, resp.GetGetidbyorg());
507  } else { // Internal: wrong respond type
508  SetLastError( "INTERNAL: TaxService response type is not Getidbyorg" );
509  }
510  }
511  return ZERO_TAX_ID;
512 }
513 
514 //----------------------------------------------
515 // Get tax_id by organism name
516 // Returns: tax_id - if organism found
517 // 0 - no organism found
518 // -1 - error during processing occured
519 // -tax_id - if multiple nodes found
520 // (where tax_id > 1 is id of one of the nodes)
521 ///
522 TTaxId
523 CTaxon1::GetTaxIdByName(const string& orgname)
524 {
526  if( orgname.empty() )
527  return ZERO_TAX_ID;
528  list< CRef< CTaxon1_name > > lNames;
529  TTaxId retc = SearchTaxIdByName(orgname, eSearch_Exact, &lNames);
530  switch(TAX_ID_TO(TIntId, retc) ) {
531  case -2: retc = INVALID_TAX_ID; break;
532  case -1: retc = -lNames.front()->GetTaxid(); break; // Multiple nodes found, get first taxid
533  default: break;
534  }
535 
536  return retc;
537 }
538 
539 //----------------------------------------------
540 // Get tax_id by organism "unique" name
541 // Returns: tax_id - if organism found
542 // 0 - no organism found
543 // -1 - error during processing occured
544 // -tax_id - if multiple nodes found
545 // (where tax_id > 1 is id of one of the nodes)
546 ///
547 TTaxId
548 CTaxon1::FindTaxIdByName(const string& orgname)
549 {
551  if( !TAXON1_IS_INITED ) {
552  if( !Init() ) {
553  return INVALID_TAX_ID;
554  }
555  }
556  if( orgname.empty() )
557  return ZERO_TAX_ID;
558 
559  TTaxId id( GetTaxIdByName(orgname) );
560 
561  if(id < TAX_ID_CONST(1)) {
562 
563  TTaxId idu = ZERO_TAX_ID;
564 
565  CTaxon1_req req;
566  CTaxon1_resp resp;
567 
568  req.SetGetunique().assign( orgname );
569 
570  if( SendRequest( req, resp ) ) {
571  if( resp.IsGetunique() ) {
572  // Correct response, return object
573  idu = resp.GetGetunique();
574  } else { // Internal: wrong respond type
575  SetLastError( "INTERNAL: TaxService response type is not Getunique" );
576  }
577  }
578 
579  if( idu > ZERO_TAX_ID )
580  id= idu;
581  }
582  return id;
583 }
584 
585 //----------------------------------------------
586 // Get tax_id by organism name using fancy search modes. If given a pointer
587 // to the list of names then it'll return all found names (one name per
588 // tax id). Previous content of name_list_out will be destroyed.
589 // Returns: tax_id - if organism found
590 // 0 - no organism found
591 // -1 - if multiple nodes found
592 // -2 - error during processing occured
593 ///
594 TTaxId
595 CTaxon1::SearchTaxIdByName(const string& orgname, ESearch mode,
596  list< CRef< CTaxon1_name > >* pNameList)
597 {
598  // Use fancy searches
600  if( !TAXON1_IS_INITED ) {
601  if( !Init() ) {
602  return TAX_ID_CONST(-2);
603  }
604  }
605  if( orgname.empty() ) {
606  return ZERO_TAX_ID;
607  }
608  CRef< CTaxon1_info > pQuery( new CTaxon1_info() );
609  int nMode = 0;
610  switch( mode ) {
611  default:
612  case eSearch_Exact: nMode = 0; break;
613  case eSearch_TokenSet: nMode = 1; break;
614  case eSearch_WildCard: nMode = 2; break; // shell-style wildcards, i.e. *,?,[]
615  case eSearch_Phonetic: nMode = 3; break;
616  }
617  pQuery->SetIval1( nMode );
618  pQuery->SetIval2( 0 );
619  pQuery->SetSval( orgname );
620 
621  CTaxon1_req req;
622  CTaxon1_resp resp;
623 
624  req.SetSearchname( *pQuery );
625 
626  if( SendRequest( req, resp ) ) {
627  if( resp.IsSearchname() ) {
628  // Correct response, return object
629  TTaxId retc = ZERO_TAX_ID;
630  const CTaxon1_resp::TSearchname& lNm = resp.GetSearchname();
631  if( lNm.size() == 0 ) {
632  retc = ZERO_TAX_ID;
633  } else if( lNm.size() == 1 ) {
634  retc = lNm.front()->GetTaxid();
635  } else {
636  retc = INVALID_TAX_ID;
637  }
638  // Fill the names list
639  if( pNameList ) {
640  pNameList->swap( resp.SetSearchname() );
641  }
642  return retc;
643  } else { // Internal: wrong respond type
644  SetLastError( "INTERNAL: TaxService response type is not Searchname" );
645  return TAX_ID_CONST(-2);
646  }
647  } else if( GetLastError().find("Nothing found") != string::npos ) {
648  return ZERO_TAX_ID;
649  }
650  return TAX_ID_CONST(-2);
651 }
652 
653 //----------------------------------------------
654 // Get ALL tax_id by organism name
655 // Returns: number of organisms found (negative value on error),
656 // id list appended with found tax ids
657 ///
658 int
659 CTaxon1::GetAllTaxIdByName(const string& orgname, TTaxIdList& lIds)
660 {
661  int count = 0;
662 
664  if( !TAXON1_IS_INITED ) {
665  if( !Init() ) {
666  return -2;
667  }
668  }
669  if( orgname.empty() )
670  return 0;
671 
672  CTaxon1_req req;
673  CTaxon1_resp resp;
674 
675  req.SetFindname().assign(orgname);
676 
677  if( SendRequest( req, resp ) ) {
678  if( resp.IsFindname() ) {
679  // Correct response, return object
680  const list< CRef< CTaxon1_name > >& lNm = resp.GetFindname();
681  // Fill in the list
682  for( list< CRef< CTaxon1_name > >::const_iterator
683  i = lNm.begin();
684  i != lNm.end(); ++i, ++count )
685  lIds.push_back( (*i)->GetTaxid() );
686  } else { // Internal: wrong respond type
687  SetLastError( "INTERNAL: TaxService response type is not Findname" );
688  return 0;
689  }
690  }
691  return count;
692 }
693 
694 //----------------------------------------------
695 // Get organism by tax_id
696 // Returns: pointer to OrgRef structure if organism found
697 // NULL - if no such organism in taxonomy database or error occured
698 // (check GetLastError() for the latter)
699 // NOTE:
700 // This function does not make a copy of OrgRef structure but returns
701 // pointer to internally stored OrgRef.
702 ///
705  bool& is_species,
706  bool& is_uncultured,
707  string& blast_name,
708  bool* is_specified)
709 {
711  if( !TAXON1_IS_INITED ) {
712  if( !Init() ) {
713  return null;
714  }
715  }
716  if( tax_id > ZERO_TAX_ID ) {
717  CTaxon2_data* pData = 0;
718  if( m_plCache->LookupAndInsert( tax_id, &pData ) && pData ) {
719  is_species = pData->GetIs_species_level();
720  is_uncultured = pData->GetIs_uncultured();
721  if( pData->IsSetBlast_name() && pData->GetBlast_name().size() > 0 ) {
722  blast_name.assign( pData->GetBlast_name().front() );
723  }
724  if( is_specified ) {
725  //*is_specified = pData->GetOrg().GetOrgname().IsFormalName();
726  bool specified = false;
727  if( GetNodeProperty( tax_id, "specified_inh", specified ) ) {
728  *is_specified = specified;
729  } else {
730  return null;
731  }
732  }
733  return CConstRef<COrg_ref>(&pData->GetOrg());
734  }
735  }
736  return null;
737 }
738 
739 //---------------------------------------------
740 // Set mode for synonyms in OrgRef
741 // Returns: previous mode
742 // NOTE:
743 // Default value: false (do not copy synonyms to the new OrgRef)
744 ///
745 bool
747 {
749  bool old_val( m_bWithSynonyms );
750  m_bWithSynonyms = on_off;
751  return old_val;
752 }
753 
754 //---------------------------------------------
755 // Get parent tax_id
756 // Returns: tax_id of parent node or 0 if error
757 // NOTE:
758 // Root of the tree has tax_id of 1
759 ///
760 TTaxId
762 {
763  CTaxon1Node* pNode = 0;
765  if( !TAXON1_IS_INITED ) {
766  if( !Init() ) {
767  return ZERO_TAX_ID;
768  }
769  }
770  if( m_plCache->LookupAndAdd( id_tax, &pNode )
771  && pNode && pNode->GetParent() ) {
772  return pNode->GetParent()->GetTaxId();
773  }
774  return ZERO_TAX_ID;
775 }
776 
777 //---------------------------------------------
778 // Get species tax_id (id_tax should be below species).
779 // There are 2 species search modes: one based solely on node rank and
780 // another based on the flag is_species returned in the Taxon2_data
781 // structure.
782 // Returns: tax_id of species node (> 1)
783 // or 0 if no species above (maybe id_tax above species)
784 // or -1 if error
785 // NOTE:
786 // Root of the tree has tax_id of 1
787 ///
788 TTaxId
790 {
791  CTaxon1Node* pNode = 0;
793  if( !TAXON1_IS_INITED ) {
794  if( !Init() ) {
795  return INVALID_TAX_ID;
796  }
797  }
798  if( m_plCache->LookupAndAdd( id_tax, &pNode )
799  && pNode && m_plCache->InitRanks() ) {
800  if( mode == eSpeciesMode_RankOnly ) {
801  TTaxRank species_rank(m_plCache->GetSpeciesRank());
802  while( !pNode->IsRoot() ) {
803  TTaxRank rank( pNode->GetRank() );
804  if( rank == species_rank )
805  return pNode->GetTaxId();
806  if( (rank > 0) && (rank < species_rank))
807  return ZERO_TAX_ID;
808  pNode = pNode->GetParent();
809  }
810  return ZERO_TAX_ID;
811  } else { // Based on flag
812  CTaxon1Node* pResult = NULL;
813  CTaxon2_data* pData = NULL;
814  while( !pNode->IsRoot() ) {
815  if( m_plCache->LookupAndInsert( pNode->GetTaxId(), &pData ) ) {
816  if( !pData )
817  return INVALID_TAX_ID;
818  if( !(pData->IsSetIs_species_level() && pData->GetIs_species_level()) ) {
819  if( pResult ) {
820  return pResult->GetTaxId();
821  } else {
822  return ZERO_TAX_ID;
823  }
824  }
825  pResult = pNode;
826  pNode = pNode->GetParent();
827  } else { // Node in the lineage not found
828  return INVALID_TAX_ID;
829  }
830  }
831  }
832  }
833  return INVALID_TAX_ID;
834 }
835 
836 //---------------------------------------------
837 // Get genus tax_id (id_tax should be below genus)
838 // Returns: tax_id of genus or
839 // 0 - no genus in the lineage
840 // -1 - if error
841 ///
842 TTaxId
844 {
845  CTaxon1Node* pNode = 0;
847  if( !TAXON1_IS_INITED ) {
848  if( !Init() ) {
849  return INVALID_TAX_ID;
850  }
851  }
852  if( m_plCache->LookupAndAdd( id_tax, &pNode )
853  && pNode && m_plCache->InitRanks() ) {
854  TTaxRank genus_rank(m_plCache->GetGenusRank());
855  while( !pNode->IsRoot() ) {
856  TTaxRank rank( pNode->GetRank() );
857  if( rank == genus_rank )
858  return pNode->GetTaxId();
859  if( (rank > 0) && (rank < genus_rank))
860  return ZERO_TAX_ID;
861  pNode = pNode->GetParent();
862  }
863  return ZERO_TAX_ID;
864  }
865  return INVALID_TAX_ID;
866 }
867 
868 //---------------------------------------------
869 // Get superkingdom tax_id (id_tax should be below superkingdom)
870 // Returns: tax_id of superkingdom or
871 // 0 - no superkingdom in the lineage
872 // -1 - if error
873 ///
874 TTaxId
876 {
877  CTaxon1Node* pNode = 0;
879  if( !TAXON1_IS_INITED ) {
880  if( !Init() ) {
881  return INVALID_TAX_ID;
882  }
883  }
884  if( m_plCache->LookupAndAdd( id_tax, &pNode )
885  && pNode && m_plCache->InitRanks() ) {
887  while( !pNode->IsRoot() ) {
888  TTaxRank rank( pNode->GetRank() );
889  if( rank == sk_rank )
890  return pNode->GetTaxId();
891  if( (rank > 0) && (rank < sk_rank))
892  return ZERO_TAX_ID;
893  pNode = pNode->GetParent();
894  }
895  return ZERO_TAX_ID;
896  }
897  return INVALID_TAX_ID;
898 }
899 
900 //---------------------------------------------
901 // Get ancestor tax_id by rank name
902 // rank name might be one of:
903 // no rank
904 // superkingdom
905 // kingdom
906 // subkingdom
907 // superphylum
908 // phylum
909 // subphylum
910 // superclass
911 // class
912 // subclass
913 // infraclass
914 // cohort
915 // subcohort
916 // superorder
917 // order
918 // suborder
919 // infraorder
920 // parvorder
921 // superfamily
922 // family
923 // subfamily
924 // tribe
925 // subtribe
926 // genus
927 // subgenus
928 // species group
929 // species subgroup
930 // species
931 // subspecies
932 // varietas
933 // forma
934 //
935 // Returns: tax_id of properly ranked accessor or
936 // 0 - no such rank in the lineage
937 // -1 - tax id is not found
938 // -2 - invalid rank name
939 // -3 - any other error (use GetLastError for details)
940 ///
941 TTaxId
942 CTaxon1::GetAncestorByRank(TTaxId id_tax, const char* rank_name)
943 {
945  if( !TAXON1_IS_INITED ) {
946  if( !Init() ) {
947  return TAX_ID_CONST(-3);
948  }
949  }
950  if( rank_name ) {
951  TTaxRank rank( m_plCache->FindRankByName( rank_name ) );
952  if( rank != -1000 ) {
953  return GetAncestorByRank(id_tax, rank);
954  }
955  }
956  SetLastError( "rank not found" );
957  ERR_POST_X( 2, GetLastError() );
958  return TAX_ID_CONST(-2);
959 }
960 
961 TTaxId
963 {
964  CTaxon1Node* pNode = 0;
966  if( !TAXON1_IS_INITED ) {
967  if( !Init() ) {
968  return TAX_ID_CONST(-3);
969  }
970  }
971  if( m_plCache->LookupAndAdd( id_tax, &pNode )
972  && pNode ) {
973  while( !pNode->IsRoot() ) {
974  TTaxRank rank( pNode->GetRank() );
975  if( rank == rank_id )
976  return pNode->GetTaxId();
977  if( (rank >= 0) && (rank < rank_id))
978  return ZERO_TAX_ID;
979  pNode = pNode->GetParent();
980  }
981  return ZERO_TAX_ID;
982  }
983  return INVALID_TAX_ID;
984 }
985 
986 //---------------------------------------------
987 // Get taxids for all children of specified node.
988 // Returns: number of children, id list appended with found tax ids
989 // -1 - in case of error
990 ///
991 int
992 CTaxon1::GetChildren(TTaxId id_tax, TTaxIdList& children_ids)
993 {
994  int count(0);
995  CTaxon1Node* pNode = 0;
997  if( !TAXON1_IS_INITED ) {
998  if( !Init() ) {
999  return -1;
1000  }
1001  }
1002  if( m_plCache->LookupAndAdd( id_tax, &pNode )
1003  && pNode ) {
1004 
1005  CTaxon1_req req;
1006  CTaxon1_resp resp;
1007 
1008  req.SetTaxachildren(TAX_ID_TO(int, id_tax) );
1009 
1010  if( SendRequest( req, resp ) ) {
1011  if( resp.IsTaxachildren() ) {
1012  // Correct response, return object
1013  list< CRef< CTaxon1_name > >& lNm = resp.SetTaxachildren();
1014  // Fill in the list
1016  pIt->GoNode( pNode );
1017  for( list< CRef< CTaxon1_name > >::const_iterator
1018  i = lNm.begin();
1019  i != lNm.end(); ++i, ++count ) {
1020  children_ids.push_back( (*i)->GetTaxid() );
1021  // Add node to the partial tree
1022  CTaxon1Node* pNewNode = new CTaxon1Node(*i);
1023  m_plCache->SetIndexEntry(TAX_ID_TO(int, pNewNode->GetTaxId()), pNewNode);
1024  pIt->AddChild( pNewNode );
1025  }
1026  } else { // Internal: wrong respond type
1027  SetLastError( "INTERNAL: TaxService response type is not Taxachildren" );
1028  return 0;
1029  }
1030  }
1031  }
1032  return count;
1033 }
1034 
1035 bool
1036 CTaxon1::GetGCName(TTaxGeneticCode gc_id, string& gc_name_out )
1037 {
1038  SetLastError(NULL);
1039  if( !TAXON1_IS_INITED ) {
1040  if( !Init() ) {
1041  return false;
1042  }
1043  }
1044  if( m_gcStorage.empty() ) {
1045  CTaxon1_req req;
1046  CTaxon1_resp resp;
1047 
1048  req.SetGetgcs();
1049 
1050  if( SendRequest( req, resp ) ) {
1051  if( resp.IsGetgcs() ) {
1052  // Correct response, return object
1053  const list< CRef< CTaxon1_info > >& lGc = resp.GetGetgcs();
1054  // Fill in storage
1055  for( list< CRef< CTaxon1_info > >::const_iterator
1056  i = lGc.begin();
1057  i != lGc.end(); ++i ) {
1058  m_gcStorage.insert( TGCMap::value_type((*i)->GetIval1(),
1059  (*i)->GetSval()) );
1060  }
1061  } else { // Internal: wrong respond type
1062  SetLastError( "INTERNAL: TaxService response type is not Getgcs" );
1063  return false;
1064  }
1065  }
1066  }
1067  TGCMap::const_iterator gci( m_gcStorage.find( gc_id ) );
1068  if( gci != m_gcStorage.end() ) {
1069  gc_name_out.assign( gci->second );
1070  return true;
1071  } else {
1072  SetLastError( "ERROR: GetGCName(): Unknown genetic code" );
1073  return false;
1074  }
1075 }
1076 
1077 //---------------------------------------------
1078 // Get taxonomic rank name by rank id
1079 ///
1080 bool
1081 CTaxon1::GetRankName(TTaxRank rank_id, string& rank_name_out )
1082 {
1083  SetLastError( NULL );
1084  if( !TAXON1_IS_INITED ) {
1085  if( !Init() ) {
1086  return false;
1087  }
1088  }
1089  const char* pchName = m_plCache->GetRankName( rank_id );
1090  if( pchName ) {
1091  rank_name_out.assign( pchName );
1092  return true;
1093  } else {
1094  SetLastError( "ERROR: GetRankName(): Rank not found" );
1095  return false;
1096  }
1097 }
1098 
1099 //---------------------------------------------
1100 // Get taxonomic rank id by rank name
1101 // Returns: rank id
1102 // -2 - in case of error
1103 ///
1104 TTaxRank
1105 CTaxon1::GetRankIdByName(const string& rank_name)
1106 {
1107  SetLastError( NULL );
1108  if( !TAXON1_IS_INITED ) {
1109  if( !Init() ) {
1110  return false;
1111  }
1112  }
1113  TTaxRank id = m_plCache->FindRankByName( rank_name.c_str() );
1114  if( id != -1000 ) {
1115  return id;
1116  } else {
1117  // Error already set
1118  return -2;
1119  }
1120 }
1121 
1122 //---------------------------------------------
1123 // Get taxonomic division name by division id
1124 ///
1125 bool
1126 CTaxon1::GetDivisionName(TTaxDivision div_id, string& div_name_out, string* div_code_out )
1127 {
1128  SetLastError( NULL );
1129  if( !TAXON1_IS_INITED ) {
1130  if( !Init() ) {
1131  return false;
1132  }
1133  }
1134  const char* pchName = m_plCache->GetDivisionName( div_id );
1135  const char* pchCode = m_plCache->GetDivisionCode( div_id );
1136  if( pchName ) {
1137  div_name_out.assign( pchName );
1138  if( pchCode && div_code_out != NULL ) {
1139  div_code_out->assign( pchCode );
1140  }
1141  return true;
1142  } else {
1143  SetLastError( "ERROR: GetDivisionName(): Division not found" );
1144  return false;
1145  }
1146 }
1147 
1148 //---------------------------------------------
1149 // Get taxonomic division id by division name (or code)
1150 // Returns: rank id
1151 // -1 - in case of error
1152 ///
1154 CTaxon1::GetDivisionIdByName(const string& div_name)
1155 {
1156  SetLastError( NULL );
1157  if( !TAXON1_IS_INITED ) {
1158  if( !Init() ) {
1159  return false;
1160  }
1161  }
1162  TTaxDivision id = m_plCache->FindDivisionByName( div_name.c_str() );
1163  if( id <= -1 ) {
1164  id = m_plCache->FindDivisionByCode( div_name.c_str() );
1165  if( id <= -1 ) {
1166  return -1;
1167  }
1168  }
1169  return id;
1170 }
1171 
1172 //---------------------------------------------
1173 // Get taxonomic name class (scientific name, common name, etc.) by id
1174 ///
1175 bool
1176 CTaxon1::GetNameClass(TTaxNameClass nameclass_id, string& name_class_out )
1177 {
1178  SetLastError( NULL );
1179  if( !TAXON1_IS_INITED ) {
1180  if( !Init() ) {
1181  return false;
1182  }
1183  }
1184  const char* pchName = m_plCache->GetNameClassName( nameclass_id );
1185  if( pchName ) {
1186  name_class_out.assign( pchName );
1187  return true;
1188  } else {
1189  SetLastError( "ERROR: GetNameClass(): Name class not found" );
1190  return false;
1191  }
1192 }
1193 
1194 //---------------------------------------------
1195 // Get name class id by name class name
1196 // Returns: value < 0 - Incorrect class name
1197 ///
1199 CTaxon1::GetNameClassId( const string& class_name )
1200 {
1201  SetLastError( NULL );
1202  if( !TAXON1_IS_INITED ) {
1203  if( !Init() ) {
1204  return -1;
1205  }
1206  }
1207  if( m_plCache->InitNameClasses() ) {
1208  return m_plCache->FindNameClassByName( class_name.c_str() );
1209  }
1210  return -1;
1211 }
1212 
1213 //---------------------------------------------
1214 // Get the nearest common ancestor for two nodes
1215 // Returns: id of this ancestor (id == 1 means that root node only is
1216 // ancestor)
1217 // -1 - in case of an error
1218 ///
1219 TTaxId
1220 CTaxon1::Join(TTaxId taxid1, TTaxId taxid2)
1221 {
1222  TTaxId tax_id = ZERO_TAX_ID;
1223  CTaxon1Node *pNode1, *pNode2;
1224  SetLastError(NULL);
1225  if( !TAXON1_IS_INITED ) {
1226  if( !Init() ) {
1227  return INVALID_TAX_ID;
1228  }
1229  }
1230  if( m_plCache->LookupAndAdd( taxid1, &pNode1 ) && pNode1
1231  && m_plCache->LookupAndAdd( taxid2, &pNode2 ) && pNode2 ) {
1233  pIt->GoNode( pNode1 );
1234  pIt->GoAncestor( pNode2 );
1235  tax_id = pIt->GetNode()->GetTaxId();
1236  }
1237  return tax_id;
1238 }
1239 
1240 //---------------------------------------------
1241 // Get all names for tax_id
1242 // Returns: number of names, name list appended with ogranism's names
1243 // -1 - in case of an error
1244 // NOTE:
1245 // If unique is true then only unique names will be stored
1246 ///
1247 int
1248 CTaxon1::GetAllNames(TTaxId tax_id, TNameList& lNames, bool unique)
1249 {
1250  int count(0);
1251  SetLastError(NULL);
1252  if( !TAXON1_IS_INITED ) {
1253  if( !Init() ) {
1254  return -1;
1255  }
1256  }
1257  CTaxon1_req req;
1258  CTaxon1_resp resp;
1259 
1260  req.SetGetorgnames(TAX_ID_TO(int, tax_id) );
1261 
1262  if( SendRequest( req, resp ) ) {
1263  if( resp.IsGetorgnames() ) {
1264  // Correct response, return object
1265  const list< CRef< CTaxon1_name > >& lNm = resp.GetGetorgnames();
1266  // Fill in the list
1267  for( list< CRef< CTaxon1_name > >::const_iterator
1268  i = lNm.begin();
1269  i != lNm.end(); ++i, ++count )
1270  if( !unique ) {
1271  lNames.push_back( (*i)->GetOname() );
1272  } else {
1273  lNames.push_back( ((*i)->IsSetUname() && !(*i)->GetUname().empty()) ?
1274  (*i)->GetUname() :
1275  (*i)->GetOname() );
1276  }
1277  } else { // Internal: wrong respond type
1278  SetLastError( "INTERNAL: TaxService response type is not Getorgnames" );
1279  return 0;
1280  }
1281  }
1282 
1283  return count;
1284 }
1285 
1286 //---------------------------------------------
1287 // Get list of all names for tax_id.
1288 // Clears the previous content of the list.
1289 // Returns: TRUE - success
1290 // FALSE - failure
1291 ///
1292 bool
1294 {
1295  SetLastError(NULL);
1296  if( !TAXON1_IS_INITED ) {
1297  if( !Init() ) {
1298  return false;
1299  }
1300  }
1301  CTaxon1_req req;
1302  CTaxon1_resp resp;
1303 
1304  lNames.clear();
1305 
1306  req.SetGetorgnames(TAX_ID_TO(int, tax_id) );
1307 
1308  if( SendRequest( req, resp ) ) {
1309  if( resp.IsGetorgnames() ) {
1310  // Correct response, return object
1311  const list< CRef< CTaxon1_name > >& lNm = resp.GetGetorgnames();
1312  // Fill in the list
1313  for( list< CRef< CTaxon1_name > >::const_iterator
1314  i = lNm.begin(), li = lNm.end(); i != li; ++i ) {
1315  lNames.push_back( *i );
1316  }
1317  } else { // Internal: wrong respond type
1318  SetLastError( "INTERNAL: TaxService response type is not Getorgnames" );
1319  return false;
1320  }
1321  }
1322 
1323  return true;
1324 }
1325 
1326 bool
1328 {
1329  SetLastError(NULL);
1330  if( !TAXON1_IS_INITED ) {
1331  if( !Init() ) {
1332  return false;
1333  }
1334  }
1335  CTaxon1_req req;
1336  CTaxon1_resp resp;
1337 
1338  req.SetDumpnames4class( name_class );
1339 
1340  if( SendRequest( req, resp ) ) {
1341  if( resp.IsDumpnames4class() ) {
1342  // Correct response, return object
1343  lOut.swap( resp.SetDumpnames4class() );
1344  } else { // Internal: wrong respond type
1345  SetLastError( "INTERNAL: TaxService response type is not Dumpnames4class" );
1346  return false;
1347  }
1348  }
1349 
1350  return true;
1351 }
1352 
1353 bool
1355 {
1356  SetLastError(NULL);
1357  if( TAXON1_IS_INITED ) {
1358  if( !m_pOut || !m_pOut->InGoodState() )
1359  SetLastError( "Output stream is not in good state" );
1360  else if( !m_pIn || !m_pIn->InGoodState() )
1361  SetLastError( "Input stream is not in good state" );
1362  else
1363  return true;
1364  } else {
1365  SetLastError( "Not connected to Taxonomy service" );
1366  }
1367  return false;
1368 }
1369 
1370 bool
1372 {
1373  SetLastError(NULL);
1374  if( !TAXON1_IS_INITED ) {
1375  if( !Init() ) {
1376  return false;
1377  }
1378  }
1379 
1380  CTaxon1_req req;
1381  CTaxon1_resp resp;
1382 
1383  req.SetId4gi( gi );
1384 
1385  if( SendRequest( req, resp ) ) {
1386  if( resp.IsId4gi() ) {
1387  // Correct response, return object
1388  tax_id_out = resp.GetId4gi();
1389  return true;
1390  } else if( resp.IsError() && resp.GetError().IsSetLevel() && resp.GetError().GetLevel() == CTaxon1_error::eLevel_error &&
1391  resp.GetError().IsSetMsg() && resp.GetError().GetMsg() == "id4gi: No taxid for this gi" ) {
1392  tax_id_out = ZERO_TAX_ID;
1393  return true;
1394  } else { // Internal: wrong respond type
1395  SetLastError( "INTERNAL: TaxService response type is not Id4gi" );
1396  }
1397  } else if( NStr::EqualNocase( GetLastError(), "ERROR: id4gi: No taxid for this gi") ) {
1398  tax_id_out = ZERO_TAX_ID;
1399  return true;
1400  }
1401  return false;
1402 }
1403 
1404 bool
1405 CTaxon1::GetBlastName(TTaxId tax_id, string& blast_name_out )
1406 {
1407  CTaxon1Node* pNode = 0;
1408  SetLastError(NULL);
1409  if( !TAXON1_IS_INITED ) {
1410  if( !Init() ) {
1411  return false;
1412  }
1413  }
1414  if( m_plCache->LookupAndAdd( tax_id, &pNode ) && pNode ) {
1415  while( !pNode->IsRoot() ) {
1416  if( !pNode->GetBlastName().empty() ) {
1417  blast_name_out.assign( pNode->GetBlastName() );
1418  return true;
1419  }
1420  pNode = pNode->GetParent();
1421  }
1422  blast_name_out.erase();
1423  return true;
1424  }
1425  return false;
1426 }
1427 
1428 bool
1429 CTaxon1::SendRequest( CTaxon1_req& req, CTaxon1_resp& resp, bool bShouldReconnect )
1430 {
1431  unsigned nIterCount( 0 );
1432  unsigned fail_flags( 0 );
1433  if( !m_pServer ) {
1434  SetLastError( "Service is not initialized" );
1435  return false;
1436  }
1437  SetLastError( NULL );
1438 
1439  do {
1440  bool bNeedReconnect( false );
1441 
1442  try {
1443  *m_pOut << req;
1444  m_pOut->Flush();
1445 
1446  try {
1447  *m_pIn >> resp;
1448 
1449  if( m_pIn->InGoodState() ) {
1450  if( resp.IsError() ) { // Process error here
1451  string err;
1452  resp.GetError().GetErrorText( err );
1453  SetLastError( err.c_str() );
1454  return false;
1455  } else
1456  return true;
1457  }
1458  } catch( CEofException& /*eoe*/ ) {
1459  bNeedReconnect = bShouldReconnect;
1460  } catch( exception& e ) {
1461  SetLastError( e.what() );
1462  bNeedReconnect = bShouldReconnect;
1463  }
1464  fail_flags = m_pIn->GetFailFlags();
1465  bNeedReconnect |= bShouldReconnect &&
1466  (fail_flags & ( CObjectIStream::eReadError
1469  ? true : false);
1470  } catch( exception& e ) {
1471  SetLastError( e.what() );
1472  fail_flags = m_pOut->GetFailFlags();
1473  bNeedReconnect = bShouldReconnect &&
1474  (fail_flags & ( CObjectOStream::eWriteError
1477  ? true : false);
1478  }
1479 
1480  if( !bNeedReconnect )
1481  break;
1482  // Reconnect the service
1483  if( nIterCount < m_nReconnectAttempts ) {
1484  delete m_pOut;
1485  delete m_pIn;
1486  delete m_pServer;
1487  m_pOut = NULL;
1488  m_pIn = NULL;
1489  m_pServer = NULL;
1490  try {
1491  unique_ptr<CObjectOStream> pOut;
1492  unique_ptr<CObjectIStream> pIn;
1493  unique_ptr<CConn_ServiceStream>
1495  0, 0, m_timeout) );
1496 
1497  pOut.reset( CObjectOStream::Open(m_eDataFormat, *pServer) );
1498  pIn.reset( CObjectIStream::Open(m_eDataFormat, *pServer) );
1499  pOut->FixNonPrint(eFNP_Allow);
1500  pIn->FixNonPrint(eFNP_Allow);
1501 
1502  m_pServer = pServer.release();
1503  m_pIn = pIn.release();
1504  m_pOut = pOut.release();
1505  } catch( exception& e ) {
1506  SetLastError( e.what() );
1507  }
1508  } else { // No more attempts left
1509  break;
1510  }
1511  } while( nIterCount++ < m_nReconnectAttempts );
1512  return false;
1513 }
1514 
1515 void
1516 CTaxon1::SetLastError( const char* pchErr )
1517 {
1518  if( pchErr )
1519  m_sLastError.assign( pchErr );
1520  else
1521  m_sLastError.erase();
1522 }
1523 
1525 {
1526  CTaxon1Node* pNode = static_cast<CTaxon1Node*>( pIt->GetNode() );
1527  if( !pNode->IsJoinTerminal() ) {
1528  lTo.push_back( pNode->GetTaxId() );
1529  }
1530  if( pIt->GoChild() ) {
1531  do {
1532  s_StoreResidueTaxid( pIt, lTo );
1533  } while( pIt->GoSibling() );
1534  pIt->GoParent();
1535  }
1536 }
1537 //--------------------------------------------------
1538 // This function constructs minimal common tree from the gived tax id
1539 // set (ids_in) treated as tree's leaves. It then returns a residue of
1540 // this tree node set and the given tax id set in ids_out.
1541 // Returns: false if some error
1542 // true if Ok
1543 ///
1544 typedef vector<CTaxon1Node*> TTaxNodeLineage;
1545 bool
1547 {
1548  SetLastError(NULL);
1549  if( !TAXON1_IS_INITED ) {
1550  if( !Init() ) {
1551  return false;
1552  }
1553  }
1554  if( ids_in.size() > 0 ) {
1556  CTaxon1Node *pParent = 0, *pNode = 0, *pNewParent = 0;
1557  CTreeCont tPartTree; // Partial tree
1558  CTreeIterator* pIt = tPartTree.GetIterator();
1559  TTaxNodeLineage vLin;
1560  // Build the partial tree
1561  bool bHasSiblings;
1562  vLin.reserve( 256 );
1563  for( TTaxIdList::const_iterator ci = ids_in.begin();
1564  ci != ids_in.end();
1565  ++ci ) {
1566  map< TTaxId, CTaxon1Node* >::iterator nmi = nodeMap.find( *ci );
1567  if( nmi == nodeMap.end() ) {
1568  if( m_plCache->LookupAndAdd( *ci, &pNode ) ) {
1569  if( !tPartTree.GetRoot() ) {
1570  pNewParent = new CTaxon1Node
1571  ( *static_cast<const CTaxon1Node*>
1572  (m_plCache->GetTree().GetRoot()) );
1573  tPartTree.SetRoot( pNewParent );
1575  (pNewParent->GetTaxId(), pNewParent) );
1576  }
1577  if( pNode ) {
1578  vLin.clear();
1579  pParent = pNode->GetParent();
1580  pNode = new CTaxon1Node( *pNode );
1581  pNode->SetJoinTerminal();
1582  vLin.push_back( pNode );
1583  while( pParent &&
1584  ((nmi=nodeMap.find(pParent->GetTaxId()))
1585  == nodeMap.end()) ) {
1586  pNode = new CTaxon1Node( *pParent );
1587  vLin.push_back( pNode );
1588  pParent = pParent->GetParent();
1589  }
1590  if( !pParent ) {
1591  pIt->GoRoot();
1592  } else {
1593  pIt->GoNode( nmi->second );
1594  }
1595  for( TTaxNodeLineage::reverse_iterator i =
1596  vLin.rbegin();
1597  i != vLin.rend();
1598  ++i ) {
1599  pNode = *i;
1601  ( pNode->GetTaxId(), pNode ) );
1602  pIt->AddChild( pNode );
1603  pIt->GoNode( pNode );
1604  }
1605  }
1606  } else { // Error while adding - ignore invalid tax_ids
1607  continue;
1608  //return false;
1609  }
1610  } else { // Node is already here
1611  nmi->second->SetJoinTerminal();
1612  }
1613  }
1614  // Partial tree is build, make a residue
1615  if( tPartTree.GetRoot() ) {
1616  pIt->GoRoot();
1617  bHasSiblings = true;
1618  if( pIt->GoChild() ) {
1619  while( !pIt->GoSibling() ) {
1620  pNode = static_cast<CTaxon1Node*>( pIt->GetNode() );
1621  if( pNode->IsJoinTerminal() || !pIt->GoChild() ) {
1622  bHasSiblings = false;
1623  break;
1624  }
1625  }
1626  if( bHasSiblings ) {
1627  pIt->GoParent();
1628  }
1629  s_StoreResidueTaxid( pIt, ids_out );
1630  }
1631  }
1632  }
1633  return true;
1634 }
1635 
1636 //-----------------------------------
1637 // Tree-related functions
1638 bool
1639 CTaxon1::LoadSubtreeEx( TTaxId tax_id, int levels, const ITaxon1Node** ppNode )
1640 {
1641  CTaxon1Node* pNode = 0;
1642  SetLastError(NULL);
1643  if( !TAXON1_IS_INITED ) {
1644  if( !Init() ) {
1645  return false;
1646  }
1647  }
1648  if( ppNode ) {
1649  *ppNode = pNode;
1650  }
1651  if( m_plCache->LookupAndAdd( tax_id, &pNode )
1652  && pNode ) {
1653 
1654  if( ppNode ) {
1655  *ppNode = pNode;
1656  }
1657 
1658  if( pNode->IsSubtreeLoaded() ) {
1659  return true;
1660  }
1661 
1662  if( levels == 0 ) {
1663  return true;
1664  }
1665 
1666  CTaxon1_req req;
1667  CTaxon1_resp resp;
1668 
1669  if( levels < 0 ) {
1670  tax_id = -tax_id;
1671  }
1672  req.SetTaxachildren(TAX_ID_TO(int, tax_id) );
1673 
1674  if( SendRequest( req, resp ) ) {
1675  if( resp.IsTaxachildren() ) {
1676  // Correct response, return object
1677  list< CRef< CTaxon1_name > >& lNm = resp.SetTaxachildren();
1678  // Fill in the list
1680  pIt->GoNode( pNode );
1681  for( list< CRef< CTaxon1_name > >::const_iterator
1682  i = lNm.begin();
1683  i != lNm.end(); ++i ) {
1684  if( (*i)->GetCde() == 0 ) { // Change parent node
1685  if( m_plCache->LookupAndAdd( (*i)->GetTaxid(), &pNode )
1686  && pNode ) {
1687  pIt->GoNode( pNode );
1688  } else { // Invalid parent specified
1689  SetLastError( ("Invalid parent taxid "
1690  + NStr::NumericToString((*i)->GetTaxid())
1691  ).c_str() );
1692  return false;
1693  }
1694  } else { // Add node to the partial tree
1695  if( !m_plCache->Lookup((*i)->GetTaxid(), &pNode) ) {
1696  pNode = new CTaxon1Node(*i);
1697  m_plCache->SetIndexEntry(TAX_ID_TO(int, pNode->GetTaxId()), pNode);
1698  pIt->AddChild( pNode );
1699  }
1700  }
1701  pNode->SetSubtreeLoaded( pNode->IsSubtreeLoaded() ||
1702  (levels < 0) );
1703  }
1704  return true;
1705  } else { // Internal: wrong respond type
1706  SetLastError( "INTERNAL: TaxService response type is not Taxachildren" );
1707  return false;
1708  }
1709  }
1710  }
1711  return false;
1712 }
1713 
1716 {
1717  if( !TAXON1_IS_INITED ) {
1718  if( !Init() ) {
1719  return null;
1720  }
1721  }
1722 
1725 
1726  switch( mode ) {
1727  default:
1729  pIt.Reset( new CFullTreeConstIterator( pIter ) );
1730  break;
1732  pIt.Reset( new CTreeLeavesBranchesIterator( pIter ) );
1733  break;
1734  case eIteratorMode_Best:
1735  pIt.Reset( new CTreeBestIterator( pIter ) );
1736  break;
1737  case eIteratorMode_Blast:
1738  pIt.Reset( new CTreeBlastIterator( pIter ) );
1739  break;
1740  }
1741  SetLastError(NULL);
1742  return pIt;
1743 }
1744 
1747 {
1749  CTaxon1Node* pData = 0;
1750  SetLastError(NULL);
1751  if( !TAXON1_IS_INITED ) {
1752  if( !Init() ) {
1753  return null;
1754  }
1755  }
1756  if( m_plCache->LookupAndAdd( tax_id, &pData ) ) {
1757  pIt = GetTreeIterator( mode );
1758  if( !pIt->GoNode( pData ) ) {
1759  SetLastError( "Iterator in this mode cannot point to the node with"
1760  " this tax id" );
1761  pIt.Reset( NULL );
1762  }
1763  }
1764  return pIt;
1765 }
1766 
1767 bool
1768 CTaxon1::GetNodeProperty( TTaxId tax_id, const string& prop_name,
1769  string& prop_val )
1770 {
1771  SetLastError(NULL);
1772  if( !TAXON1_IS_INITED ) {
1773  if( !Init() ) {
1774  return false;
1775  }
1776  }
1777  CTaxon1_req req;
1778  CTaxon1_resp resp;
1779  CRef<CTaxon1_info> pProp( new CTaxon1_info() );
1780 
1781  CDiagAutoPrefix( "Taxon1::GetNodeProperty" );
1782 
1783  if( !prop_name.empty() ) {
1784  pProp->SetIval1(TAX_ID_TO(int, tax_id) );
1785  pProp->SetIval2( -1 ); // Get string property by name
1786  pProp->SetSval( prop_name );
1787 
1788  req.SetGetorgprop( *pProp );
1789  try {
1790  if( SendRequest( req, resp ) ) {
1791  if( !resp.IsGetorgprop() ) { // error
1792  ERR_POST_X( 4, "Response type is not Getorgprop" );
1793  SetLastError( "INTERNAL: TaxService response type is not Getorgprop" );
1794  } else {
1795  if( resp.GetGetorgprop().size() > 0 ) {
1796  CRef<CTaxon1_info> pInfo
1797  ( resp.GetGetorgprop().front() );
1798  prop_val.assign( pInfo->GetSval() );
1799  return true;
1800  }
1801  }
1802  } else if( resp.IsError()
1803  && resp.GetError().GetLevel()
1805  string sErr;
1806  resp.GetError().GetErrorText( sErr );
1807  ERR_POST_X( 5, sErr );
1808  }
1809  } catch( exception& e ) {
1810  ERR_POST_X( 6, e.what() );
1811  SetLastError( e.what() );
1812  }
1813  } else {
1814  SetLastError( "Empty property name is not accepted" );
1815  ERR_POST_X( 7, GetLastError() );
1816  }
1817  return false;
1818 }
1819 
1820 bool
1821 CTaxon1::GetNodeProperty( TTaxId tax_id, const string& prop_name,
1822  bool& prop_val )
1823 {
1824  SetLastError(NULL);
1825  if( !TAXON1_IS_INITED ) {
1826  if( !Init() ) {
1827  return false;
1828  }
1829  }
1830  CTaxon1_req req;
1831  CTaxon1_resp resp;
1832  CRef<CTaxon1_info> pProp( new CTaxon1_info() );
1833 
1834  CDiagAutoPrefix( "Taxon1::GetNodeProperty" );
1835 
1836  if( !prop_name.empty() ) {
1837  pProp->SetIval1(TAX_ID_TO(int, tax_id) );
1838  pProp->SetIval2( -3 ); // Get bool property by name
1839  pProp->SetSval( prop_name );
1840 
1841  req.SetGetorgprop( *pProp );
1842  try {
1843  if( SendRequest( req, resp ) ) {
1844  if( !resp.IsGetorgprop() ) { // error
1845  ERR_POST_X( 8, "Response type is not Getorgprop" );
1846  SetLastError( "INTERNAL: TaxService response type is not Getorgprop" );
1847  } else {
1848  if( resp.GetGetorgprop().size() > 0 ) {
1849  CRef<CTaxon1_info> pInfo
1850  = resp.GetGetorgprop().front();
1851  prop_val = pInfo->GetIval2() != 0;
1852  return true;
1853  }
1854  }
1855  } else if( resp.IsError()
1856  && resp.GetError().GetLevel()
1858  string sErr;
1859  resp.GetError().GetErrorText( sErr );
1860  ERR_POST_X( 9, sErr );
1861  }
1862  } catch( exception& e ) {
1863  ERR_POST_X( 10, e.what() );
1864  SetLastError( e.what() );
1865  }
1866  } else {
1867  SetLastError( "Empty property name is not accepted" );
1868  ERR_POST_X( 11, GetLastError() );
1869  }
1870  return false;
1871 }
1872 
1873 bool
1874 CTaxon1::GetNodeProperty( TTaxId tax_id, const string& prop_name,
1875  int& prop_val )
1876 {
1877  SetLastError(NULL);
1878  if( !TAXON1_IS_INITED ) {
1879  if( !Init() ) {
1880  return false;
1881  }
1882  }
1883  CTaxon1_req req;
1884  CTaxon1_resp resp;
1885  CRef<CTaxon1_info> pProp( new CTaxon1_info() );
1886 
1887  CDiagAutoPrefix( "Taxon1::GetNodeProperty" );
1888 
1889  if( !prop_name.empty() ) {
1890  pProp->SetIval1(TAX_ID_TO(int, tax_id) );
1891  pProp->SetIval2( -2 ); // Get int property by name
1892  pProp->SetSval( prop_name );
1893 
1894  req.SetGetorgprop( *pProp );
1895  try {
1896  if( SendRequest( req, resp ) ) {
1897  if( !resp.IsGetorgprop() ) { // error
1898  ERR_POST_X( 12, "Response type is not Getorgprop" );
1899  SetLastError( "INTERNAL: TaxService response type is not Getorgprop" );
1900  } else {
1901  if( resp.GetGetorgprop().size() > 0 ) {
1902  CRef<CTaxon1_info> pInfo
1903  = resp.GetGetorgprop().front();
1904  prop_val = pInfo->GetIval2();
1905  return true;
1906  }
1907  }
1908  } else if( resp.IsError()
1909  && resp.GetError().GetLevel()
1911  string sErr;
1912  resp.GetError().GetErrorText( sErr );
1913  ERR_POST_X( 13, sErr );
1914  }
1915  } catch( exception& e ) {
1916  ERR_POST_X( 14, e.what() );
1917  SetLastError( e.what() );
1918  }
1919  } else {
1920  SetLastError( "Empty property name is not accepted" );
1921  ERR_POST_X( 15, GetLastError() );
1922  }
1923  return false;
1924 }
1925 
1926 bool
1927 CTaxon1::GetInheritedPropertyDefines( const string& prop_name,
1928  CTaxon1::TInfoList& results,
1929  TTaxId root )
1930 {
1931  SetLastError(NULL);
1932  if( !TAXON1_IS_INITED ) {
1933  if( !Init() ) {
1934  return false;
1935  }
1936  }
1937  CTaxon1_req req;
1938  CTaxon1_resp resp;
1939  CRef<CTaxon1_info> pProp( new CTaxon1_info() );
1940 
1941  CDiagAutoPrefix( "Taxon1::GetInheritedPropertyDefines" );
1942 
1943  if( !prop_name.empty() ) {
1944  pProp->SetIval1(TAX_ID_TO(int, -root) );
1945  pProp->SetIval2( -4 ); // Get inherited property defines by name
1946  pProp->SetSval( prop_name );
1947 
1948  req.SetGetorgprop( *pProp );
1949  try {
1950  if( SendRequest( req, resp ) ) {
1951  if( !resp.IsGetorgprop() ) { // error
1952  ERR_POST_X( 12, "Response type is not Getorgprop" );
1953  } else {
1954  if( resp.GetGetorgprop().size() > 0 ) {
1955  results = resp.SetGetorgprop();
1956  return true;
1957  }
1958  }
1959  } else if( resp.IsError()
1960  && resp.GetError().GetLevel()
1962  string sErr;
1963  resp.GetError().GetErrorText( sErr );
1964  ERR_POST_X( 13, sErr );
1965  }
1966  } catch( exception& e ) {
1967  ERR_POST_X( 14, e.what() );
1968  SetLastError( e.what() );
1969  }
1970  } else {
1971  SetLastError( "Empty property name is not accepted" );
1972  ERR_POST_X( 15, GetLastError() );
1973  }
1974  return false;
1975 }
1976 
1977 
1978 //-----------------------------------
1979 // Iterator stuff
1980 //
1981 // 'Downward' traverse mode (nodes that closer to root processed first)
1984 {
1985  if( levels ) {
1986  switch( cb.Execute(GetNode()) ) {
1987  default:
1988  case eOk:
1989  if(!IsTerminal()) {
1990  switch( cb.LevelBegin(GetNode()) ) {
1991  case eStop: return eStop;
1992  default:
1993  case eOk:
1994  if(GoChild()) {
1995  do {
1996  if(TraverseDownward(cb, levels-1)==eStop)
1997  return eStop;
1998  } while(GoSibling());
1999  }
2000  case eSkip: // Means skip this level
2001  break;
2002  }
2003  GoParent();
2004  if( cb.LevelEnd(GetNode()) == eStop )
2005  return eStop;
2006  }
2007  case eSkip: break;
2008  case eStop: return eStop;
2009  }
2010  }
2011  return eOk;
2012 }
2013 
2014 // 'Upward' traverse mode (nodes that closer to leaves processed first)
2017 {
2018  if( levels > 0 ) {
2019  if(!IsTerminal()) {
2020  switch( cb.LevelBegin(GetNode()) ) {
2021  case eStop: return eStop;
2022  default:
2023  case eOk:
2024  if(GoChild()) {
2025  do {
2026  if( TraverseUpward(cb, levels-1) == eStop )
2027  return eStop;
2028  } while(GoSibling());
2029  }
2030  case eSkip: // Means skip this level
2031  break;
2032  }
2033  GoParent();
2034  if( cb.LevelEnd(GetNode()) == eStop )
2035  return eStop;
2036  }
2037  return cb.Execute(GetNode());
2038  }
2039  return eOk;
2040 }
2041 
2042 // 'LevelByLevel' traverse (nodes that closer to root processed first)
2045 {
2046  switch( cb.Execute( GetNode() ) ) {
2047  case eStop:
2048  return eStop;
2049  case eSkip:
2050  return eSkip;
2051  case eOk:
2052  default:
2053  break;
2054  }
2055  if(!IsTerminal()) {
2056  vector< const ITaxon1Node* > skippedNodes;
2057  return TraverseLevelByLevelInternal(cb, levels, skippedNodes);
2058  }
2059  return eOk;
2060 }
2061 
2064  vector< const ITaxon1Node* >& skp)
2065 {
2066  size_t skp_start = skp.size();
2067  if( levels > 1 ) {
2068  if(!IsTerminal()) {
2069  switch( cb.LevelBegin(GetNode()) ) {
2070  case eStop: return eStop;
2071  default:
2072  case eOk:
2073  if(GoChild()) {
2074  // First pass - call Execute for all children
2075  do {
2076  switch( cb.Execute(GetNode()) ) {
2077  default:
2078  case eOk:
2079  break;
2080  case eSkip: // Means skip this node
2081  skp.push_back( GetNode() );
2082  break;
2083  case eStop: return eStop;
2084  }
2085  } while( GoSibling() );
2086  GoParent();
2087  // Start second pass
2088  size_t skp_cur = skp_start;
2089  GoChild();
2090  do {
2091  if( skp.size() == skp_start ||
2092  skp[skp_cur] != GetNode() ) {
2093  if(TraverseLevelByLevelInternal(cb, levels-1, skp)
2094  == eStop ) {
2095  return eStop;
2096  }
2097  } else {
2098  ++skp_cur;
2099  }
2100  } while(GoSibling());
2101  GoParent();
2102  }
2103  if( cb.LevelEnd( GetNode() ) == eStop )
2104  return eStop;
2105  break;
2106  case eSkip:
2107  break;
2108  }
2109  }
2110  }
2111  skp.resize( skp_start );
2112  return eOk;
2113 }
2114 
2115 // Scans all the ancestors starting from immediate parent up to the root
2116 // (no levelBegin, levelEnd calls performed)
2119 {
2120  const ITaxon1Node* pNode = GetNode();
2121  EAction stat = eOk;
2122  while( GoParent() ) {
2123  stat = cb.Execute(GetNode());
2124  switch( stat ) {
2125  case eStop: return eStop; // Stop scan, some error occurred
2126  default:
2127  case eOk:
2128  case eSkip: // Means skip further scan, no error generated
2129  break;
2130  }
2131  if( stat == eSkip ) {
2132  break;
2133  }
2134  }
2135  GoNode( pNode );
2136  return stat;
2137 }
2138 
2139 //-----------------------------------------------
2140 // Checks whether OrgRef is current
2141 // Returns: false on any error, stat_out filled with status flags
2142 // (see above)
2143 ///
2144 bool
2145 CTaxon1::CheckOrgRef( const COrg_ref& orgRef, TOrgRefStatus& stat_out, string* psLog )
2146 {
2147  CDiagAutoPrefix( "Taxon1::CheckOrgRef" );
2148  SetLastError(NULL);
2149  if( !TAXON1_IS_INITED ) {
2150  if( !Init() ) {
2151  return false;
2152  }
2153  }
2154  stat_out = eStatus_Ok;
2155 
2156  CTaxon1_req req;
2157  CTaxon1_resp resp;
2158 
2159  SerialAssign< COrg_ref >( req.SetLookup(), orgRef );
2160  // Set version db tag
2161  COrgrefProp::SetOrgrefProp( req.SetLookup(), "version", 2 );
2162  COrgrefProp::SetOrgrefProp( req.SetLookup(), "merge", true );
2163  if( psLog ) {
2164  COrgrefProp::SetOrgrefProp( req.SetLookup(), "log", true );
2165  }
2166 
2167 
2168  if( SendRequest( req, resp ) ) {
2169  if( resp.IsLookup() ) {
2170  // Correct response, return object
2171  CRef<CTaxon2_data> pData( new CTaxon2_data() );
2172 
2173  SerialAssign< COrg_ref >( pData->SetOrg(), resp.GetLookup().GetOrg() );
2174  stat_out = x_ConvertOrgrefProps( *pData );
2175  if( psLog ) {
2176  pData->GetProperty( "log", *psLog );
2177  }
2178 
2179  return true;
2180  } else { // Internal: wrong respond type
2181  SetLastError( "INTERNAL: TaxService response type is not Lookup" );
2182  }
2183  }
2184 
2185  return false;
2186 }
2187 
2188 //---------------------------------------------------
2189 // This function returns the list of "type materials" for the node with taxid given.
2190 // The list consists of names with class type material found at the species
2191 // or subspecies ancestor of the node.
2192 // Returns: true when success and last parameter is filled with type material list,
2193 // false when call failed
2194 ///
2195 bool
2196 CTaxon1::GetTypeMaterial( TTaxId tax_id, TNameList& type_material_list_out )
2197 {
2198  CTaxon1Node* pNode = 0;
2199  SetLastError(NULL);
2200  if( !TAXON1_IS_INITED ) {
2201  if( !Init() ) {
2202  return false;
2203  }
2204  }
2205  type_material_list_out.clear();
2206  if( m_plCache->LookupAndAdd( tax_id, &pNode )
2207  && pNode &&
2208  m_plCache->InitRanks() ) {
2209  list< CRef< CTaxon1_name > > lNames;
2210 
2211  int species_rank(m_plCache->GetSpeciesRank());
2212  int subspecies_rank(m_plCache->GetSubspeciesRank());
2213  while( !pNode->IsRoot() ) {
2214  int rank( pNode->GetRank() );
2215  if( rank == subspecies_rank ) {
2216  bool a,b;
2217  string blast_name;
2218  CConstRef< COrg_ref > subsporg( GetOrgRef( pNode->GetTaxId(), a, b, blast_name ) );
2219  if( subsporg->IsSetOrgname() && subsporg->GetOrgname().IsSetName() ) {
2220  const COrgName::C_Name& on( subsporg->GetOrgname().GetName() );
2221  if( on.IsBinomial() && on.GetBinomial().IsSetSpecies()
2222  && on.GetBinomial().IsSetSubspecies()
2225  || NStr::EqualNocase( "subsp. "+on.GetBinomial().GetSpecies(), on.GetBinomial().GetSubspecies() )) ) {
2226  // nominal subspecies
2227  pNode = pNode->GetParent();
2228  continue;
2229  }
2230  }
2231  if( !GetAllNamesEx( pNode->GetTaxId(), lNames ) ) {
2232  return false;
2233  }
2234  break;
2235  } else if( rank == species_rank ) {
2236  if( !GetAllNamesEx( pNode->GetTaxId(), lNames ) ) {
2237  return false;
2238  }
2239  break;
2240  } else if( (rank > 0) && (rank < species_rank)) {
2241  SetLastError( "No species or subspecies found in lineage" );
2242  ERR_POST_X( 19, GetLastError() );
2243  return false;
2244  }
2245  pNode = pNode->GetParent();
2246  }
2247  // Filter out excessive name classes, leave type material only
2248  TTaxNameClass tm_cde = GetNameClassId( "type material" );
2249  if ( tm_cde < 0 ) {
2250  SetLastError( "Name class for type material not found" );
2251  ERR_POST_X( 19, GetLastError() );
2252  return false;
2253  }
2254  // copy only type material
2255  ITERATE( list< CRef< CTaxon1_name > >, i, lNames ) {
2256  if( (*i)->GetCde() == tm_cde ) {
2257  type_material_list_out.push_back( (*i)->GetOname() );
2258  }
2259  }
2260  return true;
2261  } else {
2262  SetLastError( "No organisms found for tax id" );
2263  ERR_POST_X( 18, GetLastError() );
2264  return false;
2265  }
2266 }
2267 
2268 //---------------------------------------------------
2269 // This function returns the maximal value for taxid
2270 // or -1 in case of error
2271 ///
2272 TTaxId
2274 {
2275  SetLastError(NULL);
2276  if( !TAXON1_IS_INITED ) {
2277  if( !Init() ) {
2278  return INVALID_TAX_ID;
2279  }
2280  }
2281  return TAX_ID_FROM(unsigned, m_plCache->m_nMaxTaxId);
2282 }
2283 
2284 //---------------------------------------------------
2285 // This function constructs the "display common name" for the taxid following this algorithm:
2286 // Return first non-empty value from the following sequence:
2287 // 1) the GenBank common name
2288 // 2) the common name if there is only one
2289 // 3) if taxid is subspecies
2290 // a) the species GenBank common name
2291 // b) the species common name if there is only one
2292 // 4) the Blast inherited blast name
2293 // Returns: true on success, false in case of error
2294 ///
2295 bool
2296 CTaxon1::GetDisplayCommonName( TTaxId tax_id, string& disp_name_out )
2297 {
2298  CTaxon1Node* pNode = 0;
2299  SetLastError(NULL);
2300  if( !TAXON1_IS_INITED ) {
2301  if( !Init() ) {
2302  return false;
2303  }
2304  }
2305  if( m_plCache->LookupAndAdd( tax_id, &pNode ) && pNode &&
2306  m_plCache->InitNameClasses() ) {
2307  tax_id = pNode->GetTaxId(); // get rid of secondary taxid
2309  list< CRef< CTaxon1_name > > lNames;
2310  if( GetAllNamesEx(tax_id, lNames) ) {
2311  // 1)
2312  ITERATE( list< CRef< CTaxon1_name > >, ci, lNames ) {
2313  if( (*ci)->GetCde() == cn ) { // we have a winner
2314  disp_name_out = (*ci)->GetOname();
2315  return true;
2316  }
2317  }
2318  // 2)
2319  cn = m_plCache->GetCommonNameClass();
2320  list< CRef< CTaxon1_name > >::const_iterator lend = lNames.end();
2321  ITERATE( list< CRef< CTaxon1_name > >, ci, lNames ) {
2322  if( (*ci)->GetCde() == cn ) { // we might have a winner
2323  if( lend == lNames.end() ) {
2324  lend = ci;
2325  } else { // another common name found
2326  lend = lNames.end();
2327  break;
2328  }
2329  }
2330  }
2331  if( lend != lNames.end() ) {
2332  disp_name_out = (*lend)->GetOname();
2333  return true;
2334  }
2335  }
2336  // 3)
2337 // if( pNode->GetRank() == m_plCache->GetSubspeciesRank() ) {
2338  // Get corresponding species
2339  TTaxId species_id = GetSpecies(tax_id);
2340  if( species_id < ZERO_TAX_ID ) {
2341  return false;
2342  } else if( species_id > ZERO_TAX_ID && species_id != tax_id ) {
2343  lNames.clear();
2345  if( GetAllNamesEx(species_id, lNames) ) {
2346  // 3a)
2347  ITERATE( list< CRef< CTaxon1_name > >, ci, lNames ) {
2348  if( (*ci)->GetCde() == cn ) { // we have a winner
2349  disp_name_out = (*ci)->GetOname();
2350  return true;
2351  }
2352  }
2353  // 3b)
2354  cn = m_plCache->GetCommonNameClass();
2355  list< CRef< CTaxon1_name > >::const_iterator lend = lNames.end();
2356  ITERATE( list< CRef< CTaxon1_name > >, ci, lNames ) {
2357  if( (*ci)->GetCde() == cn ) { // we might have a winner
2358  if( lend == lNames.end() ) {
2359  lend = ci;
2360  } else { // another common name found
2361  lend = lNames.end();
2362  break;
2363  }
2364  }
2365  }
2366  if( lend != lNames.end() ) {
2367  disp_name_out = (*lend)->GetOname();
2368  return true;
2369  }
2370  }
2371  }
2372 // }
2373  // 4)
2374  if( !GetBlastName(tax_id, disp_name_out ) ) {
2375  return false;
2376  }
2377  } else {
2378  return false;
2379  }
2380  return true;
2381 }
2382 
2383 //--------------------------------------------------
2384 // Get scientific name for taxonomy id
2385 // Returns: false if some error occurred (name_out not changed)
2386 // true if Ok
2387 // name_out contains scientific name of this node
2388 ///
2389 bool
2390 CTaxon1::GetScientificName(TTaxId tax_id, string& name_out)
2391 {
2392  CTaxon1Node* pNode = 0;
2393  SetLastError(NULL);
2394  if( !TAXON1_IS_INITED ) {
2395  if( !Init() ) {
2396  return false;
2397  }
2398  }
2399  if( m_plCache->LookupAndAdd( tax_id, &pNode ) && pNode ) {
2400  if( !pNode->GetName().empty() ) {
2401  name_out.assign( pNode->GetName() );
2402  return true;
2403  } else {
2404  SetLastError( "ERROR: No scientific name at the node" );
2405  }
2406  }
2407  return false;
2408 }
2409 
2410 END_objects_SCOPE
#define false
Definition: bool.h:36
This stream exchanges data with a named service, in a constraint that the service is implemented as o...
CConstRef –.
Definition: ncbiobj.hpp:1266
CDiagAutoPrefix –.
Definition: ncbidiag.hpp:1430
TTaxNameClass FindNameClassByName(const char *pchName)
Definition: cache.cpp:381
bool LookupAndAdd(TTaxId tax_id, CTaxon1Node **ppData)
Definition: cache.cpp:114
TTaxRank GetSuperkingdomRank() const
Definition: cache.hpp:108
const char * GetNameClassName(short nc)
Definition: cache.cpp:370
TTaxRank GetSubspeciesRank() const
Definition: cache.hpp:111
TTaxRank GetGenusRank() const
Definition: cache.hpp:109
const char * GetDivisionName(TTaxDivision div_id)
Definition: cache.cpp:470
TTaxRank GetSpeciesRank() const
Definition: cache.hpp:110
TTaxRank FindRankByName(const char *pchName)
Definition: cache.cpp:265
TTaxNameClass GetPreferredCommonNameClass() const
Definition: cache.hpp:114
unsigned m_nMaxTaxId
Definition: cache.hpp:139
bool Lookup(TTaxId tax_id, CTaxon1Node **ppNode)
Definition: cache.cpp:103
TTaxNameClass GetCommonNameClass() const
Definition: cache.hpp:115
bool InitRanks()
Definition: cache.cpp:337
TTaxDivision FindDivisionByCode(const char *pchCode)
Definition: cache.cpp:435
TTaxDivision FindDivisionByName(const char *pchName)
Definition: cache.cpp:447
bool LookupAndInsert(TTaxId tax_id, CTaxon2_data **ppData)
Definition: cache.cpp:181
bool InitNameClasses()
Definition: cache.cpp:393
const char * GetRankName(int rank)
Definition: cache.cpp:278
bool Init(unsigned nCapacity=10)
Definition: cache.cpp:65
void SetIndexEntry(int id, CTaxon1Node *pNode)
Definition: cache.cpp:521
const char * GetDivisionCode(TTaxDivision div_id)
Definition: cache.cpp:459
CTreeCont & GetTree()
Definition: cache.hpp:120
static void SetOrgrefProp(ncbi::objects::COrg_ref &org, const std::string &prop_name, const std::string &prop_val)
virtual TTaxId GetTaxId() const
Definition: cache.hpp:191
void SetSubtreeLoaded(bool b)
Definition: cache.hpp:214
virtual const string & GetName() const
Definition: cache.hpp:192
bool IsJoinTerminal() const
Definition: cache.hpp:209
virtual bool IsRoot() const
Definition: cache.hpp:204
virtual const string & GetBlastName() const
Definition: cache.hpp:193
virtual TTaxRank GetRank() const
Definition: utils.cpp:61
bool IsSubtreeLoaded() const
Definition: cache.hpp:212
CTaxon1Node * GetParent()
Definition: cache.hpp:217
void GetErrorText(string &err) const
CTaxon1_info –.
Definition: Taxon1_info.hpp:66
CTaxon1_req –.
Definition: Taxon1_req.hpp:66
CTaxon1_resp –.
Definition: Taxon1_resp.hpp:66
const string & GetLastError() const
Definition: taxon1.hpp:471
TTaxId GetMaxTaxId(void)
Definition: taxon1.cpp:2273
bool GetNodeProperty(TTaxId tax_id, const string &prop_name, bool &prop_val)
Definition: taxon1.cpp:1821
bool GetTaxId4GI(TGi gi, TTaxId &tax_id_out)
Definition: taxon1.cpp:1371
bool GetTypeMaterial(TTaxId tax_id, TNameList &type_material_list_out)
Definition: taxon1.cpp:2196
vector< TTaxId > TTaxIdList
Definition: taxon1.hpp:70
bool GetInheritedPropertyDefines(const string &prop_name, TInfoList &results_out, TTaxId subtree_root=TAX_ID_CONST(1))
Definition: taxon1.cpp:1927
CConstRef< COrg_ref > GetOrgRef(TTaxId tax_id, bool &is_species, bool &is_uncultured, string &blast_name, bool *is_specified=NULL)
Definition: taxon1.cpp:704
bool GetDivisionName(TTaxDivision div_id, string &div_name_out, string *div_code_out=NULL)
Definition: taxon1.cpp:1126
CRef< CTaxon2_data > GetById(TTaxId tax_id)
Definition: taxon1.cpp:230
COrgRefCache * m_plCache
Definition: taxon1.hpp:605
bool SendRequest(CTaxon1_req &req, CTaxon1_resp &resp, bool bShouldReconnect=true)
Definition: taxon1.cpp:1429
bool GetDisplayCommonName(TTaxId tax_id, string &disp_name_out)
Definition: taxon1.cpp:2296
TTaxRank GetRankIdByName(const string &rank_name)
Definition: taxon1.cpp:1105
static const unsigned def_reconnect_attempts
Definition: taxon1.hpp:83
~CTaxon1()
Definition: taxon1.cpp:71
TTaxId GetTaxIdByName(const string &orgname)
Definition: taxon1.cpp:523
bool GetPopsetJoin(const TTaxIdList &ids_in, TTaxIdList &ids_out)
Definition: taxon1.cpp:1546
TTaxId GetGenus(TTaxId id_tax)
Definition: taxon1.cpp:843
const char * m_pchService
Definition: taxon1.hpp:594
@ eSearch_WildCard
Definition: taxon1.hpp:184
@ eSearch_TokenSet
Definition: taxon1.hpp:183
@ eSearch_Exact
Definition: taxon1.hpp:182
@ eSearch_Phonetic
Definition: taxon1.hpp:185
TTaxId SearchTaxIdByName(const string &orgname, ESearch mode=eSearch_TokenSet, list< CRef< CTaxon1_name > > *name_list_out=NULL)
Definition: taxon1.cpp:595
void Reset(void)
Definition: taxon1.cpp:78
void Fini(void)
Definition: taxon1.cpp:203
STimeout * m_timeout
Definition: taxon1.hpp:595
bool LoadSubtreeEx(TTaxId tax_id, int type, const ITaxon1Node **ppNode)
Definition: taxon1.cpp:1639
CTaxon1()
Definition: taxon1.cpp:60
TTaxId GetTaxIdByOrgRef(const COrg_ref &inp_orgRef)
Definition: taxon1.cpp:489
@ eStatus_WrongCommonName
Definition: taxon1.hpp:158
@ eStatus_WrongTaxname
Definition: taxon1.hpp:156
@ eStatus_WrongOrgrefMod
Definition: taxon1.hpp:157
@ eStatus_WrongLineage
Definition: taxon1.hpp:161
@ eStatus_WrongMGC
Definition: taxon1.hpp:164
@ eStatus_WrongPGC
Definition: taxon1.hpp:165
@ eStatus_WrongOrgmod
Definition: taxon1.hpp:160
@ eStatus_WrongGC
Definition: taxon1.hpp:163
@ eStatus_Ok
Definition: taxon1.hpp:153
@ eStatus_WrongDivision
Definition: taxon1.hpp:162
@ eStatus_WrongOrgname
Definition: taxon1.hpp:159
@ eStatus_WrongOrgnameAttr
Definition: taxon1.hpp:166
@ eStatus_WrongTaxId
Definition: taxon1.hpp:154
CConstRef< CTaxon2_data > LookupMerge(COrg_ref &inp_orgRef, string *psLog=0, TOrgRefStatus *pStatusOut=0)
Definition: taxon1.cpp:429
friend class COrgRefCache
Definition: taxon1.hpp:591
TOrgRefStatus x_ConvertOrgrefProps(CTaxon2_data &data)
Definition: taxon1.cpp:271
TTaxId GetSpecies(TTaxId id_tax, ESpeciesMode mode=eSpeciesMode_Flag)
Definition: taxon1.cpp:789
list< string > TNameList
Definition: taxon1.hpp:69
TTaxId GetParent(TTaxId id_tax)
Definition: taxon1.cpp:761
ESerialDataFormat m_eDataFormat
Definition: taxon1.hpp:593
void SetLastError(const char *err_msg)
Definition: taxon1.cpp:1516
bool CheckOrgRef(const COrg_ref &orgRef, TOrgRefStatus &stat_out, string *psLog=0)
Definition: taxon1.cpp:2145
bool GetGCName(TTaxGeneticCode gc_id, string &gc_name_out)
Definition: taxon1.cpp:1036
CConn_ServiceStream * m_pServer
Definition: taxon1.hpp:598
bool DumpNames(TTaxNameClass name_class, list< CRef< CTaxon1_name > > &out)
Definition: taxon1.cpp:1327
bool SetSynonyms(bool on_off)
Definition: taxon1.cpp:746
TTaxId FindTaxIdByName(const string &orgname)
Definition: taxon1.cpp:548
TTaxId GetSuperkingdom(TTaxId id_tax)
Definition: taxon1.cpp:875
bool GetScientificName(TTaxId tax_id, string &name_out)
Definition: taxon1.cpp:2390
bool GetAllNamesEx(TTaxId tax_id, list< CRef< CTaxon1_name > > &lNames)
Definition: taxon1.cpp:1293
unsigned TOrgRefStatus
Definition: taxon1.hpp:113
EIteratorMode
Definition: taxon1.hpp:510
@ eIteratorMode_Blast
Definition: taxon1.hpp:516
@ eIteratorMode_FullTree
Definition: taxon1.hpp:511
@ eIteratorMode_LeavesBranches
Definition: taxon1.hpp:513
@ eIteratorMode_Best
Definition: taxon1.hpp:514
TGCMap m_gcStorage
Definition: taxon1.hpp:611
bool GetNameClass(TTaxNameClass nameclass_id, string &class_name_out)
Definition: taxon1.cpp:1176
STimeout m_timeout_value
Definition: taxon1.hpp:596
int GetAllTaxIdByName(const string &orgname, TTaxIdList &lIds)
Definition: taxon1.cpp:659
bool Init(void)
Definition: taxon1.cpp:101
int GetAllNames(TTaxId tax_id, TNameList &lNames, bool unique)
Definition: taxon1.cpp:1248
unsigned m_nReconnectAttempts
Definition: taxon1.hpp:603
TTaxDivision GetDivisionIdByName(const string &div_name)
Definition: taxon1.cpp:1154
TTaxNameClass GetNameClassId(const string &class_name)
Definition: taxon1.cpp:1199
CRef< ITreeIterator > GetTreeIterator(EIteratorMode mode=eIteratorMode_Default)
Definition: taxon1.cpp:1715
list< CRef< CTaxon1_info > > TInfoList
Definition: taxon1.hpp:71
bool GetRankName(TTaxRank rank_id, string &rank_name_out)
Definition: taxon1.cpp:1081
bool m_bWithSynonyms
Definition: taxon1.hpp:607
bool GetBlastName(TTaxId tax_id, string &blast_name_out)
Definition: taxon1.cpp:1405
TTaxId Join(TTaxId taxid1, TTaxId taxid2)
Definition: taxon1.cpp:1220
CObjectIStream * m_pIn
Definition: taxon1.hpp:601
ESpeciesMode
Definition: taxon1.hpp:270
@ eSpeciesMode_RankOnly
Definition: taxon1.hpp:271
static const unsigned def_cache_capacity
Definition: taxon1.hpp:84
string m_sLastError
Definition: taxon1.hpp:608
bool IsAlive(void)
Definition: taxon1.cpp:1354
TTaxId GetAncestorByRank(TTaxId id_tax, const char *rank_name)
Definition: taxon1.cpp:942
CObjectOStream * m_pOut
Definition: taxon1.hpp:600
CRef< CTaxon2_data > Lookup(const COrg_ref &inp_orgRef, string *psLog=0)
Definition: taxon1.cpp:384
int GetChildren(TTaxId id_tax, TTaxIdList &children_ids)
Definition: taxon1.cpp:992
bool GetProperty(const string &name, string &value) const
void SetProperty(const string &name, const string &value)
Definition: Taxon2_data.cpp:77
bool SetRoot(CTreeContNodeBase *root)
Definition: ctreecont.hpp:108
CTreeConstIterator * GetConstIterator() const
Definition: ctreecont.cpp:368
const CTreeContNodeBase * GetRoot() const
Definition: ctreecont.hpp:116
CTreeIterator * GetIterator()
Definition: ctreecont.cpp:362
Base class for all iterators over modifiable object.
Definition: iterator.hpp:480
bool GoSibling()
Definition: ctreecont.hpp:160
bool GoParent()
Definition: ctreecont.hpp:146
CTreeContNodeBase * GetNode() const
Definition: ctreecont.hpp:254
bool GoChild()
Definition: ctreecont.hpp:153
bool AddChild(CTreeContNodeBase *new_node)
Definition: ctreecont.cpp:84
bool GoNode(CTreeContNodeBase *node)
Definition: ctreecont.hpp:167
virtual TTaxId GetTaxId() const =0
virtual EAction LevelEnd(const ITaxon1Node *)
Definition: taxon1.hpp:769
virtual EAction LevelBegin(const ITaxon1Node *)
Definition: taxon1.hpp:766
virtual EAction Execute(const ITaxon1Node *pNode)=0
EAction TraverseLevelByLevel(I4Each &, unsigned levels=kMax_UInt)
Definition: taxon1.cpp:2044
virtual bool GoSibling()=0
virtual bool GoNode(const ITaxon1Node *pNode)=0
virtual const ITaxon1Node * GetNode() const =0
virtual bool GoChild()=0
EAction TraverseLevelByLevelInternal(I4Each &cb, unsigned levels, vector< const ITaxon1Node * > &skp)
Definition: taxon1.cpp:2063
EAction TraverseUpward(I4Each &, unsigned levels=kMax_UInt)
Definition: taxon1.cpp:2016
EAction TraverseAncestors(I4Each &)
Definition: taxon1.cpp:2118
EAction TraverseDownward(I4Each &, unsigned levels=kMax_UInt)
Definition: taxon1.cpp:1983
virtual bool GoParent()=0
virtual bool IsTerminal() const =0
virtual bool GoAncestor(const ITaxon1Node *pNode)=0
container_type::iterator iterator
Definition: map.hpp:54
const_iterator end() const
Definition: map.hpp:152
iterator_bool insert(const value_type &val)
Definition: map.hpp:165
bool empty() const
Definition: map.hpp:149
const_iterator find(const key_type &key) const
Definition: map.hpp:153
Definition: map.hpp:338
The NCBI C++ standard methods for dealing with std::string.
#define TAX_ID_CONST(id)
Definition: ncbimisc.hpp:1112
#define ZERO_TAX_ID
Definition: ncbimisc.hpp:1115
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define INVALID_TAX_ID
Definition: ncbimisc.hpp:1116
#define TAX_ID_TO(T, tax_id)
Definition: ncbimisc.hpp:1110
Int8 TIntId
Definition: ncbimisc.hpp:999
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
Definition: ncbimisc.hpp:822
SStrictId_Tax::TId TTaxId
Taxon id type.
Definition: ncbimisc.hpp:1048
#define TAX_ID_FROM(T, value)
Definition: ncbimisc.hpp:1111
#define NULL
Definition: ncbistd.hpp:225
#define ERR_POST_X(err_subcode, message)
Error posting with default error code and given error subcode.
Definition: ncbidiag.hpp:550
@ eFNP_Allow
pass through unchanged, post no error message
Definition: serialdef.hpp:175
@ eSerial_AsnText
ASN.1 text.
Definition: serialdef.hpp:73
@ eSerial_AsnBinary
ASN.1 binary.
Definition: serialdef.hpp:74
static CObjectOStream * Open(ESerialDataFormat format, CNcbiOstream &outStream, bool deleteOutStream)
Create serial object writer and attach it to an output stream.
Definition: objostr.cpp:126
static CObjectIStream * Open(ESerialDataFormat format, CNcbiIstream &inStream, bool deleteInStream)
Create serial object reader and attach it to an input stream.
Definition: objistr.cpp:195
bool InGoodState(void)
Check fail flags and also the state of input data source.
Definition: objistr.cpp:570
bool InGoodState(void)
Check fail flags and also the state of output stream.
Definition: objostr.cpp:386
TFailFlags GetFailFlags(void) const
Get fail flags.
TFailFlags GetFailFlags(void) const
Get fail flags.
void Flush(void)
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
@ fSERV_Any
Definition: ncbi_service.h:79
static bool StringToBool(const CTempString str)
Convert string to bool.
Definition: ncbistr.cpp:2819
static list< string > & Split(const CTempString str, const CTempString delim, list< string > &arr, TSplitFlags flags=0, vector< SIZE_TYPE > *token_pos=NULL)
Split a string using specified delimiters.
Definition: ncbistr.cpp:3457
static bool EndsWith(const CTempString str, const CTempString end, ECase use_case=eCase)
Check if a string ends with a specified suffix value.
Definition: ncbistr.hpp:5429
static void TruncateSpacesInPlace(string &str, ETrunc where=eTrunc_Both)
Truncate spaces in a string (in-place)
Definition: ncbistr.cpp:3197
static bool StartsWith(const CTempString str, const CTempString start, ECase use_case=eCase)
Check if a string starts with a specified prefix value.
Definition: ncbistr.hpp:5411
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:5352
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:5383
@ fSplit_Tokenize
All delimiters are merged and trimmed, to get non-empty tokens only.
Definition: ncbistr.hpp:2508
int ConnNetInfo_SetTimeout(SConnNetInfo *net_info, const STimeout *timeout)
unsigned short max_try
SConnNetInfo * ConnNetInfo_Create(const char *service)
void ConnNetInfo_Destroy(SConnNetInfo *net_info)
TDb & SetDb(void)
Assign a value to Db data member.
Definition: Org_ref_.hpp:497
bool IsSetSubspecies(void) const
Check if a value has been assigned to Subspecies data member.
const TBinomial & GetBinomial(void) const
Get the variant data.
Definition: OrgName_.cpp:121
const TSpecies & GetSpecies(void) const
Get the Species member data.
bool IsSetSpecies(void) const
species required if subspecies used Check if a value has been assigned to Species data member.
const TSubspecies & GetSubspecies(void) const
Get the Subspecies member data.
bool IsBinomial(void) const
Check if variant Binomial is selected.
Definition: OrgName_.hpp:715
TTaxachildren & SetTaxachildren(void)
Select the variant.
const TFindname & GetFindname(void) const
Get the variant data.
TGetidbyorg GetGetidbyorg(void) const
Get the variant data.
bool IsSetLevel(void) const
Check if a value has been assigned to Level data member.
bool IsLookup(void) const
Check if variant Lookup is selected.
TDumpnames4class & SetDumpnames4class(void)
Select the variant.
TGetunique GetGetunique(void) const
Get the variant data.
TBlast_name & SetBlast_name(void)
Assign a value to Blast_name data member.
void SetIs_species_level(TIs_species_level value)
Assign a value to Is_species_level data member.
bool IsSetMsg(void) const
Check if a value has been assigned to Msg data member.
TTaxachildren & SetTaxachildren(void)
Select the variant.
const TGetorgnames & GetGetorgnames(void) const
Get the variant data.
TIs_species_level GetIs_species_level(void) const
Get the Is_species_level member data.
const TOrg & GetOrg(void) const
Get the Org member data.
TGetorgprop & SetGetorgprop(void)
Select the variant.
bool IsGetorgprop(void) const
Check if variant Getorgprop is selected.
void SetOrg(TOrg &value)
Assign a value to Org data member.
TGetorgnames & SetGetorgnames(void)
Select the variant.
const TSearchname & GetSearchname(void) const
Get the variant data.
bool IsSetBlast_name(void) const
inherited blast name Check if a value has been assigned to Blast_name data member.
bool IsId4gi(void) const
Check if variant Id4gi is selected.
const TOrg & GetOrg(void) const
Get the Org member data.
TIs_uncultured GetIs_uncultured(void) const
Get the Is_uncultured member data.
TLevel GetLevel(void) const
Get the Level member data.
const TBlast_name & GetBlast_name(void) const
Get the Blast_name member data.
bool IsSetIs_species_level(void) const
species level or below Check if a value has been assigned to Is_species_level data member.
bool IsDumpnames4class(void) const
Check if variant Dumpnames4class is selected.
TLookup & SetLookup(void)
Select the variant.
TSearchname & SetSearchname(void)
Select the variant.
bool IsTaxachildren(void) const
Check if variant Taxachildren is selected.
void SetInit(void)
Select the variant.
bool IsGetgcs(void) const
Check if variant Getgcs is selected.
void SetIs_uncultured(TIs_uncultured value)
Assign a value to Is_uncultured data member.
TFindname & SetFindname(void)
Select the variant.
TGetunique & SetGetunique(void)
Select the variant.
void SetGetgcs(void)
Select the variant.
bool IsGetidbyorg(void) const
Check if variant Getidbyorg is selected.
bool IsGetunique(void) const
Check if variant Getunique is selected.
TId4gi GetId4gi(void) const
Get the variant data.
TId4gi & SetId4gi(void)
Select the variant.
bool IsInit(void) const
Check if variant Init is selected.
const TMsg & GetMsg(void) const
Get the Msg member data.
TSearchname & SetSearchname(void)
Select the variant.
TDumpnames4class & SetDumpnames4class(void)
Select the variant.
void SetFini(void)
Select the variant.
bool IsSearchname(void) const
Check if variant Searchname is selected.
const TGetorgprop & GetGetorgprop(void) const
Get the variant data.
bool IsError(void) const
Check if variant Error is selected.
const TError & GetError(void) const
Get the variant data.
const TLookup & GetLookup(void) const
Get the variant data.
const TGetgcs & GetGetgcs(void) const
Get the variant data.
bool IsFini(void) const
Check if variant Fini is selected.
bool IsGetorgnames(void) const
Check if variant Getorgnames is selected.
TGetorgprop & SetGetorgprop(void)
Select the variant.
TGetidbyorg & SetGetidbyorg(void)
Select the variant.
bool IsFindname(void) const
Check if variant Findname is selected.
list< CRef< CTaxon1_name > > TSearchname
bool IsSetIs_uncultured(void) const
belongs to environmental bin Check if a value has been assigned to Is_uncultured data member.
@ eLevel_none
not an error, just a message
Definition of all error codes used in objects libraries.
int i
mdb_mode_t mode
Definition: lmdb++.h:38
unsigned int a
Definition: ncbi_localip.c:102
static char tmp[2048]
Definition: utf8.c:42
Timeout structure.
Definition: ncbi_types.h:76
static bool s_GetBoolValue(const CObject_id &val)
Definition: taxon1.cpp:255
#define TAXON1_IS_INITED
Definition: taxon1.cpp:57
static const STimeout def_timeout
Definition: taxon1.cpp:98
vector< CTaxon1Node * > TTaxNodeLineage
Definition: taxon1.cpp:1544
static void s_StoreResidueTaxid(CTreeIterator *pIt, CTaxon1::TTaxIdList &lTo)
Definition: taxon1.cpp:1524
static const char s_achInvalTaxid[]
Definition: taxon1.cpp:55
short int TTaxDivision
Definition: taxon1.hpp:59
short int TTaxRank
Primitive types for some taxon1 object fields.
Definition: taxon1.hpp:52
short int TTaxGeneticCode
Definition: taxon1.hpp:60
short int TTaxNameClass
Definition: taxon1.hpp:61
else result
Definition: token2.c:20
Modified on Tue Dec 05 02:08:24 2023 by modify_doxy.py rev. 669887