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

Go to the SVN repository for this file.

1 /* $Id: cds_glyph.cpp 47730 2024-06-03 18:05:17Z evgeniev $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * Authors: Liangshou Wu
27  *
28  * File Description:
29  */
30 
31 #include <ncbi_pch.hpp>
34 #include <gui/opengl/irender.hpp>
36 #include <objmgr/util/sequence.hpp>
38 #include <serial/iterator.hpp>
42 
43 static const int kVertSpace = 1;
44 
45 
47  : CFeatGlyph(f)
48 {
49 }
50 
51 CCdsGlyph::CCdsGlyph(const CMappedFeat& f, const CSeq_loc& loc)
52  : CFeatGlyph(f, loc)
53 {
54 }
55 
56 void CCdsGlyph::x_Draw() const
57 {
59  if (!x_WillFit())
60  return;
61 
62  IRender& gl = GetGl();
63 
64  TModelUnit trans_full = gl.GetMetric(&(m_CdsConfig->m_TransFont),
67 
68  // Translated protein sequence Y position (at the bottom)
69  TModelUnit trans_y = GetHeight() + GetTop();
70  // Genomic sequence Y postion (between the translated and original)
71  TModelUnit gen_y = trans_y - prot_h - kVertSpace;
72  // Original protein sequence Y position (inside the bar)
73  TModelUnit prot_y = gen_y - trans_full;
74  // adjust to CDS feature bar center line vertically
75  prot_y -= (m_Config->GetBarHeight(false) - prot_h) * 0.5;
76 
77  if (x_IsProjected()) {
78  x_DrawProjectedProtSeq(trans_y, gen_y, prot_y);
79  return;
80  }
81 
82  if ( !GetMappingInfo().empty() ) {
83  x_DrawProtSeqWithMapping(trans_y, gen_y, prot_y);
84  return;
85  }
86 
87  // Nov-28-2014
88  // We generate mapping always now, so there should be no cases
89  // when control is here.
90 
91  // otherwise, draw protein sequence based on feature location
92  bool flip_strand = m_Context->IsFlippedStrand();
93  string prot_seq, trans_seq;
94  TSeqPos offset = x_GetProtOffset(); // initial translation offset
96  const CSeqVector& vec = seq_ds->GetSeqVector();
98  seq_ds->GetScope(),
99  trans_seq,
100  true, true);
101 
102  if (GetFeature().IsSetProduct()) {
103  try {
104  const CSeq_loc& product = GetFeature().GetProduct();
105  CScope& scope = GetMappedFeature().GetAnnot().GetScope();
106  CSeqVector prot_vec(product, scope,
108  prot_vec.GetSeqData (0, prot_vec.size(), prot_seq);
109  }
110  catch (CException&) {
111  // ignore exceptions - these arise if the product doesn't resolve
112  }
113  } else {
114  prot_seq = trans_seq;
115  }
116 
117  TSeqPos seq_start = 0;
118  size_t idx = 0;
119 
120  // TODO: should we use intervals instead of location ?
121  for (CSeq_loc_CI lit(GetLocation()); lit; ++lit) {
122  TSeqPos ifrom = lit.GetRange().GetFrom();
123  TSeqPos ito = lit.GetRange().GetTo();
124 
125  char basesIN[2], basesOUT[2];
126  basesIN [1] = '\0';
127  basesOUT[1] = '\0';
128 
129  bool neg = lit.GetStrand () == eNa_strand_minus;
130  for (TSeqPos pos = neg ? ito : ifrom;
131  (neg ? (pos - offset >= ifrom) : (pos + offset <= ito)) &&
132  idx != prot_seq.length() && idx != trans_seq.length() ;
133  (neg ? pos -= 3 : pos += 3), ++idx)
134  {
135  bool mismatch = (prot_seq[idx] != trans_seq[idx]);
136  seq_start = neg ? pos - offset : pos + offset;
137 
138  // skip out of visible range intervals
139  if ( !m_Context->IsInVisibleRange(seq_start) )
140  continue;
141 
142  basesIN [0] = prot_seq[idx];
143  basesOUT[0] = trans_seq[idx];
144 
145  if (mismatch) {
146  gl.ColorC(m_CdsConfig->m_SeqProtMismatch); // Mismatch
147  // Draw protein sequence inside
148  m_Context->TextOut(&m_CdsConfig->m_ProdFont, basesIN, seq_start + 0.5, prot_y, true);
149  }
150 
151  // draw translation sequence underneath the bar
152  if (true/*IsSelected()*/) {
153  CRgbaColor col("dark blue");
154  gl.ColorC(col);
156  seq_start + 0.5, trans_y, true);
157 
159  try {
160  string main_seq, tmp_seq;
161  vec.GetSeqData(seq_start - 1, seq_start + 2, tmp_seq);
162 
163  if (neg) { // reverse sequence on negative strand
165  0, static_cast<TSeqPos>(tmp_seq.length()), main_seq);
166  } else {
167  main_seq = tmp_seq;
168  }
169 
170  if (flip_strand) { // handle the flipped strand mode
171  reverse(main_seq.begin(), main_seq.end());
172  }
173 
174  m_Context->TextOut(&m_CdsConfig->m_TransFont, main_seq.c_str(),
175  seq_start + 0.5, gen_y, true);
176  }
177  catch (CException&) {
178  /// ignore exceptions - these are objmgr related
179  /// and indicate sequences that don't resolve
180  }
181  }
182  }
183 
184  // Use correct offset for the next interval
185  int diff = neg ? seq_start - ifrom : ito - seq_start;
186  if (diff == 2) {
187  offset = 0;
188  } else if (diff == 1) {
189  offset = 1;
190  } else if (diff == 0) {
191  offset = 2;
192  }
193  } // for
194 }
195 
196 
198 {
199  bool will_fit = false;
200  if (x_IsProjected()) {
202  int base_width = aln_mgr->GetBaseWidth(aln_mgr->GetAnchor());
203  static const float kSequenceLevel = 0.125; // = 1.0f / 8.0;
204  will_fit = (m_Context->GetScale() < kSequenceLevel / base_width);
205  } else {
206  will_fit = m_Context->WillSeqLetterFit();
207  }
208  // currrently we do not support rendering of the prot/codon for trans-spliced CDS
209  if (will_fit && GetFeature().IsSetExcept() && GetFeature().HasExceptionText("trans-splicing"))
210  will_fit = false;
211  return will_fit;
212 }
213 
214 
216 {
218  if (x_WillFit()) {
219  IRender& gl = GetGl();
220 
221  TModelUnit trans_full = gl.GetMetric(&(m_CdsConfig->m_TransFont),
223  SetHeight(GetHeight() + trans_full +
225  }
226 }
227 
228 
229 //#define HIGHLIGHT_MISMATCHES
230 
232  TModelUnit trans_y,
233  TModelUnit gen_y,
234  TModelUnit prot_y) const
235 {
236 
237  IRender& gl = GetGl();
238  bool flip_strand = m_Context->IsFlippedStrand();
239 
240  string cds_seq;
241  string prot_seq;
242  size_t gen_len = 0;
243  size_t prot_len = 0;
244  CScope& scope = GetMappedFeature().GetAnnot().GetScope();
245 
246  CConstRef<CSeq_feat> original_cds;
247  try {
248  CBioseq_Handle prot_bsh = scope.GetBioseqHandle(GetFeature().GetProduct());
249  if (prot_bsh) { // if product defined
250 
251  const CSeq_loc& product = GetFeature().GetProduct();
252  CSeqVector prot_vec(product, scope, CBioseq_Handle::eCoding_Iupac);
253  prot_len = prot_vec.size();
254  prot_vec.GetSeqData(0, static_cast<TSeqPos>(prot_len), prot_seq);
255  gen_len = prot_len * 3;
256 
257  // protein sequence (that CDS product is pointing to)
258  // is expected to be packed in nuc_prot set
259  // GetCDSProduct finds cds annotated on this nuc_prot
260  // so we could the original mrna annotation for this cds
261 
262  //string prot_acc = sequence::GetAccessionForId(*prot_bsh.GetSeqId(), prot_bsh.GetScope());
263  const CSeq_feat* sfp = sequence::GetCDSForProduct(prot_bsh);
264  if (sfp) {
266  v.GetSeqData(0, v.size(), cds_seq);
267  }
268  }
269 
270  } catch (CException&) {
271  // ignore exceptions - these arise if the product doesn't resolve
272  }
273 
274  if (cds_seq.empty()) {
276  v.GetSeqData(0, v.size(), cds_seq);
277  const CGenetic_code* genetic_code = GetFeature().GetData().GetCdregion().IsSetCode() ?
278  &GetFeature().GetData().GetCdregion().GetCode() : nullptr;
279  CSeqTranslator::Translate(cds_seq, prot_seq, CSeqTranslator::fIs5PrimePartial, genetic_code);
280  }
281  _ASSERT(!cds_seq.empty());
282  if (cds_seq.empty()) {
283  // unexpected error to get translated sequence
284  return;
285  }
286 
287  if (gen_len == 0) {
288  gen_len = GetLocation().GetTotalRange().GetLength();
289  prot_len = gen_len / 3 + 1;
290  }
291 
292 #ifdef HIGHLIGHT_MISMATCHES
293  string gen_seq;
295  // Get genetic code
296  string trans_seq;
297  const CGenetic_code* genetic_code = GetFeature().GetData().GetCdregion().IsSetCode() ?
298  &GetFeature().GetData().GetCdregion().GetCode() : nullptr;
299  CSeqTranslator::Translate(gen_seq, trans_seq, CSeqTranslator::fIs5PrimePartial, genetic_code);
300  if (cds_seq.empty()) // no original cds present
301  cds_seq = gen_seq;
302  if (prot_seq.empty())
303  prot_seq = trans_seq;
304  char prot_out[2];
305  prot_out[1] = '\0';
306 #endif
307 
309 
310  int anchor = aln_mgr->GetAnchor();
311  int aligned_seq = aln_mgr->GetQuery();
312  int base_width = aln_mgr->GetBaseWidth(anchor);
313  int anchor_step = base_width == 3 ? 1 : 3;
314 
315  // Temp strings holding the one-letter protein sequence
316  char prot_in[2];
317  prot_in[1] = '\0';
318 
319  static const CRgbaColor codon_mismatch_col("red");
320  static const CRgbaColor translated_col("dark blue");
321 
322  TSeqPos prot_offset = x_GetProtOffset() - 1;
323 
324  bool aligned_neg = aln_mgr->IsNegativeStrand(aligned_seq);
325  bool anchor_neg = aln_mgr->IsNegativeStrand(anchor);
326 
327  for (auto&& map_it : m_ProjectedMappingInfo) {
328  auto& anchor_range = map_it.m_AnchorRange;
329  if (m_Context->IntersectVisible(anchor_range).Empty())
330  continue;
331 
332  auto& prod_int = *map_it.m_ProductInt;
333  auto& gen_int = *map_it.m_MappedInt;
334  auto& prod_range = map_it.m_MappedProdRange;
335 
336  bool neg = gen_int.IsSetStrand() && gen_int.GetStrand() == eNa_strand_minus;
337  bool aln_strand = anchor_neg || aligned_neg;
338  int anchor_sign = (aln_strand && neg || !aln_strand && !neg) ? 1 : -1;
339 
340  TSeqRange gen_range(gen_int.GetFrom(), gen_int.GetTo());
341 
342  // prod_pos - position on transcript
343  TSeqPos prod_pos = prod_int.GetFrom();
344  TSeqPos prod_stop = prod_int.GetTo() + 1;
345 
346  prod_stop = min<int>(prod_stop, prod_pos + round(float(gen_range.GetLength()) / base_width));
347 
348  TSignedSeqPos pos = anchor_sign < 0 ?
349  anchor_range.GetTo() : anchor_range.GetFrom();
350 
351  // Align the first position to frame 1, middle of codon.
352  // If frame is already 2 (last codon position), don't draw it here,
353  // use the next frame 1 position
354 
355  int prod_from = prod_range.GetFrom();
356  int frame = prod_from > 0 ? prod_from % 3 : prot_offset;
357  TSeqPos prod_pos_f1 = (prod_from / 3) * 3 + 1;
358  pos += ((anchor_sign * anchor_step) / 3) * (prod_pos_f1 - prod_from);
359  if (frame > 1) {
360  pos += (anchor_sign * anchor_step);
361  }
362  while (prod_pos < prod_stop) {
363  if (prod_pos >= prot_seq.size())
364  break;
365 
366  if (anchor_sign > 0 && pos > (TSignedSeqPos)anchor_range.GetTo())
367  break;
368  if (anchor_sign < 0 && pos < (TSignedSeqPos)anchor_range.GetFrom())
369  break;
370  // if (pos >= m_Context->GetVisSeqFrom() && pos < m_Context->GetVisSeqTo()) {
371  prot_in[0] = 'X';
372  if (prod_pos < prot_seq.size())
373  prot_in[0] = prot_seq[prod_pos];
374 #ifdef HIGHLIGHT_MISMATCHES
375  prot_out[0] = 'X'
376  if (prod_pos < trans_seq.size())
377  prot_out[0] = trans_seq[prod_pos];
378  bool mismatch = (prot_in[0] != prot_out[0]);
379 
380  // draw original protein sequence
381  if (mismatch) {
384  pos + 0.5, prot_y, true);
385  }
386 #endif
387  TSeqPos p = prod_pos > 0 ? (prod_pos * 3) : 0;
388  string codon = cds_seq.substr(p, 3);
389 #ifdef HIGHLIGHT_MISMATCHES
390  string gen_codon = gen_seq.substr(p, 3);
391  gl.ColorC(codon != gen_codon ? codon_mismatch_col : m_CdsConfig->m_SeqProtTrans);
392 #else
394 #endif
395  if (m_Context->IsInVisibleRange(pos)) {
396  x_PutCodon(codon, pos, gen_y, flip_strand != (anchor_sign < 0), false);
397 
398  // draw translated protein sequence
399  gl.ColorC(translated_col);
400  m_Context->TextOut(&m_CdsConfig->m_ProdFont, prot_in, pos + 0.5, trans_y, true);
401  }
402  // }
403  prod_pos += 1;// base_width;
404  pos += anchor_sign * anchor_step;
405  }
406  }
407 }
408 
409 // set to enable dumping CDS info
410 // #define CDS_DEBUG
411 
413  TModelUnit trans_y,
414  TModelUnit gen_y,
415  TModelUnit prot_y) const
416 {
418 
419  IRender& gl = GetGl();
420  bool flip_strand = m_Context->IsFlippedStrand();
422  const CSeqVector& vec = seq_ds->GetSeqVector();
423 
424  string cds_seq;
425  string prot_seq;
426  size_t gen_len = 0;
427  size_t prot_len = 0;
428  CScope& scope = GetMappedFeature().GetAnnot().GetScope();
429 
430  TSeqPos offs = 0;
431  if (GetFeature().CanGetProduct()) try {
432  CBioseq_Handle prot_bsh = scope.GetBioseqHandle(GetFeature().GetProduct());
433  if (prot_bsh) {
434  const CSeq_loc& product = GetFeature().GetProduct();
435  CSeqVector prot_vec(product, scope, CBioseq_Handle::eCoding_Iupac);
436  prot_len = prot_vec.size();
437  prot_vec.GetSeqData(0, static_cast<TSeqPos>(prot_len), prot_seq);
438 #ifdef CDS_DEBUG
439  cerr << "prot_seq (obtained as feature product): " << endl << prot_seq << endl << "prot_seq.length(): " <<
440  prot_seq.length() << ", * 3: " << prot_seq.length() * 3 << endl;
441 #endif
442  gen_len = prot_len * 3;
443 
444  // protein sequence (that CDS product is pointing to)
445  // is expected to be packed in nuc_prot set
446  // GetCDSProduct finds cds annotated on this nuc_prot
447  // so we could the original mrna annotation for this cds
448  const CSeq_feat* sfp = sequence::GetCDSForProduct(prot_bsh);
449  if (sfp) {
450 #ifdef CDS_DEBUG
451  cerr << "sfp (cds feature obtained for the product): " << endl << MSerial_AsnText << *sfp << endl;
452 #endif
453  if (sfp->GetData().GetCdregion().IsSetFrame() && sfp->GetData().GetCdregion().GetFrame() > 1) {
454  offs = sfp->GetData().GetCdregion().GetFrame() - 1;
455  }
457  v.GetSeqData(0, v.size(), cds_seq);
458 #ifdef CDS_DEBUG
459  cerr << "cds_seq (obtained from product):" << endl << cds_seq << endl << "cds_seq.length(): " << cds_seq.length() <<
460  ", cds_start: " << sfp->GetLocation().GetTotalRange().GetFrom() << endl;
461 #endif
462  }
463  }
464  } catch (const CException&) {
465  // ignore exceptions - these arise if the product doesn't resolve
466  }
467 
468  if (gen_len == 0) {
469  gen_len = GetLocation().GetTotalRange().GetLength();
470  prot_len = gen_len / 3 + 1;
471  }
472 
473  // Get the mapped genomic sequence based the mapping intervals
474  string gen_seq;
475 #ifdef CDS_DEBUG
476  cerr << "gen_sec (parts of original seq obtained via intervals): " << endl;
477 #endif
478  gen_seq.reserve(gen_len);
479  {
480  TSeqPos pre_t1 = 0;
481  for (auto&& iter : GetMappingInfo()) {
482  // fill the gap on protein sequence with 'N'
483  TSeqPos f1 = iter.first->GetFrom();
484  TSeqPos f2 = iter.second->GetFrom();
485  TSeqPos t2 = iter.second->GetTo();
486  if(f1 > pre_t1) {
487  gen_seq.append(f1 - pre_t1, 'N');
488 #ifdef CDS_DEBUG
489  cerr << string(f1 - pre_t1, 'N');
490 #endif
491  }
492  string tmp_seq;
493  vec.GetSeqData(f2, t2 + 1, tmp_seq);
494  if (iter.second->GetStrand() == eNa_strand_minus) {
495  string seq;
497  0, static_cast<TSeqPos>(tmp_seq.length()), seq);
498  tmp_seq.swap(seq);
499  }
500  pre_t1 = iter.first->GetTo() + 1;
501  gen_seq += tmp_seq;
502 #ifdef CDS_DEBUG
503  cerr << tmp_seq.length() << ":\t" << tmp_seq << endl;
504 #endif
505  }
506  }
507 
508  // Get genetic code
509  const CGenetic_code* genetic_code = GetFeature().GetData().GetCdregion().IsSetCode() ? &GetFeature().GetData().GetCdregion().GetCode() : nullptr;
510  string trans_seq;
511  CSeqTranslator::Translate(gen_seq.substr(offs), trans_seq, CSeqTranslator::fIs5PrimePartial, genetic_code);
512 
513 #ifdef CDS_DEBUG
514  cerr << "trans_seq (translation from gen_seq): " << endl << trans_seq << endl << "trans_seq.length(): " <<
515  trans_seq.length() << ", * 3: " << trans_seq.length() * 3 << endl;
516 #endif
517  if (cds_seq.empty()) // no original cds present
518  cds_seq = gen_seq;
519  if (prot_seq.empty())
520  prot_seq = trans_seq;
521 
522  // Temp strings holding the one-letter protein sequence
523  char prot_in[2], prot_out[2];
524  prot_in [1] = '\0';
525  prot_out[1] = '\0';
526 
527  static const CRgbaColor codon_mismatch_col("red");
528  static const CRgbaColor translated_col("dark blue");
529 
530  CConstRef<CSeq_interval> prev_gen(0);
531  CConstRef<CSeq_interval> prev_prod(0);
532  auto current_exon = m_Intervals.begin();
533 
534  TModelUnit font_height = gl.TextHeight(&m_CdsConfig->m_ProdFont);
535  font_height *= 0.5;
536 
537  int prev_frame = 0;
538 
539  const CSeq_interval* previous_prod_int = nullptr;
540  for (auto&& map_it : GetMappingInfo()) {
541  auto& prod_int = *map_it.first;
542  auto& gen_int = *map_it.second;
543 
544  if (nullptr != previous_prod_int) {
545  if (previous_prod_int->GetTo() != (prod_int.GetFrom() - 1)) {
546  prev_frame += prod_int.GetFrom() - previous_prod_int->GetTo() - 1;
547  prev_frame %= 3;
548  }
549  }
550  previous_prod_int = &prod_int;
551 
552 #ifdef CDS_DEBUG
553  cerr << "product range: (" << prod_int.GetFrom() << ", " << prod_int.GetTo() << ")" << endl;
554  cerr << "general range: (" << gen_int.GetFrom() << ", " << gen_int.GetTo() << ")" << endl;
555 #endif
556 
557  bool neg = gen_int.IsSetStrand() && gen_int.GetStrand() == eNa_strand_minus;
558  TSeqRange gen_range(gen_int.GetFrom(), gen_int.GetTo());
559  int step = neg ? -3 : 3;
560  if (neg) {
561  while (current_exon != m_Intervals.end() && current_exon->GetFrom() > gen_range.GetTo()) {
562  ++current_exon;
563  prev_gen = 0;
564  }
565  } else {
566  while (current_exon != m_Intervals.end() && current_exon->GetTo() < gen_range.GetFrom()) {
567  ++current_exon;
568  prev_gen = 0;
569  }
570  }
571 
572  int frame = (gen_range.GetLength() + prev_frame) % 3;
573 
574  // if this interval is outside of the visible range, skip it
575  if (m_Context->IntersectVisible(gen_range).Empty()) {
576  prev_frame = frame;
577  continue;
578  }
579 
580  if (current_exon == m_Intervals.end())
581  prev_gen = 0;
582 
583  // prod_pos - position on transcript
584  TSeqPos prod_pos = prod_int.GetFrom();
585  TSeqPos prod_stop = min(prod_int.GetTo() + 1, (TSeqPos)gen_len);
586 
587  // c_pos - position on genomic sequence
588  TSeqPos c_pos = neg ? gen_range.GetTo() : gen_range.GetFrom();
589 
590  switch (prev_frame) {
591  case 0:
592  // segment's start is aligned with codon start
593  // move c_pos and prod_pos in the middle of the codon
594  c_pos += (neg ? -1 : 1);
595  prod_pos += 1;
596  break;
597  case 2:
598  // segment's start with last base of the codon
599  // move c_pos and prod_pos one step so it point to the middle iof the previous codon
600  c_pos += (neg ? 1 : -1);
601  prod_pos -= 1;
602  break;
603  default:
604  break;
605  }
606  prev_frame = frame;
607 
608  size_t prot_idx = (prod_pos > offs) ? (prod_pos - offs) / 3 : 0;
609 
610  string gen_codon;
611  string codon;
612 
613  while (prod_pos <= prod_stop) {
614 
615 
616  if (c_pos >= gen_range.GetFrom() && c_pos <= gen_range.GetTo() && m_Context->IsInVisibleRange(c_pos)) {
617 
618  prot_in[0] = prot_out[0] = 'X';
619  if (prot_idx < prot_seq.size())
620  prot_in[0] = prot_seq[prot_idx];
621  if (prot_idx < trans_seq.size())
622  prot_out[0] = trans_seq[prot_idx];
623  bool mismatch = (prot_in[0] != prot_out[0]);
624 
625  // draw original protein sequence
626  if (mismatch) {
628  m_Context->TextOut(&m_CdsConfig->m_ProdFont, prot_in, c_pos + 0.5, prot_y, true);
629  }
630  if (prod_pos - 1 < gen_seq.size())
631  gen_codon = gen_seq.substr(prod_pos - 1, 3);
632  else
633  gen_codon.clear();
634  if (prot_idx * 3 < cds_seq.size())
635  codon = cds_seq.substr(prot_idx * 3 + offs, 3);
636  else
637  codon.clear();
638  gl.ColorC(codon != gen_codon ? codon_mismatch_col : m_CdsConfig->m_SeqProtTrans);
639  x_PutCodon(codon, c_pos, gen_y, flip_strand != neg, false);
640 
641  // draw translated protein sequence
642  gl.ColorC(translated_col);
643  m_Context->TextOut(&m_CdsConfig->m_ProdFont, prot_in, c_pos + 0.5, trans_y, true);
644  }
645  prod_pos += 3 ;
646  c_pos += step;
647  ++prot_idx;
648  }
649  if (prev_gen != 0) {
650 
651  if (prev_prod->GetTo() + 1 != prod_int.GetFrom()) {
652  c_pos = neg ? gen_int.GetTo() + 1 : gen_int.GetFrom();
654  x_DrawInsertion(c_pos, prot_y - (font_height + font_height), prot_y, prot_y - font_height);
655  }
656  int gap_length = 0;
657  if (neg) {
658  if (prev_gen->GetFrom() - 1 != gen_int.GetTo()) {
659  c_pos = prev_gen->GetFrom() - 1;
660  gap_length = c_pos - gen_int.GetTo();
661  }
662  } else {
663  if (prev_gen->GetTo() + 1 != gen_int.GetFrom()) {
664  c_pos = prev_gen->GetTo() + 1;
665  gap_length = gen_int.GetFrom() - c_pos;
666  }
667  }
668  if (gap_length > 0) {
670 
671  while (gap_length > 0) {
672  m_Context->TextOut(&m_CdsConfig->m_ProdFont, "-", c_pos + 0.5, prot_y, true);
673  c_pos += (neg ? -1 : 1);
674  --gap_length;
675  }
676  }
677 
678  }
679  prev_gen.Reset(&gen_int);
680  prev_prod.Reset(&prod_int);
681 
682  }
683 }
684 
685 
686 void CCdsGlyph::x_PutCodon(const string& codon_str, TSeqPos pos,
687  TModelUnit y, bool neg, bool append) const
688 {
689  string new_codon = codon_str;
690  size_t len = codon_str.size();
691  if (len > 0 && len < 5) {
692  if (len == 2) {
693  if (append) new_codon += " ";
694  else new_codon.insert(0, " ");
695  }
696  if (neg) std::reverse(new_codon.begin(), new_codon.end());
697  m_Context->TextOut(&m_CdsConfig->m_ProdFont, new_codon.c_str(),
698  pos + 0.5, y, true);
699  }
700 }
701 
702 
User-defined methods of the data storage class.
T round(const T &v)
USING_SCOPE(objects)
static const int kVertSpace
Definition: cds_glyph.cpp:43
CBioseq_Handle –.
CRgbaColor m_SeqProtMismatch
mismatched sequence color.
Definition: cds_glyph.hpp:85
CGlTextureFont m_ProdFont
Definition: cds_glyph.hpp:91
CRgbaColor m_SeqProtTrans
translated sequence color.
Definition: cds_glyph.hpp:86
CGlTextureFont m_TransFont
Definition: cds_glyph.hpp:92
CRef< CCdsConfig > m_CdsConfig
Definition: cds_glyph.hpp:71
void x_DrawProtSeqWithMapping(TModelUnit trans_y, TModelUnit gen_y, TModelUnit prot_y) const
Definition: cds_glyph.cpp:412
void x_DrawProjectedProtSeq(TModelUnit trans_y, TModelUnit gen_y, TModelUnit prot_y) const
Definition: cds_glyph.cpp:231
void x_PutCodon(const string &codon_str, TSeqPos pos, TModelUnit y, bool neg, bool append) const
Definition: cds_glyph.cpp:686
virtual void x_Draw() const
The default renderer for this layout object.
Definition: cds_glyph.cpp:56
CCdsGlyph(const objects::CMappedFeat &feat)
bool x_WillFit() const
Definition: cds_glyph.cpp:197
virtual void x_UpdateBoundingBox()
Update the bounding box assuming children's sizes are fixed if any.
Definition: cds_glyph.cpp:215
TSeqPos x_GetProtOffset() const
Returns protein translation offset.
virtual void x_Draw() const
The default renderer for this layout object.
void x_DrawInsertion(TModelUnit SeqPosTriangleMidPointX, TModelUnit BoundaryYLow, TModelUnit BoundaryYHigh, TModelUnit YCenterLine) const
TIntervals m_Intervals
intervals (like for features or alignments).
virtual void x_UpdateBoundingBox()
Update the bounding box assuming children's sizes are fixed if any.
CConstRef< CFeatureParams > m_Config
All the configs needed for rendering a feature.
CProjectedMappingInfo m_ProjectedMappingInfo
const TMappingInfo & GetMappingInfo() const
virtual const objects::CSeq_loc & GetLocation(void) const
access the position of this object.
bool x_IsProjected() const
const objects::CMappedFeat & GetMappedFeature(void) const
Access a new, fully remapped feature.
const objects::CSeq_feat & GetFeature(void) const
Access the original feature.
TModelUnit GetBarHeight(bool overview) const
CMappedFeat –.
Definition: mapped_feat.hpp:59
void GetAnchorSequence(objects::CScope &scope, string &buffer) const
const IAlnGraphicDataSource * GetAlignmentDataSource() const
void TextOut(const CGlTextureFont *font, const char *text, TModelUnit x, TModelUnit y, bool center, bool adjust_flip=true) const
CRef< CSGSequenceDS > GetSeqDS() const
bool IsInVisibleRange(TSeqPos pos) const
TModelRange IntersectVisible(const CSeqGlyph *obj) const
const TModelUnit & GetScale() const
bool IsFlippedStrand() const
bool WillSeqLetterFit() const
is it enougth space to sequence letters.
class CRgbaColor provides a simple abstraction for managing colors.
Definition: rgba_color.hpp:58
objects::CScope & GetScope(void) const
Get the scope from the handle.
const objects::CSeqVector & GetSeqVector(void) const
CScope –.
Definition: scope.hpp:92
CRenderingContext * m_Context
the rendering context
Definition: seq_glyph.hpp:346
virtual void SetHeight(TModelUnit h)
Definition: seq_glyph.hpp:650
virtual TModelUnit GetTop() const
Definition: seq_glyph.hpp:599
virtual TModelUnit GetHeight() const
Definition: seq_glyph.hpp:587
static SIZE_TYPE ReverseComplement(const string &src, TCoding src_coding, TSeqPos pos, TSeqPos length, string &dst)
static SIZE_TYPE Complement(const string &src, TCoding src_coding, TSeqPos pos, TSeqPos length, string &dst)
@ e_Iupacna
Definition: sequtil.hpp:47
CSeqVector –.
Definition: seq_vector.hpp:65
namespace ncbi::objects::
Definition: Seq_feat.hpp:58
Seq-loc iterator class – iterates all intervals from a seq-loc in the correct order.
Definition: Seq_loc.hpp:453
virtual TSeqPos GetBaseWidth(IAlnExplorer::TNumrow) const =0
virtual IAlnExplorer::TNumrow GetAnchor() const =0
static void DLIST_NAME() append(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
Definition: dlist.tmpl.h:78
int offset
Definition: replacements.h:160
static FILE * f
Definition: readconf.c:23
unsigned int TSeqPos
Type for sequence locations and lengths.
Definition: ncbimisc.hpp:875
int TSignedSeqPos
Type for signed sequence position.
Definition: ncbimisc.hpp:887
string
Definition: cgiapp.hpp:690
GLdouble TModelUnit
Definition: gltypes.hpp:48
IRender & GetGl()
convenience function for getting current render manager
virtual TModelUnit TextHeight(const CGlTextureFont *font) const =0
virtual TModelUnit GetMetric(const CGlTextureFont *font, IGlFont::EMetric metric, const char *text=NULL, int len=-1) const =0
Calls the standard font metric functions except for pdf in which case it first replaces any bitmap fo...
virtual void ColorC(const CRgbaColor &c)=0
Set current color (glColor{3,4}{f,d}{v,})
@ eMetric_FullCharHeight
Definition: glfont.hpp:80
#define MSerial_AsnText
I/O stream manipulators –.
Definition: serialbase.hpp:696
TRange GetTotalRange(void) const
Definition: Seq_loc.hpp:913
const CSeq_feat * GetCDSForProduct(const CBioseq &product, CScope *scope)
Get the encoding CDS feature of a given protein sequence.
Definition: sequence.cpp:2549
static void Translate(const string &seq, string &prot, const CGenetic_code *code, bool include_stop=true, bool remove_trailing_X=false, bool *alt_start=NULL, bool is_5prime_complete=true, bool is_3prime_complete=true)
Translate a string using a specified genetic code.
Definition: sequence.cpp:4095
@ fIs5PrimePartial
= 0x4 Translate first codon even if not start codon (because sequence is 5' partial)
Definition: sequence.hpp:984
CBioseq_Handle GetBioseqHandle(const CSeq_id &id)
Get bioseq handle by seq-id.
Definition: scope.cpp:95
@ 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
TSeqPos size(void) const
Definition: seq_vector.hpp:291
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:1439
position_type GetLength(void) const
Definition: range.hpp:158
bool Empty(void) const
Definition: range.hpp:148
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:103
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:100
TTo GetTo(void) const
Get the To member data.
Definition: Range_.hpp:269
TFrom GetFrom(void) const
Get the From member data.
Definition: Range_.hpp:222
const TLocation & GetLocation(void) const
Get the Location member data.
Definition: Seq_feat_.hpp:1117
TFrame GetFrame(void) const
Get the Frame member data.
Definition: Cdregion_.hpp:534
const TData & GetData(void) const
Get the Data member data.
Definition: Seq_feat_.hpp:925
const TCdregion & GetCdregion(void) const
Get the variant data.
bool IsSetFrame(void) const
Check if a value has been assigned to Frame data member.
Definition: Cdregion_.hpp:509
TFrom GetFrom(void) const
Get the From member data.
TTo GetTo(void) const
Get the To member data.
@ eNa_strand_minus
Definition: Na_strand_.hpp:67
bm::gap_word_t gap_length(const bm::gap_word_t *buf) noexcept
Returs GAP block length.
Definition: bmfunc.h:1603
int len
constexpr bool empty(list< Ts... >) noexcept
T min(T x_, T y_)
static const float kSequenceLevel
string GetProduct(const CProt_ref &prot_ref)
#define _ASSERT
Modified on Fri Sep 20 14:58:20 2024 by modify_doxy.py rev. 669887