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

Go to the SVN repository for this file.

1 /* $Id: aln_writer.cpp 94150 2021-06-30 15:26:35Z ludwigf $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Justin Foley
27  *
28  * File Description: Write alignment
29  *
30  */
31 
32 #include <ncbi_pch.hpp>
33 
45 
46 #include <objmgr/scope.hpp>
47 #include <objmgr/bioseq_handle.hpp>
48 #include <objmgr/seq_vector.hpp>
49 #include <objmgr/util/sequence.hpp>
50 
54 
56 
59 
60 // ----------------------------------------------------------------------------
62  CScope& scope,
63  CNcbiOstream& ostr,
64  unsigned int uFlags) :
65  CWriterBase(ostr, uFlags)
66 {
67  m_pScope.Reset(&scope);
68  m_Width = 60;
70 };
71 
72 
73 // ----------------------------------------------------------------------------
74 
76  CNcbiOstream& ostr,
77  unsigned int uFlags) :
78  CAlnWriter(*(new CScope(*CObjectManager::GetInstance())), ostr, uFlags)
79 {
80 };
81 
82 
83 // ----------------------------------------------------------------------------
85  const CSeq_align& align,
86  const string& name,
87  const string& descr)
88 {
89 
90  switch (align.GetSegs().Which()) {
92  return WriteAlignDenseSeg(align.GetSegs().GetDenseg());
94  return WriteAlignSplicedSeg(align.GetSegs().GetSpliced());
96  return WriteAlignSparseSeg(align.GetSegs().GetSparse());
98  break;
99  default:
100  break;
101  }
102 
103  return false;
104 }
105 // ----------------------------------------------------------------------------
106 
108 {
109  if (m_pScope) {
110 
111  bsh = m_pScope->GetBioseqHandle(id);
114  }
115 }
116 
117 
118 // -----------------------------------------------------------------------------
119 
121  const CRange<TSeqPos>& range,
122  ENa_strand strand,
123  string& seq)
124 {
125  if (!bsh) {
127  eBadInput,
128  "Empty bioseq handle");
129  }
130 
132  if (range.IsWhole()) {
133  seq_vec.GetSeqData(0, bsh.GetBioseqLength(), seq);
134  }
135  else {
136  seq_vec.GetSeqData(range.GetFrom(), range.GetTo(), seq);
137  }
138 
139  if (NStr::IsBlank(seq)) {
141  eBadInput,
142  "Empty sequence string");
143  }
144 }
145 
146 // -----------------------------------------------------------------------------
147 
149  const CDense_seg& denseg)
150 {
151  if (!denseg.CanGetDim() ||
152  !denseg.CanGetNumseg() ||
153  !denseg.CanGetIds() ||
154  !denseg.CanGetStarts() ||
155  !denseg.CanGetLens())
156  {
157  return false;
158  }
159 
160  const auto num_rows = denseg.GetDim();
161  const auto num_segs = denseg.GetNumseg();
162 
163 
164  for (int row=0; row<num_rows; ++row)
165  {
166  const CSeq_id& id = denseg.GetSeq_id(row);
168 
169  CBioseq_Handle bsh;
170  ProcessSeqId(id, bsh, range);
171  if (!bsh) {
173  eBadInput,
174  "Unable to fetch Bioseq");
175  }
176 
177  string seq_plus;
178  GetSeqString(bsh, range, eNa_strand_plus, seq_plus);
179 
180  const CSeqUtil::ECoding coding =
181  (bsh.IsNucleotide()) ?
184 
185  string seqdata;
186  for (int seg=0; seg<num_segs; ++seg)
187  {
188  const auto start = denseg.GetStarts()[seg*num_rows + row];
189  const auto len = denseg.GetLens()[seg];
190  const ENa_strand strand = (denseg.IsSetStrands()) ?
191  denseg.GetStrands()[seg*num_rows + row] :
193  seqdata += GetSegString(seq_plus, coding, strand, start, len);
194  }
195 
196  string best_id = GetBestId(id);
197  string defline = ">" + best_id;
198  WriteContiguous(defline, seqdata);
199  }
200 
201  return true;
202 }
203 
204 // -----------------------------------------------------------------------------
205 
207  const CSpliced_seg& spliced_seg)
208 {
209  if (!spliced_seg.IsSetExons()) {
210  return false;
211  }
212 
213  CRef<CSeq_id> genomic_id;
214  if (spliced_seg.IsSetGenomic_id()) {
215  genomic_id = Ref(new CSeq_id());
216  genomic_id->Assign(spliced_seg.GetGenomic_id());
217  }
218 
219 
220  CRef<CSeq_id> product_id;
221  if (spliced_seg.IsSetGenomic_id()) {
222  product_id = Ref(new CSeq_id());
223  product_id->Assign(spliced_seg.GetProduct_id());
224  }
225 
226 
227  ENa_strand genomic_strand =
228  spliced_seg.IsSetGenomic_strand() ?
229  spliced_seg.GetGenomic_strand() :
231 
232 
233  ENa_strand product_strand =
234  spliced_seg.IsSetProduct_strand() ?
235  spliced_seg.GetProduct_strand() :
237 
238  return WriteSplicedExons(spliced_seg.GetExons(),
239  spliced_seg.GetProduct_type(),
240  genomic_id,
241  genomic_strand,
242  product_id,
243  product_strand);
244 }
245 
246 unsigned int s_ProductLength(const CProduct_pos& start, const CProduct_pos& end)
247 {
248  if (start.Which() != end.Which()) {
250  eBadInput,
251  "Unable to determine product length");
252  }
253 
254  if (start.Which() == CProduct_pos::e_not_set) {
256  eBadInput,
257  "Unable to determine product length");
258  }
259 
260  const int length = end.AsSeqPos() - start.AsSeqPos();
261 
262  return (length >= 0) ? length : -length;
263 }
264 
265 
266 // -----------------------------------------------------------------------------
268  CSpliced_seg::TProduct_type product_type,
269  CRef<CSeq_id> default_genomic_id, // May be NULL
270  ENa_strand default_genomic_strand,
271  CRef<CSeq_id> default_product_id,
272  ENa_strand default_product_strand)
273 {
274  string prev_genomic_id;
275  string prev_product_id;
276  for (const CRef<CSpliced_exon>& exon : exons) {
277 
278  const CSeq_id& genomic_id =
279  exon->IsSetGenomic_id() ?
280  exon->GetGenomic_id() :
281  *default_genomic_id;
282 
283  const CSeq_id& product_id =
284  exon->IsSetProduct_id() ?
285  exon->GetProduct_id() :
286  *default_product_id;
287 
288  // Should check to see that the ids are not empty
289  const ENa_strand genomic_strand =
290  exon->IsSetGenomic_strand() ?
291  exon->GetGenomic_strand() :
292  default_genomic_strand;
293 
294  const ENa_strand product_strand =
295  exon->IsSetProduct_strand() ?
296  exon->GetProduct_strand() :
297  default_product_strand;
298 
299  const auto genomic_start = exon->GetGenomic_start();
300  const auto genomic_end = exon->GetGenomic_end();
301 
302  if (genomic_end < genomic_start) {
304  eBadInput,
305  "Bad genomic location: end < start");
306  }
307  const int genomic_length = genomic_end - genomic_start;
308 
309  const int product_start = exon->GetProduct_start().AsSeqPos();
310  const int product_end = exon->GetProduct_end().AsSeqPos();
311 
312 
313  if (product_end < product_start) {
315  eBadInput,
316  "Bad product location: end < start");
317  }
318  // product_length is now given in nucleotide units
319  const int product_length = product_end - product_start;
320 
321  CBioseq_Handle genomic_bsh;
322  if (m_pScope) {
323  genomic_bsh = m_pScope->GetBioseqHandle(genomic_id);
324  }
325  if (!genomic_bsh) {
327  eBadInput,
328  "Unable to resolve genomic sequence");
329  }
330  CRange<TSeqPos> genomic_range(genomic_start, genomic_end+1);
331  string genomic_seq;
332  GetSeqString(genomic_bsh, genomic_range, genomic_strand, genomic_seq);
333 
334  CBioseq_Handle product_bsh;
335  if (m_pScope) {
336  product_bsh = m_pScope->GetBioseqHandle(product_id);
337  }
338  if (!product_bsh) {
340  eBadInput,
341  "Unable to resolve product sequence");
342  }
343  CRange<TSeqPos> product_range(product_start, product_end+1);
344  string product_seq;
345  GetSeqString(product_bsh, product_range, product_strand, product_seq);
346 
347  if (exon->IsSetParts()) {
348  AddGaps(product_type, exon->GetParts(), genomic_seq, product_seq);
349  }
350  else
351  if (product_length != genomic_length) {
353  eBadInput,
354  "Lengths of genomic and product sequences don't match");
355  }
356 
357  WriteContiguous(">" + GetBestId(genomic_id), genomic_seq);
358  WriteContiguous(">" + GetBestId(product_id), product_seq);
359  }
360 
361  return true;
362 }
363 
364 // -----------------------------------------------------------------------------
365 
367  CSpliced_seg::TProduct_type product_type,
368  const CSpliced_exon::TParts& exon_chunks,
369  string& genomic_seq,
370  string& product_seq)
371 {
372 
373  if (exon_chunks.empty()) {
374  return;
375  }
376 
377  string genomic_string;
378  string product_string;
379 
380  const unsigned int res_width =
381  (product_type == CSpliced_seg::eProduct_type_transcript) ?
382  1 : 3;
383 
384 
385  // Check that match + mismatch + diag + genomic_ins = genomic_length
386  int genomic_pos = 0;
387  int product_pos = 0;
388  unsigned int interval_width = 0;
389  for (CRef<CSpliced_exon_chunk> exon_chunk : exon_chunks) {
390  auto chunk_type = exon_chunk->Which();
391  switch(chunk_type) {
395  switch(chunk_type) {
396  default:
397  // compiler, shut up!
398  break;
400  interval_width = exon_chunk->GetMatch();
401  break;
403  interval_width = exon_chunk->GetMismatch();
404  break;
406  interval_width = exon_chunk->GetDiag();
407  break;
408  }
409  genomic_string.append(genomic_seq, genomic_pos, interval_width);
410  product_string.append(product_seq, product_pos, (interval_width + (res_width-1))/res_width);
411  genomic_pos += interval_width;
412  product_pos += interval_width/res_width;
413  break;
414 
416  interval_width = exon_chunk->GetGenomic_ins();
417  genomic_string.append(genomic_seq, genomic_pos, interval_width);
418  product_string.append(interval_width/res_width, '-');
419  genomic_pos += interval_width;
420  break;
421 
423  interval_width = exon_chunk->GetProduct_ins();
424  genomic_string.append(interval_width, '-');
425  product_string.append(product_seq, product_pos, interval_width/res_width);
426  product_pos += interval_width/res_width;
427  break;
428  default:
429  break;
430  }
431  }
432  genomic_seq = genomic_string;
433  product_seq = product_string;
434 }
435 
436 
437 // -----------------------------------------------------------------------------
438 
439 string CAlnWriter::GetSegString(const string& seq_plus,
440  CSeqUtil::ECoding coding,
441  const ENa_strand strand,
442  const int start,
443  const size_t len)
444 {
445  if (start >= 0) {
446  if (start >= seq_plus.size()) {
448  eBadInput,
449  "Bad location: impossible start");
450  }
451  if (strand != eNa_strand_minus) {
452  return seq_plus.substr(start, len);
453  }
454  // else
455  string seq_minus;
456  CSeqManip::ReverseComplement(seq_plus, coding, start, len, seq_minus);
457  return seq_minus;
458  }
459 
460  return string(len, '-');
461 }
462 
463 
464 // -----------------------------------------------------------------------------
466  const CSparse_seg& sparse_seg)
467 {
468  for (CRef<CSparse_align> align : sparse_seg.GetRows())
469  {
470  if (!WriteSparseAlign(*align)) {
471  return false;
472  }
473  }
474  return true;
475 }
476 
477 
478 
479 // -----------------------------------------------------------------------------
480 
482 {
483  const auto num_segs = sparse_align.GetNumseg();
484 
485  {
486  const CSeq_id& first_id = sparse_align.GetFirst_id();
487  CBioseq_Handle bsh;
489  ProcessSeqId(first_id, bsh, range);
490  if (!bsh) {
492  eBadInput,
493  "Unable to resolve ID " + first_id.AsFastaString());
494  }
495  const CSeqUtil::ECoding coding =
496  (bsh.IsNucleotide())?
499 
500  string seq_plus;
501  GetSeqString(bsh, range, eNa_strand_plus, seq_plus);
502 
503  string seqdata;
504  for (int seg=0; seg<num_segs; ++seg) {
505  const auto start = sparse_align.GetFirst_starts()[seg];
506  const auto len = sparse_align.GetLens()[seg];
507  seqdata += GetSegString(seq_plus, coding, eNa_strand_plus, start, len);
508  }
509  WriteContiguous(">" + GetBestId(first_id), seqdata);
510  }
511 
512  { // Second row
513  const CSeq_id& second_id = sparse_align.GetSecond_id();
514  CBioseq_Handle bsh;
516  ProcessSeqId(second_id, bsh, range);
517  if (!bsh) {
519  eBadInput,
520  "Unable to resolve ID " + second_id.AsFastaString());
521  }
522  const CSeqUtil::ECoding coding =
523  (bsh.IsNucleotide())?
526 
527  string seq_plus;
528  GetSeqString(bsh, range, eNa_strand_plus, seq_plus);
529 
530  string seqdata;
531  const vector<ENa_strand>& strands = sparse_align.IsSetSecond_strands() ?
532  sparse_align.GetSecond_strands() : vector<ENa_strand>(num_segs, eNa_strand_plus);
533  for (int seg=0; seg<num_segs; ++seg) {
534  const auto start = sparse_align.GetFirst_starts()[seg];
535  const auto len = sparse_align.GetLens()[seg];
536  seqdata += GetSegString(seq_plus, coding, strands[seg], start, len);
537  }
538 
539  WriteContiguous(">" + GetBestId(second_id), seqdata);
540  }
541  return true;
542 }
543 
544 // -----------------------------------------------------------------------------
545 
546 void CAlnWriter::WriteContiguous(const string& defline, const string& seqdata)
547 {
548  if (defline.back() == '|' && defline.size() > 1)
549  {
550  const auto length = defline.size();
551  m_Os << defline.substr(0,length-1) << "\n";
552  }
553  else {
554  m_Os << defline << "\n";
555  }
556  size_t pos=0;
557  while (pos < seqdata.size()) {
558 
559  if (IsCanceled()) {
560  NCBI_THROW(
562  eInterrupted,
563  "Processing terminated by user");
564  }
565 
566  m_Os << seqdata.substr(pos, m_Width) << "\n";
567  pos += m_Width;
568  }
569 }
570 
571 // -----------------------------------------------------------------------------
572 
574 {
575  string best_id;
578  *m_pScope,
579  best_id);
580  return best_id;
581 }
582 
583 // -----------------------------------------------------------------------------
584 
586 
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
User-defined methods of the data storage class.
unsigned int s_ProductLength(const CProduct_pos &start, const CProduct_pos &end)
Definition: aln_writer.cpp:246
USING_SCOPE(objects)
void ProcessSeqId(const CSeq_id &id, CBioseq_Handle &bsh, CRange< TSeqPos > &range)
Definition: aln_writer.cpp:107
bool WriteSparseAlign(const CSparse_align &sparse_aln)
Definition: aln_writer.cpp:481
void WriteContiguous(const string &defline, const string &seqdata)
Definition: aln_writer.cpp:546
bool WriteSplicedExons(const list< CRef< CSpliced_exon >> &exons, CSpliced_seg::TProduct_type product_type, CRef< CSeq_id > default_genomic_id, ENa_strand default_genomic_strand, CRef< CSeq_id > default_product_id, ENa_strand default_product_strand)
Definition: aln_writer.cpp:267
CAlnWriter(CScope &scope, CNcbiOstream &ostr, unsigned int uFlags)
Definition: aln_writer.cpp:61
void GetSeqString(CBioseq_Handle bsh, const CRange< TSeqPos > &range, ENa_strand strand, string &seq)
Definition: aln_writer.cpp:120
bool WriteAlignSparseSeg(const CSparse_seg &sparse_seg)
Definition: aln_writer.cpp:465
bool WriteAlign(const CSeq_align &align, const string &name="", const string &descr="") override
Write a raw Seq-align to the internal output stream.
Definition: aln_writer.cpp:84
string GetSegString(const string &seq_plus, CSeqUtil::ECoding coding, ENa_strand strand, int start, size_t len)
Definition: aln_writer.cpp:439
CRef< CScope > m_pScope
Definition: aln_writer.hpp:127
unsigned int m_Width
Definition: aln_writer.hpp:128
void AddGaps(CSpliced_seg::TProduct_type product_type, const CSpliced_exon::TParts &exon_chunks, string &genomic_seq, string &product_seq)
Definition: aln_writer.cpp:366
bool WriteAlignSplicedSeg(const CSpliced_seg &spliced_seg)
Definition: aln_writer.cpp:206
string GetBestId(const CSeq_id &)
Definition: aln_writer.cpp:573
bool WriteAlignDenseSeg(const CDense_seg &denseg)
Definition: aln_writer.cpp:148
CBioseq_Handle –.
const CSeq_id & GetSeq_id(TDim row) const
Definition: Dense_seg.cpp:154
static CGenbankIdResolve & Get()
void SetLabelType(CSeq_id::ELabelType labelType)
bool GetBestId(CSeq_id_Handle, CScope &, string &)
bool IsCanceled() const
Definition: writer.hpp:62
CObjectManager –.
TSeqPos AsSeqPos() const
Definition: Product_pos.cpp:56
CScope –.
Definition: scope.hpp:92
static SIZE_TYPE ReverseComplement(const string &src, TCoding src_coding, TSeqPos pos, TSeqPos length, string &dst)
@ e_Iupacna
Definition: sequtil.hpp:47
@ e_Iupacaa
Definition: sequtil.hpp:55
CSeqVector –.
Definition: seq_vector.hpp:65
Defines and provides stubs for a general interface to a variety of file formatters.
Definition: writer.hpp:81
CNcbiOstream & m_Os
Definition: writer.hpp:267
string
Definition: cgiapp.hpp:687
#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 AsFastaString(void) const
Definition: Seq_id.cpp:2266
virtual void Assign(const CSerialObject &source, ESerialRecursionMode how=eRecursive)
Optimized implementation of CSerialObject::Assign, which is not so efficient.
Definition: Seq_id.cpp:318
static CSeq_id_Handle GetHandle(const CSeq_id &id)
Normal way of getting a handle, works for any seq-id.
@ eFasta
Tagged ID in NCBI's traditional FASTA style.
Definition: Seq_id.hpp:607
CBioseq_Handle GetBioseqHandle(const CSeq_id &id)
Get bioseq handle by seq-id.
Definition: scope.cpp:95
bool IsNucleotide(void) const
TSeqPos GetBioseqLength(void) const
CSeqVector GetSeqVector(EVectorCoding coding, ENa_strand strand=eNa_strand_plus) const
Get sequence: Iupacna or Iupacaa if use_iupac_coding is true.
@ eCoding_Iupac
Set coding to printable coding (Iupacna or Iupacaa)
void GetSeqData(TSeqPos start, TSeqPos stop, string &buffer) const
Fill the buffer string with the sequence data for the interval [start, stop).
Definition: seq_vector.cpp:304
CRef< C > Ref(C *object)
Helper functions to get CRef<> and CConstRef<> objects.
Definition: ncbiobj.hpp:2015
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
IO_PREFIX::ostream CNcbiOstream
Portable alias for ostream.
Definition: ncbistre.hpp:149
static bool IsBlank(const CTempString str, SIZE_TYPE pos=0)
Check if a string is blank (has no text).
Definition: ncbistr.cpp:106
bool CanGetDim(void) const
Check if it is safe to call GetDim method.
Definition: Dense_seg_.hpp:402
const TDenseg & GetDenseg(void) const
Get the variant data.
Definition: Seq_align_.cpp:153
E_Choice Which(void) const
Which variant is currently selected.
const TGenomic_id & GetGenomic_id(void) const
Get the Genomic_id member data.
E_Choice Which(void) const
Which variant is currently selected.
Definition: Seq_align_.hpp:691
bool IsSetStrands(void) const
Check if a value has been assigned to Strands data member.
Definition: Dense_seg_.hpp:568
bool IsSetProduct_strand(void) const
should be 'plus' or 'minus' Check if a value has been assigned to Product_strand data member.
const TStarts & GetStarts(void) const
Get the Starts member data.
Definition: Dense_seg_.hpp:530
const TProduct_id & GetProduct_id(void) const
Get the Product_id member data.
const TLens & GetLens(void) const
Get the Lens member data.
Definition: Dense_seg_.hpp:555
bool CanGetNumseg(void) const
Check if it is safe to call GetNumseg method.
Definition: Dense_seg_.hpp:452
const TFirst_id & GetFirst_id(void) const
Get the First_id member data.
TProduct_type GetProduct_type(void) const
Get the Product_type member data.
TGenomic_strand GetGenomic_strand(void) const
Get the Genomic_strand member data.
bool CanGetIds(void) const
Check if it is safe to call GetIds method.
Definition: Dense_seg_.hpp:499
const TSpliced & GetSpliced(void) const
Get the variant data.
Definition: Seq_align_.cpp:219
TDim GetDim(void) const
Get the Dim member data.
Definition: Dense_seg_.hpp:421
bool IsSetGenomic_strand(void) const
Check if a value has been assigned to Genomic_strand data member.
const TLens & GetLens(void) const
Get the Lens member data.
const TExons & GetExons(void) const
Get the Exons member data.
bool IsSetSecond_strands(void) const
Check if a value has been assigned to Second_strands data member.
const TFirst_starts & GetFirst_starts(void) const
Get the First_starts member data.
TNumseg GetNumseg(void) const
Get the Numseg member data.
bool IsSetExons(void) const
set of segments involved each segment corresponds to one exon exons are always in biological order Ch...
const TSecond_strands & GetSecond_strands(void) const
Get the Second_strands member data.
list< CRef< CSpliced_exon_chunk > > TParts
const TSecond_id & GetSecond_id(void) const
Get the Second_id member data.
bool CanGetStarts(void) const
Check if it is safe to call GetStarts method.
Definition: Dense_seg_.hpp:524
TNumseg GetNumseg(void) const
Get the Numseg member data.
Definition: Dense_seg_.hpp:465
TProduct_strand GetProduct_strand(void) const
Get the Product_strand member data.
const TSparse & GetSparse(void) const
Get the variant data.
Definition: Seq_align_.cpp:241
const TRows & GetRows(void) const
Get the Rows member data.
const TStrands & GetStrands(void) const
Get the Strands member data.
Definition: Dense_seg_.hpp:580
const TSegs & GetSegs(void) const
Get the Segs member data.
Definition: Seq_align_.hpp:921
bool CanGetLens(void) const
Check if it is safe to call GetLens method.
Definition: Dense_seg_.hpp:549
bool IsSetGenomic_id(void) const
Check if a value has been assigned to Genomic_id data member.
@ e_Product_ins
insertion in product sequence (i.e. gap in the genomic sequence)
@ e_Diag
both sequences are represented, there is sufficient similarity between product and genomic sequences....
@ e_Genomic_ins
insertion in genomic sequence (i.e. gap in the product sequence)
@ e_Match
both sequences represented, product and genomic sequences match
@ e_Mismatch
both sequences represented, product and genomic sequences do not match
@ e_not_set
No variant selected.
ENa_strand
strand of nucleic acid
Definition: Na_strand_.hpp:64
@ eNa_strand_plus
Definition: Na_strand_.hpp:66
@ eNa_strand_minus
Definition: Na_strand_.hpp:67
int len
range(_Ty, _Ty) -> range< _Ty >
#define row(bind, expected)
Definition: string_bind.c:73
Modified on Thu Jun 13 17:32:29 2024 by modify_doxy.py rev. 669887