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 47485 2023-05-02 14:46:59Z ucko $
2  * ===========================================================================
3  *
4  * PUBLIC DOMAIN NOTICE
5  * National Center for Biotechnology Information
6  *
7  * This software/database is a "United States Government Work" under the
8  * terms of the United States Copyright Act. It was written as part of
9  * the author's official duties as a United States Government employee and
10  * thus cannot be copyrighted. This software/database is freely available
11  * to the public for use. The National Library of Medicine and the U.S.
12  * Government have not placed any restriction on its use or reproduction.
13  *
14  * Although all reasonable efforts have been taken to ensure the accuracy
15  * and reliability of the software and data, the NLM and the U.S.
16  * Government do not and cannot warrant the performance or results that
17  * may be obtained by using this software or data. The NLM and the U.S.
18  * Government disclaim all warranties, express or implied, including
19  * warranties of performance, merchantability or fitness for any particular
20  * purpose.
21  *
22  * Please cite the author in any work or product based on this material.
23  *
24  * ===========================================================================
25  *
26  * 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  int anchor_sign = (anchor_neg != aligned_neg && anchor_neg) || (aligned_neg != neg) ? -1 : 1;
338 
339  TSeqRange gen_range(gen_int.GetFrom(), gen_int.GetTo());
340 
341  // prod_pos - position on transcript
342  TSeqPos prod_pos = prod_int.GetFrom();
343  TSeqPos prod_stop = prod_int.GetTo() + 1;
344 
345  prod_stop = min<int>(prod_stop, prod_pos + round(float(gen_range.GetLength()) / base_width));
346 
347  TSignedSeqPos pos = anchor_sign < 0 ?
348  anchor_range.GetTo() : anchor_range.GetFrom();
349 
350  // Align the first position to frame 1, middle of codon.
351  // If frame is already 2 (last codon position), don't draw it here,
352  // use the next frame 1 position
353 
354  int prod_from = prod_range.GetFrom();
355  int frame = prod_from > 0 ? prod_from % 3 : prot_offset;
356  TSeqPos prod_pos_f1 = (prod_from / 3) * 3 + 1;
357  pos += ((anchor_sign * anchor_step) / 3) * (prod_pos_f1 - prod_from);
358  if (frame > 1) {
359  pos += (anchor_sign * anchor_step);
360  }
361  while (prod_pos < prod_stop) {
362  if (prod_pos >= prot_seq.size())
363  break;
364 
365  if (anchor_sign > 0 && pos > (TSignedSeqPos)anchor_range.GetTo())
366  break;
367  if (anchor_sign < 0 && pos < (TSignedSeqPos)anchor_range.GetFrom())
368  break;
369  // if (pos >= m_Context->GetVisSeqFrom() && pos < m_Context->GetVisSeqTo()) {
370  prot_in[0] = 'X';
371  if (prod_pos < prot_seq.size())
372  prot_in[0] = prot_seq[prod_pos];
373 #ifdef HIGHLIGHT_MISMATCHES
374  prot_out[0] = 'X'
375  if (prod_pos < trans_seq.size())
376  prot_out[0] = trans_seq[prod_pos];
377  bool mismatch = (prot_in[0] != prot_out[0]);
378 
379  // draw original protein sequence
380  if (mismatch) {
383  pos + 0.5, prot_y, true);
384  }
385 #endif
386  TSeqPos p = prod_pos > 0 ? (prod_pos * 3) : 0;
387  string codon = cds_seq.substr(p, 3);
388 #ifdef HIGHLIGHT_MISMATCHES
389  string gen_codon = gen_seq.substr(p, 3);
390  gl.ColorC(codon != gen_codon ? codon_mismatch_col : m_CdsConfig->m_SeqProtTrans);
391 #else
393 #endif
394  if (m_Context->IsInVisibleRange(pos)) {
395  x_PutCodon(codon, pos, gen_y, flip_strand != (anchor_sign < 0), false);
396 
397  // draw translated protein sequence
398  gl.ColorC(translated_col);
399  m_Context->TextOut(&m_CdsConfig->m_ProdFont, prot_in, pos + 0.5, trans_y, true);
400  }
401  // }
402  prod_pos += 1;// base_width;
403  pos += anchor_sign * anchor_step;
404  }
405  }
406 }
407 
408 // set to enable dumping CDS info
409 // #define CDS_DEBUG
410 
412  TModelUnit trans_y,
413  TModelUnit gen_y,
414  TModelUnit prot_y) const
415 {
417 
418  IRender& gl = GetGl();
419  bool flip_strand = m_Context->IsFlippedStrand();
421  const CSeqVector& vec = seq_ds->GetSeqVector();
422 
423  string cds_seq;
424  string prot_seq;
425  size_t gen_len = 0;
426  size_t prot_len = 0;
427  CScope& scope = GetMappedFeature().GetAnnot().GetScope();
428 
429  TSeqPos offs = 0;
430  if (GetFeature().CanGetProduct()) try {
431  CBioseq_Handle prot_bsh = scope.GetBioseqHandle(GetFeature().GetProduct());
432  if (prot_bsh) {
433  const CSeq_loc& product = GetFeature().GetProduct();
434  CSeqVector prot_vec(product, scope, CBioseq_Handle::eCoding_Iupac);
435  prot_len = prot_vec.size();
436  prot_vec.GetSeqData(0, static_cast<TSeqPos>(prot_len), prot_seq);
437 #ifdef CDS_DEBUG
438  cerr << "prot_seq (obtained as feature product): " << endl << prot_seq << endl << "prot_seq.length(): " <<
439  prot_seq.length() << ", * 3: " << prot_seq.length() * 3 << endl;
440 #endif
441  gen_len = prot_len * 3;
442 
443  // protein sequence (that CDS product is pointing to)
444  // is expected to be packed in nuc_prot set
445  // GetCDSProduct finds cds annotated on this nuc_prot
446  // so we could the original mrna annotation for this cds
447  const CSeq_feat* sfp = sequence::GetCDSForProduct(prot_bsh);
448  if (sfp) {
449 #ifdef CDS_DEBUG
450  cerr << "sfp (cds feature obtained for the product): " << endl << MSerial_AsnText << *sfp << endl;
451 #endif
452  if (sfp->GetData().GetCdregion().IsSetFrame() && sfp->GetData().GetCdregion().GetFrame() > 1) {
453  offs = sfp->GetData().GetCdregion().GetFrame() - 1;
454  }
456  v.GetSeqData(0, v.size(), cds_seq);
457 #ifdef CDS_DEBUG
458  cerr << "cds_seq (obtained from product):" << endl << cds_seq << endl << "cds_seq.length(): " << cds_seq.length() <<
459  ", cds_start: " << sfp->GetLocation().GetTotalRange().GetFrom() << endl;
460 #endif
461  }
462  }
463  } catch (const CException&) {
464  // ignore exceptions - these arise if the product doesn't resolve
465  }
466 
467  if (gen_len == 0) {
468  gen_len = GetLocation().GetTotalRange().GetLength();
469  prot_len = gen_len / 3 + 1;
470  }
471 
472  // Get the mapped genomic sequence based the mapping intervals
473  string gen_seq;
474 #ifdef CDS_DEBUG
475  cerr << "gen_sec (parts of original seq obtained via intervals): " << endl;
476 #endif
477  gen_seq.reserve(gen_len);
478  {
479  TSeqPos pre_t1 = 0;
480  for (auto&& iter : GetMappingInfo()) {
481  // fill the gap on protein sequence with 'N'
482  TSeqPos f1 = iter.first->GetFrom();
483  TSeqPos f2 = iter.second->GetFrom();
484  TSeqPos t2 = iter.second->GetTo();
485  if(f1 > pre_t1) {
486  gen_seq.append(f1 - pre_t1, 'N');
487 #ifdef CDS_DEBUG
488  cerr << string(f1 - pre_t1, 'N');
489 #endif
490  }
491  string tmp_seq;
492  vec.GetSeqData(f2, t2 + 1, tmp_seq);
493  if (iter.second->GetStrand() == eNa_strand_minus) {
494  string seq;
496  0, static_cast<TSeqPos>(tmp_seq.length()), seq);
497  tmp_seq.swap(seq);
498  }
499  pre_t1 = iter.first->GetTo() + 1;
500  gen_seq += tmp_seq;
501 #ifdef CDS_DEBUG
502  cerr << tmp_seq.length() << ":\t" << tmp_seq << endl;
503 #endif
504  }
505  }
506 
507  // Get genetic code
508  const CGenetic_code* genetic_code = GetFeature().GetData().GetCdregion().IsSetCode() ? &GetFeature().GetData().GetCdregion().GetCode() : nullptr;
509  string trans_seq;
510  CSeqTranslator::Translate(gen_seq.substr(offs), trans_seq, CSeqTranslator::fIs5PrimePartial, genetic_code);
511 
512 #ifdef CDS_DEBUG
513  cerr << "trans_seq (translation from gen_seq): " << endl << trans_seq << endl << "trans_seq.length(): " <<
514  trans_seq.length() << ", * 3: " << trans_seq.length() * 3 << endl;
515 #endif
516  if (cds_seq.empty()) // no original cds present
517  cds_seq = gen_seq;
518  if (prot_seq.empty())
519  prot_seq = trans_seq;
520 
521  // Temp strings holding the one-letter protein sequence
522  char prot_in[2], prot_out[2];
523  prot_in [1] = '\0';
524  prot_out[1] = '\0';
525 
526  static const CRgbaColor codon_mismatch_col("red");
527  static const CRgbaColor translated_col("dark blue");
528 
529  CConstRef<CSeq_interval> prev_gen(0);
530  CConstRef<CSeq_interval> prev_prod(0);
531  auto current_exon = m_Intervals.begin();
532 
533  TModelUnit font_height = gl.TextHeight(&m_CdsConfig->m_ProdFont);
534  font_height *= 0.5;
535 
536  int prev_frame = 0;
537 
538  const CSeq_interval* previous_prod_int = nullptr;
539  for (auto&& map_it : GetMappingInfo()) {
540  auto& prod_int = *map_it.first;
541  auto& gen_int = *map_it.second;
542 
543  if (nullptr != previous_prod_int) {
544  if (previous_prod_int->GetTo() != (prod_int.GetFrom() - 1)) {
545  prev_frame += prod_int.GetFrom() - previous_prod_int->GetTo() - 1;
546  prev_frame %= 3;
547  }
548  }
549  previous_prod_int = &prod_int;
550 
551 #ifdef CDS_DEBUG
552  cerr << "product range: (" << prod_int.GetFrom() << ", " << prod_int.GetTo() << ")" << endl;
553  cerr << "general range: (" << gen_int.GetFrom() << ", " << gen_int.GetTo() << ")" << endl;
554 #endif
555 
556  bool neg = gen_int.IsSetStrand() && gen_int.GetStrand() == eNa_strand_minus;
557  TSeqRange gen_range(gen_int.GetFrom(), gen_int.GetTo());
558  int step = neg ? -3 : 3;
559  if (neg) {
560  while (current_exon != m_Intervals.end() && current_exon->GetFrom() > gen_range.GetTo()) {
561  ++current_exon;
562  prev_gen = 0;
563  }
564  } else {
565  while (current_exon != m_Intervals.end() && current_exon->GetTo() < gen_range.GetFrom()) {
566  ++current_exon;
567  prev_gen = 0;
568  }
569  }
570 
571  int frame = (gen_range.GetLength() + prev_frame) % 3;
572 
573  // if this interval is outside of the visible range, skip it
574  if (m_Context->IntersectVisible(gen_range).Empty()) {
575  prev_frame = frame;
576  continue;
577  }
578 
579  if (current_exon == m_Intervals.end())
580  prev_gen = 0;
581 
582  // prod_pos - position on transcript
583  TSeqPos prod_pos = prod_int.GetFrom();
584  TSeqPos prod_stop = min(prod_int.GetTo() + 1, (TSeqPos)gen_len);
585 
586  // c_pos - position on genomic sequence
587  TSeqPos c_pos = neg ? gen_range.GetTo() : gen_range.GetFrom();
588 
589  switch (prev_frame) {
590  case 0:
591  // segment's start is aligned with codon start
592  // move c_pos and prod_pos in the middle of the codon
593  c_pos += (neg ? -1 : 1);
594  prod_pos += 1;
595  break;
596  case 2:
597  // segment's start with last base of the codon
598  // move c_pos and prod_pos one step so it point to the middle iof the previous codon
599  c_pos += (neg ? 1 : -1);
600  prod_pos -= 1;
601  break;
602  default:
603  break;
604  }
605  prev_frame = frame;
606 
607  size_t prot_idx = (prod_pos > offs) ? (prod_pos - offs) / 3 : 0;
608 
609  string gen_codon;
610  string codon;
611 
612  while (prod_pos <= prod_stop) {
613 
614 
615  if (c_pos >= gen_range.GetFrom() && c_pos <= gen_range.GetTo() && m_Context->IsInVisibleRange(c_pos)) {
616 
617  prot_in[0] = prot_out[0] = 'X';
618  if (prot_idx < prot_seq.size())
619  prot_in[0] = prot_seq[prot_idx];
620  if (prot_idx < trans_seq.size())
621  prot_out[0] = trans_seq[prot_idx];
622  bool mismatch = (prot_in[0] != prot_out[0]);
623 
624  // draw original protein sequence
625  if (mismatch) {
627  m_Context->TextOut(&m_CdsConfig->m_ProdFont, prot_in, c_pos + 0.5, prot_y, true);
628  }
629  if (prod_pos - 1 < gen_seq.size())
630  gen_codon = gen_seq.substr(prod_pos - 1, 3);
631  else
632  gen_codon.clear();
633  if (prot_idx * 3 < cds_seq.size())
634  codon = cds_seq.substr(prot_idx * 3 + offs, 3);
635  else
636  codon.clear();
637  gl.ColorC(codon != gen_codon ? codon_mismatch_col : m_CdsConfig->m_SeqProtTrans);
638  x_PutCodon(codon, c_pos, gen_y, flip_strand != neg, false);
639 
640  // draw translated protein sequence
641  gl.ColorC(translated_col);
642  m_Context->TextOut(&m_CdsConfig->m_ProdFont, prot_in, c_pos + 0.5, trans_y, true);
643  }
644  prod_pos += 3 ;
645  c_pos += step;
646  ++prot_idx;
647  }
648  if (prev_gen != 0) {
649 
650  if (prev_prod->GetTo() + 1 != prod_int.GetFrom()) {
651  c_pos = neg ? gen_int.GetTo() + 1 : gen_int.GetFrom();
653  x_DrawInsertion(c_pos, prot_y - (font_height + font_height), prot_y, prot_y - font_height);
654  }
655  int gap_length = 0;
656  if (neg) {
657  if (prev_gen->GetFrom() - 1 != gen_int.GetTo()) {
658  c_pos = prev_gen->GetFrom() - 1;
659  gap_length = c_pos - gen_int.GetTo();
660  }
661  } else {
662  if (prev_gen->GetTo() + 1 != gen_int.GetFrom()) {
663  c_pos = prev_gen->GetTo() + 1;
664  gap_length = gen_int.GetFrom() - c_pos;
665  }
666  }
667  if (gap_length > 0) {
669 
670  while (gap_length > 0) {
671  m_Context->TextOut(&m_CdsConfig->m_ProdFont, "-", c_pos + 0.5, prot_y, true);
672  c_pos += (neg ? -1 : 1);
673  --gap_length;
674  }
675  }
676 
677  }
678  prev_gen.Reset(&gen_int);
679  prev_prod.Reset(&prod_int);
680 
681  }
682 }
683 
684 
685 void CCdsGlyph::x_PutCodon(const string& codon_str, TSeqPos pos,
686  TModelUnit y, bool neg, bool append) const
687 {
688  string new_codon = codon_str;
689  size_t len = codon_str.size();
690  if (len > 0 && len < 5) {
691  if (len == 2) {
692  if (append) new_codon += " ";
693  else new_codon.insert(0, " ");
694  }
695  if (neg) std::reverse(new_codon.begin(), new_codon.end());
696  m_Context->TextOut(&m_CdsConfig->m_ProdFont, new_codon.c_str(),
697  pos + 0.5, y, true);
698  }
699 }
700 
701 
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:411
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:685
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
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:687
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_)
double f(double x_, const double &y_)
Definition: njn_root.hpp:188
static const float kSequenceLevel
string GetProduct(const CProt_ref &prot_ref)
#define _ASSERT
Modified on Tue Apr 16 20:07:23 2024 by modify_doxy.py rev. 669887