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

Go to the SVN repository for this file.

1 /* $Id: mate_pair_glyph.cpp 41823 2018-10-17 17:34:58Z katargir $
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: Vlad Lebedev, Liangshou Wu
27  *
28  * File Description:
29  * CMatePairGlyph -- utility class to layout mate pairs (a special type of
30  * pairwise alignments and hold a set of CAlignGlyph
31  */
32 
33 #include <ncbi_pch.hpp>
36 #include <gui/objutils/tooltip.hpp>
37 #include <gui/opengl/irender.hpp>
40 
41 
42 
45 
46 
48  : m_SeqAligns(aligns)
49  , m_LibraryId(eLibrary_NotSet)
50  , m_ErrorType(eError_NotSet)
51 {
52  if (m_SeqAligns.size() != 1) {
54  }
55 
56  const CSeq_id* id = NULL;
58  ITERATE (TAlignList, iter, m_SeqAligns) {
59  const CAlignGlyph& pw = **iter;
60  TSeqRange curr_r = pw.GetLocation().GetTotalRange();
61  range += curr_r;
62  id = &pw.GetAlignMgr().GetSeqId(pw.GetAlignMgr().GetAnchor());
63 
64  const CSeq_align_Handle& align = pw.GetOrigAlignment();
65  int type = 0;
66  if (m_ErrorType != eError_NoError &&
67  align.GetSeq_align()->GetNamedScore("bad matepair code", type)) {
68  m_ErrorType = static_cast<EErrorType>(type);
69  }
70  align.GetSeq_align()->GetNamedScore("matepair library", m_LibraryId);
71  m_Intervals.push_back(curr_r);
72  }
73 
76  }
77 
78  if (m_ErrorType == eError_NotSet) {
80  }
81 
82  // if not set, set it based on pairs' orientation
83  if (m_SeqAligns.size() == 2 && m_ErrorType == eError_NoError) {
84  if (m_SeqAligns[0]->IsNegative() == m_SeqAligns[1]->IsNegative()) {
86  } else {
88  }
89  }
90 
91  if (id) {
92  m_Location.Reset(new CSeq_loc());
93  m_Location->SetInt().SetFrom(range.GetFrom());
94  m_Location->SetInt().SetTo (range.GetTo());
95  m_Location->SetId(*id);
96  }
97 }
98 
99 
100 bool CMatePairGlyph::NeedTooltip(const TModelPoint& /*p*/, ITooltipFormatter& /*tt*/, string& /*t_title*/) const
101 {
102  return true;
103 }
104 
105 
106 void CMatePairGlyph::GetTooltip(const TModelPoint& p, ITooltipFormatter& tt, string& t_title) const
107 {
108  TModelPoint lcl_p(p);
109  x_World2Local(lcl_p);
110 /*
111  ITERATE(TAlignList, iter, m_SeqAligns) {
112  TModelPoint t = (*iter)->GetPos();
113  if ((*iter)->IsIn(lcl_p)) {
114  (*iter)->GetTooltip(p, tt, t_title);
115  break;
116  }
117  }
118 */
119  TModelUnit bar_h = m_SeqAligns.front()->GetBarHeight();
120  TModelUnit verticalOffset(0.0);
121  // In case two mate pair ends overlap, the second one is put right under the first one.
122  if (2 == m_SeqAligns.size()) {
123  if (m_SeqAligns[0]->GetRange().IntersectingWith(m_SeqAligns[1]->GetRange()))
124  verticalOffset = bar_h;
125  }
126  TSeqRange r(GetLeft(), GetRight());
127  TModelUnit t_y = 0;
128  bool show_label = m_Config->m_ShowLabel && m_Context->WillLabelFit(r);
129  if (show_label) {
130  IRender& gl = GetGl();
131  t_y += gl.TextHeight(&(m_Config->m_LabelFont)) + 4;
132  }
133 
134  for (const auto& aln_g : m_SeqAligns) {
135  if (lcl_p.m_Y >= t_y && lcl_p.m_Y <= t_y + bar_h) {
136  const auto& r = aln_g->GetRange();
137  if (lcl_p.m_X >= r.GetFrom() && lcl_p.m_X <= r.GetTo()) {
138  aln_g->GetTooltip(p, tt, t_title);
139  break;
140  }
141  }
142  t_y += verticalOffset;
143  }
144 
145 }
146 
147 
149 {
150  TModelUnit bar_h = m_SeqAligns.front()->GetBarHeight();
151  TModelUnit verticalOffset(0.0);
152  // In case two mate pair ends overlap, the second one is put right under the first one.
153  if (2 == m_SeqAligns.size()) {
154  if (m_SeqAligns[0]->GetRange().IntersectingWith(m_SeqAligns[1]->GetRange()))
155  verticalOffset = bar_h;
156  }
157 
158  TModelUnit t_x = 0;
159  TModelUnit t_y = 0;
160  x_Local2World(t_x, t_y);
161 
162  t_y += GetHeight();
163 
165  CHTMLActiveArea area;
166  TVPUnit x1 = m_Context->SeqToScreenXClipped((*iter)->GetLeft());
167  TVPUnit x2 = m_Context->SeqToScreenXClipped((*iter)->GetRight());
168  if (m_Context->IsFlippedStrand()) {
169  x1 = -x1;
170  x2 = -x2;
171  }
172 
173  TVPUnit y1 = TVPUnit(t_y - bar_h);
174  TVPUnit y2 = TVPUnit(t_y);
175 
176  t_y -= verticalOffset;
177 
178  area.m_Bounds.Init(x1, y2, x2, y1);
179  area.m_SeqRange = (*iter)->GetRange();
180  area.m_Signature = (*iter)->GetSignature();
181  p_areas->push_back(area);
182  }
183 }
184 
186 {
187  return m_Location->GetTotalRange();
188 }
189 
190 
192 {
193  return true;
194 }
195 
196 
197 const objects::CSeq_loc& CMatePairGlyph::GetLocation(void) const
198 {
199  return *m_Location;
200 }
201 
202 
204 {
205  ITERATE (TAlignList, iter, m_SeqAligns) {
206  CConstRef<CObject> obj = (*iter)->GetObject(pos);
207  if (obj.NotEmpty()) {
208  return obj;
209  }
210  }
211  return CConstRef<CObject>();
212 }
213 
214 
216 {
217  ITERATE (TAlignList, iter, m_SeqAligns) {
218  (*iter)->GetObjects(objs);
219  }
220 }
221 
222 
224 {
225  ITERATE(TAlignList, iter, m_SeqAligns) {
226  if ( (*iter)->HasObject(obj) ) {
227  m_ObjSel.push_back(obj);
228  return true;
229  }
230  }
231  return false;
232 }
233 
234 
236 {
237  // always return the signature of the first alignment
238  ITERATE (TAlignList, iter, m_SeqAligns) {
239  return (*iter)->GetSignature();
240  }
241  return string();
242 }
243 
244 
246 {
247  return m_Intervals;
248 }
249 
250 
252 {
253  ITERATE(vector<CConstRef<CObject> >, iter, m_ObjSel) {
254  if (pw_aln->HasObject(*iter))
255  return true;
256  }
257  return false;
258 }
259 
260 
262 {
263  if (!GetVisible())
264  return;
266  {
267  (*iter)->SetVisible(true);
268  (*iter)->SetTearline(GetTearline());
269  (*iter)->SetRowNum(GetRowNum());
270  }
271  IRender& gl = GetGl();
272 
273  TModelRect rcm = GetModelRect();
276 
277  TModelUnit yy = rcm.Top();
278  bool show_label = m_Config->m_ShowLabel && m_Context->WillLabelFit(inrc);
279  if (show_label) {
280  yy += gl.TextHeight(&(m_Config->m_LabelFont)) + 4;
281  }
282 
283  TModelUnit bar_h = m_SeqAligns.front()->GetBarHeight();
284 
285  // Set Colors based on Error code for Mate Pairs
286  CRgbaColor c_fg, c_seq, c_mis;
287  switch (GetError()) {
288  case eError_Orientation:
289  c_fg = m_Config->m_FGOrientation;
290  c_seq = m_Config->m_SeqOrientation;
292  break;
293  case eError_NonUnique:
294  c_fg = m_Config->m_FGNonUnique;
295  c_seq = m_Config->m_SeqNonUnique;
297  break;
298  case eError_Distance:
299  c_fg = m_Config->m_FGDistance;
300  c_seq = m_Config->m_SeqDistance;
302  break;
303  case eError_CoAlign:
304  c_fg = m_Config->m_FGCoAlign;
305  c_seq = m_Config->m_SeqNo;
306  c_mis = m_Config->m_SeqMismatchNo;
307  break;
308  case eError_ContraAlign:
309  c_fg = m_Config->m_FGContraAlign;
310  c_seq = m_Config->m_SeqNo;
311  c_mis = m_Config->m_SeqMismatchNo;
312  break;
313  default:
314  c_fg = m_Config->m_FGNo;
315  c_seq = m_Config->m_SeqNo;
316  c_mis = m_Config->m_SeqMismatchNo;
317  break;
318  }
319 
320  // Draw each Pairwise Alignment inside
321  // If two mates overlap, move the second one below the first one
322  TModelUnit y_off = 0.0;
323  if (m_SeqAligns.size() == 2 &&
324  m_SeqAligns[0]->GetRange().IntersectingWith(m_SeqAligns[1]->GetRange())) {
325  y_off = bar_h;
326  }
327  TModelUnit yTop = yy;
328  ITERATE(TAlignList, iter, m_SeqAligns) {
329  TSeqRange l_range = (*iter)->GetRange();
330  TModelRect rcm_pw(l_range.GetFrom(), yTop + bar_h, l_range.GetTo(), yTop);
331  (*iter)->ApplyFading();
332  (*iter)->DrawPWAlignElem(rcm_pw, false, false, c_fg, c_seq, c_mis);
333  yTop += y_off;
334  }
335 
336 
337  auto fade_factor = GetFadeFactor();
338  if (fade_factor != 1.) {
339  gl.Enable(GL_BLEND);
340  gl.BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
341  }
342  // draw link between mate pairs
343  if (m_SeqAligns.size() == 2) {
344  CRgbaColor c(m_Config->m_FGLink, fade_factor);
345  gl.ColorC(c);
346  gl.LineWidth(1.0f);
347  gl.Disable(GL_LINE_SMOOTH);
348  gl.LineStipple(2, 0xAAAA);
349  gl.Enable(GL_LINE_STIPPLE);
350 
351  //TSeqRange r1 = m_SeqAligns[0]->GetRange();
352  //TSeqRange r2 = m_SeqAligns[1]->GetRange();
355  TSeqRange inter_r = r1.IntersectionWith(r2);
356  if (inter_r.Empty()) {
357  TSeqPos from = r1.GetFrom() < r2.GetFrom() ? r1.GetTo() : r2.GetTo();
358  TSeqPos to = r1.GetFrom() < r2.GetFrom() ? r2.GetFrom() : r1.GetFrom();
359  _ASSERT(from <= to);
360  auto gap = m_Context->ScreenToSeq(1);
361  m_Context->DrawLine(from + gap, yy + bar_h * 0.5f - 1.0, to + gap, yy + bar_h * 0.5f - 1.0);
362  } else {
363  m_Context->DrawLine(inter_r.GetFrom(), yy + bar_h, inter_r.GetTo(), yy + bar_h);
364  }
365  gl.Disable(GL_LINE_STIPPLE);
366  }
367 
368  /*
369  // Highlight background based on Library ID
370  if (m_ConfigSettings->GetShowAlignBg() &&
371  pair->GetLibraryId() > 0 &&
372  m_ConfigSettings->GetShowPWAlignLabels()) {
373  CRgbaColor color = m_ColorTable.GetColor(pair->GetLibraryId());
374  gl.Color4f(color.GetRed(), color.GetGreen(), color.GetBlue(), 0.1f);
375  x_DrawQuad(rcm, horz);
376  }
377  */
378 
379  // draw label
380  if (show_label) {
381  string title;
382  x_GetTitle(&title, CLabel::eDefault);
383 
384  TModelUnit widthP = m_Context->SeqToScreen(inrc.GetLength());
385  title = m_Config->m_LabelFont.Truncate(title.c_str(), widthP);
386 
387  CRgbaColor text_color(IsSelected() ?
389  fade_factor);
390  gl.ColorC(text_color);
391 
392  TModelUnit xM = (inrc.GetFrom() + inrc.GetTo()) * 0.5;
393  m_Context->TextOut(&m_Config->m_LabelFont, title.c_str(), xM, yy - 2, true);
394  } // done with labels
395 
396  if (IsSelected()) {
397  m_Context->DrawSelection(rcm);
398  }
399 }
400 
401 
403 {
404  IRender& gl = GetGl();
405 
406  bool overlap = m_SeqAligns.size() == 2 &&
407  m_SeqAligns[0]->GetRange().IntersectingWith(m_SeqAligns[1]->GetRange());
408 
409  TAlignList::iterator iter = m_SeqAligns.begin();
410  while (iter != m_SeqAligns.end()) {
411  (*iter)->Update(true);
412  ++iter;
413  }
414 
415  iter = m_SeqAligns.begin();
416  TModelRange range((*iter)->GetLeft(), (*iter)->GetRight());
417  ++iter;
418  if (iter != m_SeqAligns.end()) {
419  range.CombineWith(TModelRange((*iter)->GetLeft(), (*iter)->GetRight()));
420  }
421  SetLeft(range.GetFrom());
422  SetWidth(range.GetLength());
423 
424  SetHeight(m_SeqAligns.front()->GetBarHeight());
425 
426  // in case two mate pair ends overlap, we put the second one
427  // right under the first one.
428  if (overlap) {
429  SetHeight(2*GetHeight());
430  }
432  bool show_label = m_Config->m_ShowLabel && m_Context->WillLabelFit(inrc);
433  TModelUnit yy = 0;// GetTop();
434 
435  if (show_label) {
436  auto label_height = gl.TextHeight(&(m_Config->m_LabelFont)) + 4;
437  SetHeight(GetHeight() + label_height);
438  yy += label_height;
439  }
440 
441  // Adjust the coordinates of the alignments
442 
443  TModelUnit bar_h = m_SeqAligns.front()->GetBarHeight();
444  // If two mates overlap, move the second one below the first one
445  TModelUnit y_off = overlap ? bar_h : 0.0;
446  TModelUnit yTop = yy;
448  (*iter)->SetTop(yTop);
449  yTop += y_off;
450  }
451 }
452 
453 
455 {
456  *title = "Mate Pair: ";
457  string tmp = "";
458 
459  ITERATE(TAlignList, iter, m_SeqAligns) {
460  if (tmp.length() > 0) *title = *title + " / ";
461  tmp.erase();
462  (*iter)->GetTitle(&tmp, type);
463  *title = *title + tmp;
464  }
465 }
466 
468 
CRgbaColor m_FGOrientation
CRgbaColor m_FGDistance
CRgbaColor m_FGContraAlign
CRgbaColor m_SeqDistance
CRgbaColor m_SeqNonUnique
CGlTextureFont m_LabelFont
CRgbaColor m_SeqOrientation
CRgbaColor m_SeqMismatchNo
CRgbaColor m_FGCoAlign
CRgbaColor m_SeqMismatchNonUnique
CRgbaColor m_FGNonUnique
CRgbaColor m_SeqMismatchDistance
CRgbaColor m_SeqMismatchOrientation
TIntervals m_Intervals
virtual void GetObjects(vector< CConstRef< CObject > > &objs) const
retrieve CObjects corresponding to this CSeqGlyph.
CRef< objects::CSeq_loc > m_Location
bool IsPairSelected(const CAlignGlyph *pw_aln) const
virtual const TIntervals & GetIntervals(void) const
access sub-intervals (if any).
virtual bool IsClickable() const
Query if this glyph is clickable.
EErrorType m_ErrorType
CMatePairGlyph(const TAlignList &aligns)
virtual bool HasObject(CConstRef< CObject > obj) const
check if the wrapped object(s) is the one.
vector< CRef< CAlignGlyph > > TAlignList
virtual TSeqRange GetRange(void) const
get the total range of this object.
virtual string GetSignature() const
return signature for this glyph.
EErrorType GetError() const
virtual void GetTooltip(const TModelPoint &p, ITooltipFormatter &tt, string &t_title) const
Get the tooltip if available.
virtual void x_UpdateBoundingBox()
Update the bounding box assuming children's sizes are fixed if any.
virtual const objects::CSeq_loc & GetLocation(void) const
access the position of this object.
void x_GetTitle(string *title, CLabel::ELabelType type) const
virtual void GetHTMLActiveAreas(TAreaVector *p_areas) const
Get html active areas.
TAlignList m_SeqAligns
vector< CConstRef< CObject > > m_ObjSel
virtual bool NeedTooltip(const TModelPoint &p, ITooltipFormatter &tt, string &t_title) const
Check if need to show tooltip.
CConstRef< CMatePairConfig > m_Config
virtual CConstRef< CObject > GetObject(TSeqPos pos) const
access our core component - we wrap an object(s) of some sort.
virtual void x_Draw() const
The default renderer for this layout object.
void TextOut(const CGlTextureFont *font, const char *text, TModelUnit x, TModelUnit y, bool center, bool adjust_flip=true) const
TModelRange IntersectVisible(const CSeqGlyph *obj) const
TVPUnit SeqToScreenXClipped(const TModelUnit &size) const
void DrawLine(TModelUnit x1, TModelUnit y1, TModelUnit x2, TModelUnit y2) const
void DrawSelection(const TModelRect &rc) const
TModelUnit SeqToScreen(const TModelUnit &size) const
convert from sequence positions to screen pixels
TModelUnit ScreenToSeq(const TModelUnit &size) const
convert from screen pixels to sequence positions
bool IsFlippedStrand() const
const CRgbaColor & GetSelLabelColor() const
bool WillLabelFit(const TModelRect &rc) const
class CRgbaColor provides a simple abstraction for managing colors.
Definition: rgba_color.hpp:58
CRenderingContext * m_Context
the rendering context
Definition: seq_glyph.hpp:346
virtual void SetHeight(TModelUnit h)
Definition: seq_glyph.hpp:650
virtual TModelUnit GetRight() const
Definition: seq_glyph.hpp:603
virtual void SetWidth(TModelUnit w)
Definition: seq_glyph.hpp:646
bool IsSelected() const
Definition: seq_glyph.hpp:573
virtual void SetLeft(TModelUnit l)
Definition: seq_glyph.hpp:654
virtual TModelUnit GetHeight() const
Definition: seq_glyph.hpp:587
float GetFadeFactor() const
Definition: seq_glyph.hpp:742
size_t GetRowNum() const
Definition: seq_glyph.hpp:281
size_t GetTearline() const
Definition: seq_glyph.hpp:736
size_t GetVisible() const
Definition: seq_glyph.hpp:284
void x_Local2World(TModelPoint &p) const
Transform the coordiantes from local coord. to world coord.
Definition: seq_glyph.hpp:726
virtual TModelUnit GetWidth() const
Definition: seq_glyph.hpp:591
virtual TModelUnit GetLeft() const
Definition: seq_glyph.hpp:595
TModelRect GetModelRect() const
get the bounding box.
Definition: seq_glyph.hpp:562
vector< CHTMLActiveArea > TAreaVector
Definition: seq_glyph.hpp:84
void x_World2Local(TModelPoint &p) const
Transform the coordiante from world coord. to local coord.
Definition: seq_glyph.hpp:722
bool GetNamedScore(const string &id, int &score) const
Get score.
Definition: Seq_align.cpp:563
virtual const objects::CSeq_id & GetSeqId(TNumrow row) const =0
vector< TSeqRange > TIntervals
virtual IAlnExplorer::TNumrow GetAnchor() const =0
primitive interface to arrange tabular data in the tooltips
Definition: tooltip.hpp:55
static int type
Definition: getdata.c:31
static char tmp[3200]
Definition: utf8.c:42
unsigned int TSeqPos
Type for sequence locations and lengths.
Definition: ncbimisc.hpp:875
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:815
#define NON_CONST_ITERATE(Type, Var, Cont)
Non constant version of ITERATE macro.
Definition: ncbimisc.hpp:822
#define REVERSE_ITERATE(Type, Var, Cont)
ITERATE macro to reverse sequence through container elements.
Definition: ncbimisc.hpp:827
string
Definition: cgiapp.hpp:687
#define NULL
Definition: ncbistd.hpp:225
virtual bool HasObject(CConstRef< CObject > obj) const
check if the wrapped object(s) is the one.
const IAlnGraphicDataSource & GetAlignMgr(void) const
Inline methods.
const objects::CSeq_align_Handle & GetOrigAlignment(void) const
virtual const objects::CSeq_loc & GetLocation(void) const
access the position of this object.
GLdouble TModelUnit
Definition: gltypes.hpp:48
virtual void Enable(GLenum glstate)=0
virtual void LineStipple(GLint factor, GLushort pattern)=0
Set line stipple pattern: glLineStipple(). Deprecated in gl 3.2+.
void Init()
Definition: glrect.hpp:62
T Top() const
Definition: glrect.hpp:84
virtual void BlendFunc(GLenum sfactor, GLenum dfactor)=0
Options to be used when GL_BLEND is enabled.
IRender & GetGl()
convenience function for getting current render manager
virtual TModelUnit TextHeight(const CGlTextureFont *font) const =0
int TVPUnit
Definition: gltypes.hpp:47
CRange< TModelUnit > TModelRange
Definition: gltypes.hpp:56
virtual void Disable(GLenum glstate)=0
glDisable()
virtual void LineWidth(GLfloat w)=0
Set line width for drawing: glLineWidth()
virtual void ColorC(const CRgbaColor &c)=0
Set current color (glColor{3,4}{f,d}{v,})
string Truncate(const char *text, TModelUnit w, ETruncate trunc=eTruncate_Ellipsis) const
Truncate text to the secified width.
ELabelType
Definition: label.hpp:60
@ eDefault
Definition: label.hpp:73
CConstRef< CSeq_align > GetSeq_align(void) const
Get const reference to current seq-align.
void Reset(void)
Reset reference object.
Definition: ncbiobj.hpp:773
bool NotEmpty(void) const THROWS_NONE
Check if CConstRef is not empty – pointing to an object and has a non-null value.
Definition: ncbiobj.hpp:1392
position_type GetLength(void) const
Definition: range.hpp:158
TThisType IntersectionWith(const TThisType &r) const
Definition: range.hpp:312
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
USING_SCOPE(objects)
range(_Ty, _Ty) -> range< _Ty >
double r(size_t dimension_, const Int4 *score_, const double *prob_, double theta_)
Definition: type.c:6
#define _ASSERT
Modified on Mon Jun 17 05:11:35 2024 by modify_doxy.py rev. 669887