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

Go to the SVN repository for this file.

1 /* $Id: blastxml2_format.cpp 92020 2020-12-17 15:27:44Z grichenk $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's offical 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:Amelia Fong
27 *
28 * ===========================================================================
29 */
30 
31 /// @file blastxml2_format.cpp
32 /// Formatting of BLAST results in XML2 form, using the BLAST XML2 specification.
33 
34 #include <ncbi_pch.hpp>
37 #include <objmgr/util/sequence.hpp>
39 
43 
49 
50 
52 #include <serial/objostrxml.hpp>
53 #include <serial/objostrjson.hpp>
54 
56 #include <sstream>
57 
58 #include <algorithm>
59 
62 USING_SCOPE(blast);
63 USING_SCOPE(align_format);
64 
65 
66 /// Returns translation frame given the strand, alignment endpoints and
67 /// total sequence length.
68 /// @param plus_strand Is this position on a forward strand? [in]
69 /// @param start Starting position, in 1-offset coordinates. [in]
70 /// @param end Ending position in 1-offset coordinates [in]
71 /// @param seq_length Total length of sequence [in]
72 /// @return Frame number.
73 static int
74 s_GetTranslationFrame(bool plus_strand, int start, int end, int seq_length)
75 {
76  int frame;
77 
78  if (plus_strand) {
79  frame = (start - 1) % 3 + 1;
80  } else {
81  frame = -((seq_length - end) % 3 + 1);
82  }
83 
84  return frame;
85 }
86 
87 /// Creates a list of blastxml2::CHsp structures for the XML output, given a list of
88 /// Seq-aligns.
89 /// @param xhsp_list List of blastxml2::CHsp's to populate [in] [out]
90 /// @param alnset Set of alignments to get data from [in]
91 /// @param scope Scope for retrieving sequences [in]
92 /// @param matrix 256x256 matrix for calculating positives for a protein search.
93 /// NULL is passed for a nucleotide search.
94 /// @param mask_info Masking locations [in]
95 static void
97  const CSeq_align_set& alnset, CRef<CScope> scope,
98  const CBlastFormattingMatrix* matrix,
99  const ncbi::TMaskedQueryRegions & mask_info,
100  int master_gentic_code, int slave_genetic_code)
101 {
102  int index = 1;
103  ITERATE(CSeq_align_set::Tdata, iter, alnset.Get()) {
104  CRef<blastxml2::CHsp> xhsp(new blastxml2::CHsp());
105  const CSeq_align& kAlign = *(*iter);
106  xhsp->SetNum(index);
107  ++index;
108  bool query_is_na, subject_is_na;
109  int query_length, subject_length;
110 
111  int score, num_ident;
112  double bit_score;
113  double evalue;
114  int sum_n;
115  list<TGi> use_this_gi;
116  CBlastFormatUtil::GetAlnScores(kAlign, score, bit_score, evalue, sum_n,
117  num_ident, use_this_gi);
118 
119  //Print 6 significant digits for double values
120  char tmp[512];
121  sprintf(tmp,"%.*g", 6, bit_score );
122  bit_score = atof(tmp);
123  sprintf(tmp,"%.*g", 6, evalue );
124  evalue = atof(tmp);
125 
126  xhsp->SetBit_score(bit_score);
127  xhsp->SetScore(score);
128  xhsp->SetEvalue(evalue);
129 
130  // Extract the full list of subject ids
131  try {
132  const CBioseq_Handle& kQueryBioseqHandle =
133  scope->GetBioseqHandle(kAlign.GetSeq_id(0));
134  query_is_na = kQueryBioseqHandle.IsNa();
135  query_length = kQueryBioseqHandle.GetBioseqLength();
136  const CBioseq_Handle& kSubjBioseqHandle =
137  scope->GetBioseqHandle(kAlign.GetSeq_id(1));
138  subject_is_na = kSubjBioseqHandle.IsNa();
139  subject_length = kSubjBioseqHandle.GetBioseqLength();
140  } catch (const CException&) {
141  // Either query or subject sequence not found - the remaining
142  // information cannot be correctly filled. Add this HSP as is
143  // and continue.
144  xhsp->SetQuery_from(0);
145  xhsp->SetQuery_to(0);
146  xhsp->SetHit_from(0);
147  xhsp->SetHit_to(0);
148  xhsp->SetIdentity(num_ident); // This may be inaccurate when
149  // alignment contains filtered regions.
150  xhsp->SetQseq(NcbiEmptyString);
151  xhsp->SetHseq(NcbiEmptyString);
152  xhsp_list.push_back(xhsp);
153  continue;
154  }
155 
156  CRef<CSeq_align> final_aln(0);
157 
158  // Convert Std-seg and Dense-diag alignments to Dense-seg.
159  // Std-segs are produced only for translated searches; Dense-diags only
160  // for ungapped, not translated searches.
161  const bool kTranslated = kAlign.GetSegs().IsStd();
162  if (kTranslated) {
163  CRef<CSeq_align> densegAln = kAlign.CreateDensegFromStdseg();
164  // When both query and subject are translated, i.e. tblastx, convert
165  // to a special type of Dense-seg.
166  if (query_is_na && subject_is_na)
167  final_aln = densegAln->CreateTranslatedDensegFromNADenseg();
168  else
169  final_aln = densegAln;
170  } else if (kAlign.GetSegs().IsDendiag()) {
171  final_aln = CBlastFormatUtil::CreateDensegFromDendiag(kAlign);
172  }
173 
174  const CDense_seg& kDenseg = (final_aln ? final_aln->GetSegs().GetDenseg() :
175  kAlign.GetSegs().GetDenseg());
176 
177 
178 
179 
180  // Do not trust the identities count in the Seq-align, because if masking
181  // was used, then masked residues were not counted as identities.
182  // Hence retrieve the sequences present in the alignment and count the
183  // identities again.
184  string query_seq;
185  string subject_seq;
186  string middle_seq;
187  string masked_query_seq;
188 
189  // For blastn search, the matches are shown as '|', and mismatches as
190  // ' '; For all other searches matches are shown as matched characters,
191  // mismatches as ' ', and positives as '+'.
192  // This is a blastn search if and only if both query and subject are
193  // nucleotide, and it is not a translated search.
194  const bool kIsBlastn =
195  (query_is_na && subject_is_na && !kTranslated);
196 
197  const CDense_seg * ds_pt = &kDenseg;
198  CRef<CDense_seg> reversed_ds;
199  // For non-transalted reverse strand alignments, show plus strand on
200  // query and minus strand on subject. To accomplish this, Dense-seg must
201  // be reversed.
202  if (!kTranslated && kDenseg.IsSetStrands() &&
203  kDenseg.GetStrands().front() == eNa_strand_minus)
204  {
205  reversed_ds.Reset(new CDense_seg);
206  reversed_ds->Assign(kDenseg);
207  reversed_ds->Reverse();
208  ds_pt = &(*reversed_ds);
209  }
210 
211  int q_start, q_end, s_start, s_end, q_frame=0, s_frame=0;
212 
213  unsigned int num_gaps = 0;
214  int align_length = 0;
215 
216  if (kAlign.GetSegs().IsDendiag())
217  {
218  align_length = final_aln->GetAlignLength();
219  q_start = final_aln->GetSeqStart(0) + 1;
220  q_end = final_aln->GetSeqStop(0) + 1;
221  s_start = final_aln->GetSeqStart(1) + 1;
222  s_end = final_aln->GetSeqStop(1) + 1;
223  }
224  else
225  {
226  if(!kTranslated)
227  {
228  num_gaps = kAlign.GetTotalGapCount();
229  align_length = kAlign.GetAlignLength();
230  }
231  q_start = kAlign.GetSeqStart(0) + 1;
232  q_end = kAlign.GetSeqStop(0) + 1;
233  s_start = kAlign.GetSeqStart(1) + 1;
234  s_end = kAlign.GetSeqStop(1) + 1;
235  }
236 
237  if (!kTranslated && query_is_na && subject_is_na) {
238  xhsp->SetQuery_strand("Plus");
239  xhsp->SetHit_strand("Plus");
240  if (eNa_strand_minus == kAlign.GetSeqStrand(0)){
241  xhsp->SetHit_strand("Minus");
242  int tmp = s_start;
243  s_start = s_end;
244  s_end = tmp;
245  }
246 
247  } else if (kTranslated) {
248  align_length = final_aln->GetAlignLength();
249  num_gaps = final_aln->GetTotalGapCount();
250 
251  if (query_is_na) {
252  q_frame = s_GetTranslationFrame(eNa_strand_minus != final_aln->GetSeqStrand(0),
253  q_start, q_end, query_length);
254  xhsp->SetQuery_frame(q_frame);
255  }
256  if (subject_is_na) {
257  s_frame = s_GetTranslationFrame(eNa_strand_minus != final_aln->GetSeqStrand(1),
258  s_start, s_end, subject_length);
259  xhsp->SetHit_frame(s_frame);
260  }
261  }
262 
263  xhsp->SetQuery_from(q_start);
264  xhsp->SetQuery_to(q_end);
265  xhsp->SetHit_from(s_start);
266  xhsp->SetHit_to(s_end);
267 
268  if (mask_info.empty())
269  {
271  subject_seq,
272  *ds_pt,
273  *scope,
274  master_gentic_code,
275  slave_genetic_code);
276  }
277  else
278  {
281  masked_query_seq,
282  subject_seq,
283  *ds_pt,
284  *scope,
285  master_gentic_code,
286  slave_genetic_code,
287  mask_info,
288  kMaskCharOpt,
289  q_frame);
290  }
291 
292  num_ident = 0;
293  int num_positives = 0;
294  middle_seq = query_seq;
295  // The query and subject sequence strings must be the same size in a
296  // correct alignment, but if alignment extends beyond the end of sequence
297  // because of a bug, one of the sequence strings may be truncated, hence
298  // it is necessary to take a minimum here.
299  // FIXME: Should an exception be thrown instead?
300  const unsigned int kMaxOffset = min(query_seq.size(),
301  subject_seq.size());
302  for (unsigned int i = 0; i < kMaxOffset; ++i) {
303  if (query_seq[i] == subject_seq[i]) {
304  ++num_ident;
305  ++num_positives;
306  if (kIsBlastn)
307  middle_seq[i] = '|';
308  } else if (matrix &&
309  (*matrix)(query_seq[i], subject_seq[i]) > 0 &&
310  !kIsBlastn) {
311  ++num_positives;
312  middle_seq[i] = kIsBlastn ? ' ' : '+';
313  } else {
314  middle_seq[i] = ' ';
315  }
316  }
317 
318  xhsp->SetIdentity(num_ident);
319  xhsp->SetGaps(num_gaps);
320  xhsp->SetAlign_len(align_length);
321 
322  if (mask_info.empty())
323  xhsp->SetQseq(query_seq);
324  else
325  xhsp->SetQseq(masked_query_seq);
326  xhsp->SetHseq(subject_seq);
327  xhsp->SetMidline(middle_seq);
328  if(!(query_is_na && subject_is_na && !kTranslated) )
329  xhsp->SetPositive(num_positives);
330 
331  xhsp_list.push_back(xhsp);
332  }
333 }
334 
335 /// Fill the blastxml2::CHit object in BLAST XML output, given an alignment and other
336 /// information.
337 /// @param hit blastxml2::CHit object to fill [in] [out]
338 /// @param align_in Sequence alignment [in]
339 /// @param scope Scope for retrieving sequences [in]
340 /// @param matrix ASCII-alphabet matrix for calculation of positives [in]
341 /// @param mask_info List of masking locations [in]
342 /// @param ungapped Is this an ungapped search? [in]
343 /// @param master_genetic_code query genetic code [in]
344 /// @param slave_genetic_code subject genetic code [in]
345 /// @param hasTaxDB Have access to taxonomy file [in]
346 static void
348  const CSeq_align& align_in, CRef<CScope> scope,
349  const CBlastFormattingMatrix* matrix,
350  const ncbi::TMaskedQueryRegions & mask_info,
351  bool ungapped, int master_gentice_code,
352  int slave_genetic_code, bool hasTaxDB)
353 {
354  _ASSERT(align_in.GetSegs().IsDisc());
355  const CSeq_align_set& kAlignSet = align_in.GetSegs().GetDisc();
356 
357  const CSeq_id& kSeqId = kAlignSet.Get().front()->GetSeq_id(1);
358 
359  try {
360  const CBioseq_Handle& subj_handle = scope->GetBioseqHandle(kSeqId);
361 
363  list <CRef<blastxml2::CHitDescr> > & descr_list = hit->SetDescription();
364 
365  if(bdlRef.NotEmpty() && bdlRef->IsSet() && (!bdlRef->Get().empty())) {
366  ITERATE(list<CRef<CBlast_def_line> >, itr, bdlRef->Get()) {
367  const CBlast_def_line & defline = **itr;
368  CRef<blastxml2::CHitDescr> hit_exp(new blastxml2::CHitDescr);
369  hit_exp->SetId(CShowBlastDefline::GetSeqIdListString(defline.GetSeqid(), true));
370 
371  CRef<CSeq_id> best_id = FindBestChoice(defline.GetSeqid(), CSeq_id::Score);
372  CSeq_id_Handle id_handle = CSeq_id_Handle::GetHandle(*best_id);
373  string accession = CAlignFormatUtil::GetLabel(id_handle.GetSeqId());
374  if(accession != kEmptyStr)
375  hit_exp->SetAccession(accession);
376 
377  if(defline.IsSetTitle())
378  hit_exp->SetTitle(defline.GetTitle());
379 
380  if(defline.IsSetTaxid() && defline.GetTaxid() != ZERO_TAX_ID) {
381  TTaxId tax_id = defline.GetTaxid();
382  hit_exp->SetTaxid(tax_id);
383  if(hasTaxDB) {
384  SSeqDBTaxInfo taxinfo;
385  CSeqDB::GetTaxInfo(tax_id, taxinfo);
386  hit_exp->SetSciname(taxinfo.scientific_name);
387  }
388  }
389  descr_list.push_back(hit_exp);
390  }
391  }
392  else {
393  CRef<blastxml2::CHitDescr> hit_exp(new blastxml2::CHitDescr);
394  list<CRef<objects::CSeq_id> > ids;
395  CShowBlastDefline::GetSeqIdList(subj_handle, ids);
396  hit_exp->SetId(CShowBlastDefline::GetSeqIdListString(ids, true));
398  if(!best_id->IsLocal()) {
399  CSeq_id_Handle id_handle = CSeq_id_Handle::GetHandle(*best_id);
400  string accession = CAlignFormatUtil::GetLabel(id_handle.GetSeqId());
401  if(accession != kEmptyStr)
402  hit_exp->SetAccession(accession);
403  }
404 
405  hit_exp->SetTitle(sequence::CDeflineGenerator().GenerateDefline(subj_handle));
406  descr_list.push_back(hit_exp);
407  }
408 
409 
410  int length = subj_handle.GetBioseqLength();
411  hit->SetLen(length);
412  } catch (const CException&) {
413  CRef<blastxml2::CHitDescr> hit_exp(new blastxml2::CHitDescr);
414  hit_exp->SetId(kSeqId.AsFastaString());
415  hit->SetDescription().push_back(hit_exp);
416  hit->SetLen(sequence::GetLength(kSeqId, scope));
417  };
418 
419  // For ungapped search, multiple HSPs, possibly from different strands,
420  // are packed into a single Seq-align.
421  // The C++ utility functions cannot deal with such Seq-aligns, as they
422  // expect one Seq-align per alignment (HSP). Hence we need to expand the
423  // Seq-align-set obtained for an ungapped search.
424  if (ungapped) {
425  CRef<CSeq_align_set> expanded_align_set =
427 
428  s_SeqAlignSetToXMLHsps(hit->SetHsps(), *expanded_align_set, scope,
429  matrix, mask_info, master_gentice_code, slave_genetic_code);
430  } else {
431  s_SeqAlignSetToXMLHsps(hit->SetHsps(), kAlignSet, scope, matrix,
432  mask_info, master_gentice_code, slave_genetic_code);
433  }
434 }
435 
436 /// Retrieves subject Seq-id from a Seq-align
437 /// @param align Seq-align object [in]
438 /// @return Subject Seq-id for this Seq-align.
439 static const CSeq_id*
441 {
442  if (align.GetSegs().IsDenseg()) {
443  return align.GetSegs().GetDenseg().GetIds()[1];
444  } else if (align.GetSegs().IsDendiag()) {
445  return align.GetSegs().GetDendiag().front()->GetIds()[1];
446  } else if (align.GetSegs().IsStd()) {
447  return align.GetSegs().GetStd().front()->GetIds()[1];
448  }
449 
450  return NULL;
451 }
452 
453 
454 
455 
456 /// Fills the list of blastxml2::CHit objects, given a list of Seq-aligns.
457 /// @param hits List of blastxml2::CHit objects to fill [in] [out]
458 
459 static void
461 {
462 
463 
464  CConstRef<objects::CSeq_align_set> alnset = data->GetAlignmentSet(num);
465  CSeq_align_set::Tdata::const_iterator iter = alnset->Get().begin();
466 
467  CRef<CScope> scope = data->GetScope();
468  const CBlastFormattingMatrix* matrix = data->GetMatrix();
469  const ncbi::TMaskedQueryRegions & mask_info = data->GetMaskLocations();
470  bool ungapped = !(data->IsGappedSearch());
471  int master_gentice_code = data->GetQueryGeneticCode();
472  int slave_genetic_code = data->GetDbGeneticCode();
473  bool hasTaxDB = data->CanGetTaxInfo();
474 
475  int index = 1;
476  while (iter != alnset->Get().end()) {
477  CRef<blastxml2::CHit> new_hit(new blastxml2::CHit);
478  new_hit->SetNum(index);
479  index ++;
480  // Retrieve the next set of results for a single subject sequence.
481  // If the next Seq-align is discontinuous, then take it as is,
482  // otherwise go along the chain of Seq-aligns until the subject Seq-id
483  // changes, then wrap the single subject list into a discontinuous
484  // Seq-align.
485  if ((*iter)->GetSegs().IsDisc()) {
486  s_SeqAlignToXMLHit(new_hit, *(*iter), scope, matrix, mask_info,
487  ungapped, master_gentice_code, slave_genetic_code, hasTaxDB);
488  ++iter;
489  } else {
490  CSeq_align_set one_subject_alnset;
491  CConstRef<CSeq_id> current_id(s_GetSubjectId(*(*iter)));
492  for ( ; iter != alnset->Get().end(); ++iter) {
493  CConstRef<CSeq_id> next_id(s_GetSubjectId(*(*iter)));
494  if (!current_id->Match(*next_id)) {
495  break;
496  }
497  one_subject_alnset.Set().push_back(*iter);
498  }
499  CSeq_align disc_align_wrap;
500  disc_align_wrap.SetSegs().SetDisc(one_subject_alnset);
501  s_SeqAlignToXMLHit(new_hit, disc_align_wrap, scope, matrix,
502  mask_info, ungapped, master_gentice_code, slave_genetic_code, hasTaxDB);
503  }
504 
505  hits.push_back(new_hit);
506  }
507 }
508 
509 
510 /// Fills the parameters part of the BLAST XML output.
511 /// @param bxmlout BLAST XML output object [in] [out]
512 /// @param data Data structure, from which all necessary information can be
513 /// retrieved [in]
514 static void
515 s_SetBlastXMLParameters(blastxml2::CParameters & params, const IBlastXML2ReportData* data)
516 {
517  string matrix_name = data->GetMatrixName();
518  if (matrix_name != NcbiEmptyString)
519  params.SetMatrix(matrix_name);
520 
521  params.SetExpect(data->GetEvalueThreshold());
522 
523  int val;
524  string str;
525  if ((val = data->GetMatchReward()) != 0)
526  params.SetSc_match(val);
527 
528  if ((val = data->GetMismatchPenalty()) != 0)
529  params.SetSc_mismatch(val);
530 
531  if(data->IsGappedSearch()) {
532  params.SetGap_open(data->GetGapOpeningCost());
533  params.SetGap_extend(data->GetGapExtensionCost());
534  }
535  if ((str = data->GetPHIPattern()) != NcbiEmptyString)
536  params.SetPattern(str);
537 
538  if ((str = data->GetFilterString()) != NcbiEmptyString)
539  params.SetFilter(str);
540 
541  if ((str = data->GetBl2seqMode()) != NcbiEmptyString)
542  params.SetBl2seq_mode(str);
543 
544  if((val = data->GetCompositionBasedStats()) != 0)
545  params.SetCbs(val);
546 
547  if((str = data->GetEntrezQuery()) != NcbiEmptyString)
548  params.SetEntrez_query(str);
549 
550  if((val = data->GetQueryGeneticCode()) != 0)
551  params.SetQuery_gencode(val);
552 
553  if((val = data->GetDbGeneticCode()) != 0)
554  params.SetDb_gencode(val);
555 }
556 
557 /// Fills the search statistics part of the BLAST XML output for all queries.
558 /// @param stat_vec Vector of the blastxml2::CStatics objects, to be filled. [in] [out]
559 /// @param data Data structure, from which all necessary information can be
560 /// retrieved [in]
561 static void
562 s_SetBlastXMLStatistics(blastxml2::CStatistics & stats,
563  const IBlastXML2ReportData* data, int num)
564 {
565  if(!data->IsBl2seq()) {
566  stats.SetDb_num(data->GetDbNumSeqs());
567  stats.SetDb_len(data->GetDbLength());
568  }
569 
570  stats.SetHsp_len(data->GetLengthAdjustment(num));
571  stats.SetEff_space(data->GetEffectiveSearchSpace(num));
572  stats.SetKappa(data->GetKappa(num));
573  stats.SetLambda(data->GetLambda(num));
574  stats.SetEntropy(data->GetEntropy(num));
575 }
576 
577 
578 static void
579 s_SetBlastXMLSearch(blastxml2::CSearch & search,
580  const IBlastXML2ReportData* data, int num)
581 {
582  CConstRef<objects::CSeq_loc> q_loc = data->GetQuerySeqLoc();
583  const CSeq_id * q_id = q_loc->GetId();
584  CRef<CScope> scope = data->GetScope();
585  try {
586  CBioseq_Handle bh = scope->GetBioseqHandle(*q_id);
587  // Get the full query Seq-id string.
588  const CBioseq& q_bioseq = *bh.GetBioseqCore();
589  search.SetQuery_id(CBlastFormatUtil::GetSeqIdString(q_bioseq));
590  string q_title = sequence::CDeflineGenerator().GenerateDefline(bh);
591  if(q_title != kEmptyStr)
592  search.SetQuery_title(q_title);
593  } catch (const CException&) {
594  search.SetQuery_id(q_id->AsFastaString());
595  }
596 
597  search.SetQuery_len(sequence::GetLength(*q_loc, &(*scope)));
598 
599  if(!data->GetMaskLocations().empty()) {
600  list<CRef< blastxml2::CRange> > & masks = search.SetQuery_masking();
601  TMaskedQueryRegions mask_locs = data->GetMaskLocations();
602  ITERATE(TMaskedQueryRegions, itr, mask_locs) {
603  CRef<CSeqLocInfo> loc = *itr;
604  if(loc->GetStrand() == eNa_strand_minus)
605  continue;
606  CRef<blastxml2::CRange> rng (new blastxml2::CRange);
607  rng->SetFrom(loc->GetInterval().GetFrom());
608  rng->SetTo(loc->GetInterval().GetTo());
609  masks.push_back(rng);
610  }
611  }
612 
613  blastxml2::CStatistics & stats = search.SetStat();
615 
616  string msg = data->GetMessages(num);
617  // Check if the list is empty. Then there is nothing to fill.
618  if (data->GetAlignmentSet(num).Empty()) {
619  msg += " \n";
620  msg += CBlastFormatUtil::kNoHitsFound;
621  search.SetMessage(msg);
622  return;
623  }
624 
625  if(msg != kEmptyStr)
626  search.SetMessage(msg);
627 
628  list<CRef<blastxml2::CHit> > & hit_list = search.SetHits();
629  s_SetBlastXMlHitList(hit_list, data, num);
630 }
631 
632 /// Given BLAST task, returns enumerated value for the publication to be
633 /// referenced.
634 /// @param program BLAST task [in]
635 /// @return What publication to reference?
638 {
640 
641  switch (program) {
642  case eMegablast:
643  publication = CReference::eMegaBlast; break;
644  case ePHIBlastp: case ePHIBlastn:
645  publication = CReference::ePhiBlast; break;
646  case ePSIBlast:
647  publication = CReference::eCompBasedStats; break;
648  case eDeltaBlast:
649  publication = CReference::eDeltaBlast; break;
650  default:
651  publication = CReference::eGappedBlast; break;
652  }
653  return publication;
654 }
655 
656 static void s_FillBlastOutput(blastxml2::CBlastOutput2 & bxmlout, const IBlastXML2ReportData* data)
657 {
658  if(data == NULL)
659  NCBI_THROW(CException, eUnknown, "blastxml2: NULL XML2ReportData pointer");
660 
661  bxmlout.Reset();
662  blastxml2::CReport & report = bxmlout.SetReport();
663  string program_name = data->GetBlastProgramName();
664  report.SetProgram(program_name);
665  report.SetVersion(CBlastFormatUtil::BlastGetVersion(program_name));
666  EProgram blast_task = data->GetBlastTask();
667  report.SetReference(CReference::GetString(s_GetBlastPublication(blast_task)));
668  if(!data->GetSubjectIds().empty()) {
669  report.SetSearch_target().SetSubjects() = data->GetSubjectIds();
670  }
671  else {
672  report.SetSearch_target().SetDb(data->GetDatabaseName());
673  }
674 
675  blastxml2::CParameters & params = report.SetParams();
676  s_SetBlastXMLParameters(params, data);
677 
678  blastxml2::CResults & results = report.SetResults();
679  if(data->IsBl2seq()) {
680  list<CRef<blastxml2::CSearch> > & bl2seq = results.SetBl2seq();
681  for(int i=0; i < data->GetNumOfSearchResults(); i++ ) {
682  CRef<blastxml2::CSearch> search (new blastxml2::CSearch);
683  s_SetBlastXMLSearch(*search, data, i);
684  bl2seq.push_back(search);
685  }
686 
687  }
688  else if(data->IsIterativeSearch()) {
689  list<CRef<blastxml2::CIteration> > & iterations = results.SetIterations();
690  for(int i=0; i < data->GetNumOfSearchResults(); i++ ) {
691  CRef<blastxml2::CIteration> itr (new blastxml2::CIteration);
692  itr->SetIter_num(i+1);
693  blastxml2::CSearch & search = itr->SetSearch();
694  s_SetBlastXMLSearch(search, data, i);
695  iterations.push_back(itr);
696  }
697  }
698  else {
699  blastxml2::CSearch & search = results.SetSearch();
700  s_SetBlastXMLSearch(search, data, 0);
701  }
702 
703 }
705 {
706 public:
707 
709  : CObjectOStreamXml(stream , deleteOut) {}
710  virtual ~CBlastOStreamXml (void) {};
711  // WriteFileHeader() is a dummy to keep xml prolog, doctype
712  // from being printed with each object
713  virtual void WriteFileHeader(TTypeInfo type) {;};
714 };
715 
716 static void
717 s_WriteXML2ObjectNoHeader(blastxml2::CBlastOutput2 & bxmlout, CNcbiOstream *out_stream)
718 {
719  TTypeInfo typeInfo = bxmlout.GetThisTypeInfo();
720  unique_ptr<CBlastOStreamXml> xml_out(new CBlastOStreamXml (*out_stream, eNoOwnership));
721  xml_out->SetEncoding(eEncoding_Ascii);
722  xml_out->SetVerifyData( eSerialVerifyData_No );
723  xml_out->SetEnforcedStdXml();
724  xml_out->Write(&bxmlout, typeInfo );
725 }
726 
727 
728 static void
729 s_WriteXML2Object(blastxml2::CBlastOutput2 & bxmlout, CNcbiOstream *out_stream)
730 {
731  TTypeInfo typeInfo = bxmlout.GetThisTypeInfo();
732  unique_ptr<CObjectOStreamXml> xml_out(new CObjectOStreamXml (*out_stream, eNoOwnership));
733  xml_out->SetEncoding(eEncoding_Ascii);
734  xml_out->SetVerifyData( eSerialVerifyData_No );
735  //xml_out->SetReferenceDTD();
736  xml_out->SetReferenceSchema();
737  xml_out->SetUseSchemaLocation(true);
738  xml_out->SetEnforcedStdXml();
739  xml_out->SetDTDFilePrefix("http://www.ncbi.nlm.nih.gov/data_specs/schema_alt/");
740  xml_out->SetDefaultSchemaNamespace("http://www.ncbi.nlm.nih.gov");
741  xml_out->Write(&bxmlout, typeInfo );
742 }
743 
744 /// Fills all fields in the data structure for a BLAST XML report.
745 /// @param bxmlout BLAST XML report data structure to fill [in] [out]
746 /// @param data Data structure, from which all necessary information can be
747 /// retrieved [in]
748 /// @param out_stream Output stream for incremental output, ignore if NULL [out]
749 void
751 {
752  blastxml2::CBlastOutput2 bxmlout;
753  try {
754  s_FillBlastOutput(bxmlout, data);
755  s_WriteXML2ObjectNoHeader(bxmlout, out_stream);
756  }
757  catch(CException &e){
758  ERR_POST(Error << e.GetMsg() << e.what() );
759  return;
760  }
761  catch(...){
762  ERR_POST(Error << "XML format failed" );
763  return;
764  }
765 }
766 
767 void
769 {
770  blastxml2::CBlastOutput2 bxmlout;
771  CNcbiOfstream out_stream;
772  out_stream.open(file_name.c_str(), IOS_BASE::out);
773  if(!out_stream.is_open())
774  NCBI_THROW(CArgException, eInvalidArg, "Cannot open output file");
775 
776  s_FillBlastOutput(bxmlout, data);
777  s_WriteXML2Object(bxmlout, &out_stream);
778 }
779 
780 void
782 {
783  CNcbiOstrstream ostr;
784  unique_ptr<CObjectOStreamXml> xml_out(new CObjectOStreamXml (ostr, eNoOwnership));
785  xml_out->SetEncoding(eEncoding_Ascii);
786  xml_out->SetVerifyData( eSerialVerifyData_No );
787  xml_out->SetReferenceSchema();
788  xml_out->SetUseSchemaLocation(true);
789  xml_out->SetEnforcedStdXml();
790  xml_out->SetDTDFilePrefix("http://www.ncbi.nlm.nih.gov/data_specs/schema_alt/");
791  xml_out->SetDefaultSchemaNamespace("http://www.ncbi.nlm.nih.gov");
792 
793  blastxml2::CBlastXML2 xml2;
794  TTypeInfo typeInfo = xml2.GetThisTypeInfo();
795  xml_out->Write(&xml2, typeInfo);
796 
797  string out_str = string(CNcbiOstrstreamToString(ostr));
798  string::size_type end_pos = out_str.find("</BlastXML2>");
799  out_str.erase(end_pos);
800 
801  *out_stream << out_str;
802 }
803 
804 void
805 BlastXML2_FormatError(int exit_code, string err_msg,
806  CNcbiOstream *out_stream)
807 {
808  blastxml2::CBlastOutput2 bxmlout;
809  bxmlout.SetError().SetCode(exit_code);
810  if(err_msg != kEmptyStr) {
811  bxmlout.SetError().SetMessage(err_msg);
812  }
813  s_WriteXML2Object(bxmlout, out_stream);
814 }
815 
817 {
818 public:
819 
821  : CObjectOStreamJson(stream , deleteOut) {}
822  virtual ~CBlastOStreamJson (void) {};
823  // WriteFileHeader() is a dummy to keep xml prolog, doctype
824  // from being printed with each object
826  virtual void EndOfWrite(void) {
828  m_Output.PutEol();
830  };
831 };
832 
833 void
835 {
836  *out_stream << "{\n\"BlastOutput2\": [\n";
837 }
838 
839 static void
840 s_WriteJSONObjectNoHeader(blastxml2::CBlastOutput2 & bxmlout, CNcbiOstream *out_stream)
841 {
842  TTypeInfo typeInfo = bxmlout.GetThisTypeInfo();
843  unique_ptr<CObjectOStreamJson> json_out(new CBlastOStreamJson (*out_stream, eNoOwnership));
844  json_out->SetDefaultStringEncoding(eEncoding_Ascii);
845  //json_out.SetUseIndentation(true);
846  //json_out.SetUseEol(true);
847  json_out->Write(&bxmlout, typeInfo );
848 }
849 
850 
851 static void
852 s_WriteJSONObject(blastxml2::CBlastOutput2 & bxmlout, CNcbiOstream *out_stream)
853 {
854  TTypeInfo typeInfo = bxmlout.GetThisTypeInfo();
855  unique_ptr<CObjectOStreamJson> json_out(new CObjectOStreamJson (*out_stream, eNoOwnership));
856  json_out->SetDefaultStringEncoding(eEncoding_Ascii);
857  //json_out.SetUseIndentation(true);
858  //json_out.SetUseEol(true);
859  json_out->Write(&bxmlout, typeInfo );
860 }
861 
862 
863 void
865 {
866  blastxml2::CBlastOutput2 bxmlout;
867  CNcbiOfstream out_stream;
868  out_stream.open(file_name.c_str(), IOS_BASE::out);
869  if(!out_stream.is_open())
870  NCBI_THROW(CArgException, eInvalidArg, "Cannot open output file");
871 
872  s_FillBlastOutput(bxmlout, data);
873  s_WriteJSONObject(bxmlout, &out_stream);
874 }
875 
876 void
878 {
879  blastxml2::CBlastOutput2 bxmlout;
880  try {
881  s_FillBlastOutput(bxmlout, data);
882  s_WriteJSONObjectNoHeader(bxmlout, out_stream);
883  }
884  catch(CException &e){
885  ERR_POST(Error << e.GetMsg() << e.what() );
886  return;
887  }
888  catch(...){
889  ERR_POST(Error << "JSON format failed" );
890  return;
891  }
892 }
893 
User-defined methods of the data storage class.
Declares singleton objects to store the version and reference for the BLAST engine.
BLAST formatter utilities.
Declares class to display one-line descriptions at the top of the BLAST report.
EProgram
This enumeration is to evolve into a task/program specific list that specifies sets of default parame...
Definition: blast_types.hpp:56
@ ePHIBlastn
Nucleotide PHI BLAST.
Definition: blast_types.hpp:70
@ ePHIBlastp
Protein PHI BLAST.
Definition: blast_types.hpp:69
@ ePSIBlast
PSI Blast.
Definition: blast_types.hpp:67
@ eMegablast
Nucl-Nucl (traditional megablast)
Definition: blast_types.hpp:65
@ eDeltaBlast
Delta Blast.
Definition: blast_types.hpp:71
USING_SCOPE(objects)
static void s_WriteXML2ObjectNoHeader(blastxml2::CBlastOutput2 &bxmlout, CNcbiOstream *out_stream)
static void s_SetBlastXMLSearch(blastxml2::CSearch &search, const IBlastXML2ReportData *data, int num)
static void s_SetBlastXMlHitList(list< CRef< blastxml2::CHit > > &hits, const IBlastXML2ReportData *data, int num)
Fills the list of blastxml2::CHit objects, given a list of Seq-aligns.
static void s_SeqAlignToXMLHit(CRef< blastxml2::CHit > &hit, const CSeq_align &align_in, CRef< CScope > scope, const CBlastFormattingMatrix *matrix, const ncbi::TMaskedQueryRegions &mask_info, bool ungapped, int master_gentice_code, int slave_genetic_code, bool hasTaxDB)
Fill the blastxml2::CHit object in BLAST XML output, given an alignment and other information.
static void s_FillBlastOutput(blastxml2::CBlastOutput2 &bxmlout, const IBlastXML2ReportData *data)
static void s_WriteJSONObjectNoHeader(blastxml2::CBlastOutput2 &bxmlout, CNcbiOstream *out_stream)
static int s_GetTranslationFrame(bool plus_strand, int start, int end, int seq_length)
Returns translation frame given the strand, alignment endpoints and total sequence length.
static CReference::EPublication s_GetBlastPublication(EProgram program)
Given BLAST task, returns enumerated value for the publication to be referenced.
static void s_WriteJSONObject(blastxml2::CBlastOutput2 &bxmlout, CNcbiOstream *out_stream)
static void s_SetBlastXMLStatistics(blastxml2::CStatistics &stats, const IBlastXML2ReportData *data, int num)
Fills the search statistics part of the BLAST XML output for all queries.
static void s_SetBlastXMLParameters(blastxml2::CParameters &params, const IBlastXML2ReportData *data)
Fills the parameters part of the BLAST XML output.
static const CSeq_id * s_GetSubjectId(const CSeq_align &align)
Retrieves subject Seq-id from a Seq-align.
static void s_WriteXML2Object(blastxml2::CBlastOutput2 &bxmlout, CNcbiOstream *out_stream)
static void s_SeqAlignSetToXMLHsps(list< CRef< blastxml2::CHsp > > &xhsp_list, const CSeq_align_set &alnset, CRef< CScope > scope, const CBlastFormattingMatrix *matrix, const ncbi::TMaskedQueryRegions &mask_info, int master_gentic_code, int slave_genetic_code)
Creates a list of blastxml2::CHsp structures for the XML output, given a list of Seq-aligns.
static string GetLabel(CConstRef< objects::CSeq_id > id, bool with_version=false)
Return a label for an ID Tries to recreate behavior of GetLabel before a change that prepends "ti|" t...
CArgException –.
Definition: ncbiargs.hpp:120
CBioseq_Handle –.
256x256 matrix used for calculating positives etc.
virtual void WriteFileHeader(TTypeInfo type)
virtual ~CBlastOStreamJson(void)
virtual void EndOfWrite(void)
CBlastOStreamJson(CNcbiOstream &stream, EOwnership deleteOut)
CBlastOStreamXml(CNcbiOstream &stream, EOwnership deleteOut)
virtual ~CBlastOStreamXml(void)
virtual void WriteFileHeader(TTypeInfo type)
void Reverse(void)
Reverse the segments' orientation.
Definition: Dense_seg.cpp:644
void Assign(const CSerialObject &obj, ESerialRecursionMode how=eRecursive)
overloaded Assign()
Definition: Dense_seg.cpp:62
static CRef< objects::CSeq_align_set > PrepareBlastUngappedSeqalign(const objects::CSeq_align_set &alnset)
static functions Need to call this if the seqalign is stdseg or dendiag for ungapped blast alignment ...
Definition: showalign.cpp:3164
SeqLocCharOption
character used to display seqloc, such as masked sequence
Definition: showalign.hpp:204
CNcbiOstrstreamToString class helps convert CNcbiOstrstream to a string Sample usage:
Definition: ncbistre.hpp:802
CObjectOStreamJson –.
Definition: objostrjson.hpp:54
CObjectOStreamXml –.
Definition: objostrxml.hpp:54
CRef –.
Definition: ncbiobj.hpp:618
static void GetTaxInfo(TTaxId taxid, SSeqDBTaxInfo &info)
Get taxonomy information.
Definition: seqdb.cpp:1105
static CRef< CBlast_def_line_set > ExtractBlastDefline(const CBioseq &bioseq)
Extract a Blast-def-line-set object from a Bioseq retrieved by CSeqDB.
Definition: seqdbvol.cpp:1247
objects::ENa_strand GetStrand() const
Convert the frame to a strand.
Definition: seqlocinfo.cpp:39
const objects::CSeq_interval & GetInterval() const
Definition: seqlocinfo.hpp:69
CRef< CSeq_align > CreateTranslatedDensegFromNADenseg(void) const
Create a Dense-seg with widths from Dense-seg of nucleotides Used by AlnMgr to handle translated nucl...
Definition: Seq_align.cpp:953
CRef< CSeq_align > CreateDensegFromStdseg(SSeqIdChooser *SeqIdChooser=0) const
---------------------------------------------------------------------------- PRE : the Seq-align has ...
Definition: Seq_align.cpp:728
TSeqPos GetTotalGapCount(TDim row=-1) const
Retrieves the total number of gaps in the given row an alignment; all gaps by default.
Definition: Seq_align.cpp:1550
TSeqPos GetSeqStop(TDim row) const
Definition: Seq_align.cpp:273
const CSeq_id & GetSeq_id(TDim row) const
Get seq-id (the first one if segments have different ids).
Definition: Seq_align.cpp:317
TSeqPos GetSeqStart(TDim row) const
Definition: Seq_align.cpp:252
ENa_strand GetSeqStrand(TDim row) const
Get strand (the first one if segments have different strands).
Definition: Seq_align.cpp:294
TSeqPos GetAlignLength(bool include_gaps=true) const
Get the length of this alignment.
Definition: Seq_align.cpp:1993
static void GetSeqIdList(const objects::CBioseq_Handle &bh, list< CRef< objects::CSeq_id > > &ids)
Converts a Bioseq handle's sequence id type into a list of objects::CSeq_id references,...
static string GetSeqIdListString(const list< CRef< objects::CSeq_id > > &id, bool show_gi)
Creates a '|' delimited string, corresponding to a list of Seq-ids.
CTypeInfo class contains all information about C++ types (both basic and classes): members and layout...
Definition: typeinfo.hpp:76
Interface for filling the top layer of the XML report.
Collection of masked regions for a single query sequence.
Definition: seqlocinfo.hpp:113
string GetSeqIdString(const CSeq_id &id)
Definition: compartp.cpp:100
const char * file_name[]
std::ofstream out("events_result.xml")
main entry point for tests
static const char * str(char *buf, int n)
Definition: stats.c:84
static char tmp[3200]
Definition: utf8.c:42
char data[12]
Definition: iconv.c:80
static string GetString(EPublication pub)
Reference for requested publication.
Definition: version.cpp:112
EPublication
Enumerates the various BLAST publications.
Definition: version.hpp:70
@ eMaxPublications
Used as sentinel value.
Definition: version.hpp:78
@ ePhiBlast
1998 NAR paper
Definition: version.hpp:72
@ eCompBasedStats
2001 NAR paper
Definition: version.hpp:74
@ eGappedBlast
1997 NAR paper
Definition: version.hpp:71
@ eMegaBlast
2000 J Compt Biol paper
Definition: version.hpp:73
@ eDeltaBlast
2012 Biology Direct on DeltaBLAST
Definition: version.hpp:77
#define ZERO_TAX_ID
Definition: ncbimisc.hpp:1115
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
SStrictId_Tax::TId TTaxId
Taxon id type.
Definition: ncbimisc.hpp:1048
@ eNoOwnership
No ownership is assumed.
Definition: ncbi_types.h:135
void BlastXML2_FormatError(int exit_code, string err_msg, CNcbiOstream *out_stream)
static void GetWholeAlnSeqStrings(string &query, string &subject, const objects::CDense_seg &ds, objects::CScope &scope, int master_gen_code, int slave_gen_code)
static string BlastGetVersion(const string program)
Returns the version and release date, e.g.
void BlastXML2_FormatReport(const IBlastXML2ReportData *data, CNcbiOstream *out_stream)
Fills all fields in the data structure for a BLAST XML report.
void BlastJSON_FormatReport(const IBlastXML2ReportData *data, string file_name)
void BlastXML2_PrintHeader(CNcbiOstream *out_stream)
void BlastJSON_PrintHeader(CNcbiOstream *out_stream)
string
Definition: cgiapp.hpp:687
#define NULL
Definition: ncbistd.hpp:225
#define ERR_POST(message)
Error posting with file, line number information but without error codes.
Definition: ncbidiag.hpp:186
void Error(CExceptionArgs_Base &args)
Definition: ncbiexpt.hpp:1197
#define NCBI_THROW(exception_class, err_code, message)
Generic macro to throw an exception, given the exception class, error code and message string.
Definition: ncbiexpt.hpp:704
const string & GetMsg(void) const
Get message string.
Definition: ncbiexpt.cpp:461
virtual const char * what(void) const noexcept
Standard report (includes full backlog).
Definition: ncbiexpt.cpp:342
@ eUnknown
Definition: app_popup.hpp:72
@ eSerialVerifyData_No
do not verify
Definition: serialdef.hpp:109
const string AsFastaString(void) const
Definition: Seq_id.cpp:2266
CConstRef< CSeq_id > GetSeqId(void) const
bool Match(const CSeq_id &sid2) const
Match() - TRUE if SeqIds are equivalent.
Definition: Seq_id.hpp:1065
static CSeq_id_Handle GetHandle(const CSeq_id &id)
Normal way of getting a handle, works for any seq-id.
static int Score(const CRef< CSeq_id > &id)
Wrappers for use with FindBestChoice from <corelib/ncbiutil.hpp>
Definition: Seq_id.hpp:772
virtual void EndOfWrite(void)
Definition: objostr.cpp:559
COStreamBuffer m_Output
Definition: objostr.hpp:796
TSeqPos GetLength(const CSeq_id &id, CScope *scope)
Get sequence length if scope not null, else return max possible TSeqPos.
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.
TSeqPos GetBioseqLength(void) const
bool IsNa(void) const
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
bool NotEmpty(void) const THROWS_NONE
Check if CRef is not empty – pointing to an object and has a non-null value.
Definition: ncbiobj.hpp:726
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
void IncIndentLevel(size_t step=2)
void PutEol(bool indent=true)
void DecIndentLevel(size_t step=2)
IO_PREFIX::ofstream CNcbiOfstream
Portable alias for ofstream.
Definition: ncbistre.hpp:500
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
Definition: ncbistre.hpp:149
#define kEmptyStr
Definition: ncbistr.hpp:123
#define NcbiEmptyString
Definition: ncbistr.hpp:122
@ eEncoding_Ascii
Definition: ncbistr.hpp:202
enum ENcbiOwnership EOwnership
Ownership relations between objects.
C::value_type FindBestChoice(const C &container, F score_func)
Find the best choice (lowest score) for values in a container.
Definition: ncbiutil.hpp:250
const TSeqid & GetSeqid(void) const
Get the Seqid member data.
bool IsSetTitle(void) const
simple title Check if a value has been assigned to Title data member.
TTaxid GetTaxid(void) const
Get the Taxid member data.
bool IsSet(void) const
Check if a value has been assigned to data member.
bool IsSetTaxid(void) const
Check if a value has been assigned to Taxid data member.
const Tdata & Get(void) const
Get the member data.
const TTitle & GetTitle(void) const
Get the Title member data.
const TDenseg & GetDenseg(void) const
Get the variant data.
Definition: Seq_align_.cpp:153
Tdata & Set(void)
Assign a value to data member.
bool IsSetStrands(void) const
Check if a value has been assigned to Strands data member.
Definition: Dense_seg_.hpp:568
void SetSegs(TSegs &value)
Assign a value to Segs data member.
Definition: Seq_align_.cpp:310
bool IsDendiag(void) const
Check if variant Dendiag is selected.
Definition: Seq_align_.hpp:720
const TStd & GetStd(void) const
Get the variant data.
Definition: Seq_align_.hpp:752
const TDendiag & GetDendiag(void) const
Get the variant data.
Definition: Seq_align_.hpp:726
bool IsStd(void) const
Check if variant Std is selected.
Definition: Seq_align_.hpp:746
bool IsDisc(void) const
Check if variant Disc is selected.
Definition: Seq_align_.hpp:772
const TIds & GetIds(void) const
Get the Ids member data.
Definition: Dense_seg_.hpp:505
list< CRef< CSeq_align > > Tdata
const TDisc & GetDisc(void) const
Get the variant data.
Definition: Seq_align_.cpp:197
const TStrands & GetStrands(void) const
Get the Strands member data.
Definition: Dense_seg_.hpp:580
const Tdata & Get(void) const
Get the member data.
const TSegs & GetSegs(void) const
Get the Segs member data.
Definition: Seq_align_.hpp:921
bool IsDenseg(void) const
Check if variant Denseg is selected.
Definition: Seq_align_.hpp:740
bool IsLocal(void) const
Check if variant Local is selected.
Definition: Seq_id_.hpp:775
@ eNa_strand_minus
Definition: Na_strand_.hpp:67
int i
static CRef< CSeq_align > CreateDensegFromDendiag(CSeq_align const &aln)
T min(T x_, T y_)
The Object manager core.
Defines BLAST database access classes.
SSeqDBTaxInfo.
string scientific_name
Scientific name, such as "Aotus vociferans".
Definition: type.c:6
#define _ASSERT
Modified on Wed Apr 17 13:09:44 2024 by modify_doxy.py rev. 669887