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

Go to the SVN repository for this file.

1 /* $Id: gui_object_info_variant.cpp 38803 2017-06-20 20:36:33Z 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 * Gui Object Info class specifically for structural variations from dbVar.
30 *
31 */
32 
41 #include <gui/objutils/tooltip.hpp>
42 
45 
47 {
48 public:
49  virtual string GetSubtype() const;
50  virtual void GetToolTip(ITooltipFormatter& tooltip, string& t_title, TSeqPos at_p = (TSeqPos)-1) const;
51  virtual void GetLinks(ITooltipFormatter& links, bool no_ncbi_base) const;
52 };
53 
54 
56 {
57  return "Structural variant";
58 }
59 
60 
61 static int s_GetChildNum(const objects::CSeq_feat& feat)
62 {
63  string num_str = feat.GetNamedQual("Child Count");
64  if ( !num_str.empty() ) {
65  try {
66  return NStr::StringToInt(num_str);
67  } catch (CException&) {
68  // ingore it
69  }
70  }
71  return -1;
72 }
73 
74 
75 void CGuiObjectInfoVariant::GetToolTip(ITooltipFormatter& tooltip, string& t_title, TSeqPos /*at_p*/) const
76 {
78 
79  const CVariation_ref& var = m_Feat->GetData().GetVariation();
80  string validation = "Not Tested";
81  string additional_info = kEmptyStr;
82 
83  if (var.IsSetId()) {
84  string id_text;
85  var.GetId().GetLabel(&id_text);
86  tooltip.AddRow("Variation ID:", id_text);
87  }
88 
89  if (var.IsSetData() && var.GetData().IsSet() && var.GetData().GetSet().IsSetVariations()) {
90  list<string> alleles;
91  int allele_len = -1;
92  auto var_list = var.GetData().GetSet().GetVariations();
93  for (auto iVariation = var_list.begin(); iVariation != var_list.end(); ++iVariation) {
94  if ((*iVariation)->IsSetData() && (*iVariation)->GetData().IsInstance()) {
95  const CVariation_ref::TData::TInstance& VarInst((*iVariation)->GetData().GetInstance());
96  if (!VarInst.CanGetDelta())
97  continue;
98 
99  ITERATE(CVariation_ref::TData::TInstance::TDelta, iDelta, VarInst.GetDelta()) {
100  if ((*iDelta)->CanGetSeq()) {
101  const CDelta_item::C_Seq& DeltaSeq((*iDelta)->GetSeq());
102  switch (DeltaSeq.Which()) {
104  {
105  if (DeltaSeq.GetLiteral().CanGetSeq_data()) {
106  const CSeq_data& Seq_data(DeltaSeq.GetLiteral().GetSeq_data());
107  // variations normally use Iupacna/Iupacaa
108  string sAllele;
109  if (Seq_data.IsIupacna())
110  sAllele = Seq_data.GetIupacna().Get().empty() ? "-" : Seq_data.GetIupacna().Get();
111  if (Seq_data.IsIupacaa())
112  sAllele = Seq_data.GetIupacaa().Get().empty() ? "-" : Seq_data.GetIupacaa().Get();
113 
114  if (!sAllele.empty())
115  alleles.push_back(sAllele);
116 
117  if (-1 == allele_len)
118  allele_len = DeltaSeq.GetLiteral().GetLength();
119  }
120  break;
121  }
123  default:
124  // no specific processing for other deltas
125  break;
126  }
127  }
128  }
129  }
130  }
131  if ( !alleles.empty() ) {
132  tooltip.AddRow("Alleles:", NStr::Join(alleles, "/"));
133  }
134  if (allele_len > -1) {
135  tooltip.AddRow("Allele Length:", NStr::NumericToString(allele_len, NStr::fWithCommas));
136  }
137  }
138 
139  if (var.IsSetValidated()) {
140  if (var.GetValidated()) {
141  validation = "Yes";
142  } else {
143  validation = "Fail";
144  }
145  } else if (var.IsSetVariant_prop() && var.GetVariant_prop().IsSetOther_validation()) {
146  if (var.GetVariant_prop().GetOther_validation()) {
147  validation = "Yes";
148  } else {
149  validation = "Fail";
150  }
151  } else if (m_Feat->IsSetExts()) {
152  const CSeq_feat::TExts& exts = m_Feat->GetExts();
153  ITERATE (CSeq_feat::TExts, iter, exts) {
154  if ( (*iter)->GetType().IsStr() &&
155  NStr::EqualNocase((*iter)->GetType().GetStr(), "Validation") &&
156  (*iter)->GetFieldRef("Status") &&
157  (*iter)->GetFieldRef("Status")->GetData().IsStr()) {
158  validation = (*iter)->GetFieldRef("Status")->GetData().GetStr();
159  CConstRef<CUser_field> a_field = (*iter)->GetFieldRef("Addition");
160  if (a_field) {
161  additional_info = a_field->GetData().GetStr();
162  }
163  break;
164  }
165  }
166  }
167 
168  // phenotype and clinical-significance
169  string phenotype = "";
170  string clinical_sig = "";
171  if (var.CanGetPhenotype()) {
172  ITERATE (CVariation_ref::TPhenotype, pnt_iter, var.GetPhenotype()) {
173  if (clinical_sig.empty() && (*pnt_iter)->CanGetClinical_significance()) {
174  clinical_sig = NSnp::ClinSigAsString((*pnt_iter)->GetClinical_significance());
175  }
176 
177  if (phenotype.empty() && (*pnt_iter)->CanGetTerm()) {
178  phenotype = (*pnt_iter)->GetTerm();
179  }
180  }
181  }
182 
183  string sample_sex = "";
184  if (var.CanGetSomatic_origin()) {
185  ITERATE (CVariation_ref::TSomatic_origin, so_iter, var.GetSomatic_origin()) {
186  if ((*so_iter)->CanGetSource() &&
187  (*so_iter)->GetSource().GetSubtype() == CSubSource::eSubtype_sex) {
188  sample_sex = (*so_iter)->GetSource().GetName();
189  break;
190  }
191  }
192  }
193 
194  bool is_sv = !var.IsSetId() || (var.GetId().GetTag().IsStr() &&
195  var.GetId().GetTag().GetStr().find("sv") == 1);
196 
197  // allele type
198  string variant_type;
199  int multiplier = -1;
200  if (var.IsComplex()) {
201  variant_type = "Complex";
202  } else if (var.IsInsertion()) {
203  variant_type = "Insertion";
204  } else if (var.IsInversion()) {
205  variant_type = "Inversion";
206  } else if (var.IsEversion()) {
207  variant_type = "Tandem duplication";
208  } else if (var.IsTranslocation()) {
209  variant_type = "Translocation";
210  } else if (var.IsDeletion()) {
211  variant_type = "Deletion";
212  } else if (var.IsDeletionInsertion()) {
213  variant_type = "Indel";
214  } else if (var.IsSNV()) {
215  variant_type = "Single nucleotide variant";
216  } else if (var.IsCNV()) {
217  if (var.GetData().GetInstance().IsSetDelta()) {
218  const CVariation_inst::TDelta& delta = var.GetData().GetInstance().GetDelta();
219  ITERATE (CVariation_inst::TDelta, iter, delta) {
220  if ((*iter)->IsSetMultiplier()) {
221  multiplier = (*iter)->GetMultiplier();
222  break;
223  }
224  }
225  }
226  if (is_sv) {
227  variant_type = "Copy number variation";
228  } else {
229  if (var.IsGain()) {
230  variant_type = "Copy number gain";
231  } else if (var.IsLoss()) {
232  variant_type = "Copy number loss";
233  } else {
234  variant_type = "Copy number variation";
235  }
236  }
237  } else { // everything else is treated as 'unknown' regardless
238  variant_type = "Unknown";
239  }
240 
241  if (is_sv) {
242  int child_num = s_GetChildNum(*m_Feat);
243  if (child_num == 0) {
244  // sv, but treated as ssv
245  is_sv = false;
246  } else {
247  if (child_num > 0) {
248  tooltip.AddRow("Supporting Variant Calls:", NStr::IntToString(child_num));
249  }
250  tooltip.AddRow("Variant Region Type:", variant_type);
251  if (multiplier > -1) {
252  tooltip.AddRow("Copy Number:", NStr::NumericToString(multiplier));
253  }
254  if ( !phenotype.empty() ) {
255  tooltip.AddRow("Phenotype:", phenotype);
256  }
257  if ( !clinical_sig.empty() ) {
258  tooltip.AddRow("Clinical Interpretation:", clinical_sig);
259  }
260  if ( !sample_sex.empty() ) {
261  tooltip.AddRow("Gender:", sample_sex);
262  }
263  tooltip.AddRow("Validation Status:", validation);
264  if ( !additional_info.empty() ) {
265  tooltip.AddRow("Additional Info:", additional_info);
266  }
267  if (m_Feat->IsSetComment()) {
268  tooltip.AddRow("Comment:", m_Feat->GetComment());
269  }
270 
271  if (m_Location) {
272  tooltip.AddRow("Total Length:", NStr::IntToString(m_Location->GetTotalRange().GetLength(), NStr::fWithCommas));
273  }
274  }
275  }
276 
277  if ( !is_sv ) {
278  if (var.CanGetParent_id()) {
279  string parent;
280  if (var.GetParent_id().GetTag().IsId()) {
281  parent = NStr::IntToString(var.GetParent_id().GetTag().GetId());
282  } else {
283  parent = var.GetParent_id().GetTag().GetStr();
284  }
285  tooltip.AddRow("Parent Variant Region:", parent);
286  }
287 
288  tooltip.AddRow("Variant Call Type:", variant_type);
289  if (multiplier > -1) {
290  tooltip.AddRow("Copy Number:", NStr::NumericToString(multiplier));
291  }
292  if ( !phenotype.empty() ) {
293  tooltip.AddRow("Phenotype:", phenotype);
294  }
295  if ( !clinical_sig.empty() ) {
296  tooltip.AddRow("Clinical Interpretation:", clinical_sig);
297  }
298  if ( !sample_sex.empty() ) {
299  tooltip.AddRow("Gender:", sample_sex);
300  }
301 
302  // inheritance
304  if (var.IsSetAllele_origin()) {
305  org = var.GetAllele_origin();
306  } else if (var.IsSetVariant_prop() && var.GetVariant_prop().IsSetAllele_origin()) {
307  org = var.GetVariant_prop().GetAllele_origin();
308  }
309 
310  if (org > 0) {
311  string inh;
313  inh += "somatic ";
314  }
316  inh += "inherited ";
317  }
319  inh += "paternal ";
320  }
322  inh += "maternal ";
323  }
325  inh += "de_novo ";
326  }
328  inh += "biparental ";
329  }
331  inh += "uniparental ";
332  }
334  inh += "not-tested ";
335  }
337  inh += "tested-inconclusive ";
338  }
340  inh += "other";
341  }
342 
344  inh = "unknown";
345  }
346 
347  tooltip.AddRow("Inheritance:", inh);
348  }
349 
350  // validation status
351  tooltip.AddRow("Validation Status:", validation);
352  if ( !additional_info.empty() ) {
353  tooltip.AddRow("Additional Info:", additional_info);
354  }
355 
356  if (m_Feat->CanGetComment()) {
357  tooltip.AddRow("Comment:", m_Feat->GetComment());
358  }
359  }
360 
361  int allele_len = -1;
362  if (var.GetData().IsInstance() && var.GetData().GetInstance().IsSetDelta()) {
363  const CVariation_inst::TDelta& delta = var.GetData().GetInstance().GetDelta();
364  ITERATE (CVariation_inst::TDelta, iter, delta) {
365  if ((*iter)->IsSetSeq() && (*iter)->GetSeq().IsLiteral()) {
366  allele_len = (*iter)->GetSeq().GetLiteral().GetLength();
367  break;
368  }
369  }
370  }
371  if (allele_len > -1) {
372  tooltip.AddRow("Allele Length:", NStr::NumericToString(allele_len, NStr::fWithCommas));
373  }
374  if (var.CanGetSample_id()) {
375  string sample_id;
376  const CVariation_ref::TSample_id& sid = var.GetSample_id();
377  if (sid.IsStr()) {
378  sample_id = sid.GetStr();
379  } else {
380  sample_id = NStr::NumericToString(sid.GetId());
381  }
382  if ( !sample_id.empty() ) {
383  tooltip.AddRow("Sample id:", sample_id);
384  }
385  }
386 }
387 
388 static const string kBaseUrl = "http://ncbi.nlm.nih.gov/dbvar/";
389 
390 void CGuiObjectInfoVariant::GetLinks(ITooltipFormatter& links, bool no_ncbi_base) const
391 {
392  // maps link names to link urls and labels (allows links with same name to be consolidated)
393  // (I don't see for dbvar that links generally require this, but it was an issue in
394  // CGuiObjectInfoSeq_feat
396  CIRef<ITooltipFormatter> tmp_links = links.CreateInstance();
397 
398  const CVariation_ref& var = m_Feat->GetData().GetVariation();
399  string label, name, url;
400  if (var.CanGetId() && var.GetId().GetTag().IsStr() &&
401  var.GetId().GetTag().GetStr().find("sv") == 1) {
403  } else if (var.CanGetParent_id()) {
404  if (var.GetParent_id().GetTag().IsId()) {
405  label = NStr::IntToString(var.GetParent_id().GetTag().GetId());
406  } else {
407  label = var.GetParent_id().GetTag().GetStr();
408  }
409  }
410 
411  if ( !label.empty() ) {
412  name = "dbVar";
413  url = kBaseUrl + "variants/" + label;
414  tmp_links->AddLinkRow("dbVar", label, url);
415  }
416 
417  if (m_Feat->IsSetExts()) {
418  ITERATE (CSeq_feat::TExts, iter, m_Feat->GetExts()) {
419  if ((*iter)->GetType().IsStr() &&
420  !(*iter)->GetData().empty()) {
421  name = "Other Variant Calls from this Sample";
422  if ((*iter)->GetType().GetStr() == "related calls") {
423  const CUser_object::TData& fields = (*iter)->GetData();
424  if (fields.size() < 5) {
425  ITERATE (CUser_object::TData, f_iter, fields) {
426  label = (*f_iter)->GetLabel().GetStr();
427  url = kBaseUrl + "variants/" + (*f_iter)->GetData().GetStr();
428  //table_rows += CSeqUtils::CreateLinkRow(name, label, url);
429  link_map[name].push_back(std::pair<string, string>(label, url));
430  }
431  } else if (var.CanGetSample_id()) {
432  string term;
433  if (var.GetSample_id().IsStr()) {
434  term = var.GetSample_id().GetStr();
435  } else {
436  term = NStr::NumericToString(var.GetSample_id().GetId());
437  }
438  CConstRef<CDbtag> study_id = m_Feat->GetNamedDbxref("study_accession");
439  if (study_id) {
440  term += " and " + study_id->GetTag().GetStr();
441  }
442 
443  label = NStr::NumericToString(fields.size());
444  url = kBaseUrl + "?term=" + term;
445  //table_rows += CSeqUtils::CreateLinkRow(name, label, url);
446  link_map[name].push_back(std::pair<string, string>(label, url));
447  }
448  break;
449  } else if ((*iter)->GetType().GetStr() == "related call count") {
450  string term;
451  ITERATE (CUser_object::TData, f_iter, (*iter)->GetData()) {
452  if ((*f_iter)->GetLabel().IsStr() && (*f_iter)->GetData().IsStr()) {
453  label = (*f_iter)->GetLabel().GetStr();
454  term = (*f_iter)->GetData().GetStr();
455  break;
456  }
457  }
458 
459  if ( !term.empty() ) {
460  CConstRef<CDbtag> study_id = m_Feat->GetNamedDbxref("study_accession");
461  if (study_id) {
462  term += " and " + study_id->GetTag().GetStr();
463  }
464  url = kBaseUrl + "?term=" + term;
465  //table_rows += CSeqUtils::CreateLinkRow(name, label, url);
466  link_map[name].push_back(std::pair<string, string>(label, url));
467  }
468  break;
469  }
470  }
471  }
472  }
473 
474  // Create links, consolidating links with same name into a single row
475  map<string, vector<pair<string, string> > >::iterator iter;
476  for (iter=link_map.begin(); iter != link_map.end(); ++iter) {
477  string table_rows;
478 
479  for (size_t i=0; i<(*iter).second.size(); ++i) {
480  // This gives a separate row to each link:
481  //tmp_links += CSeqUtils::CreateLinkRow((*iter).first, (*uiter).first, (*uiter).second);
482  if (i>0) table_rows += ",&nbsp;";
483  table_rows += tmp_links->CreateLink((*iter).second[i].first, (*iter).second[i].second);
484  }
485  tmp_links->AddLinkRow((*iter).first, table_rows, 250);
486  }
487 
488  if ( !tmp_links->IsEmpty()) {
489  links.AddLinksTitle("Go To");
490  links.Append(*tmp_links);
491  }
492 }
493 
494 
Use commas as thousands separator.
Definition: ncbistr.hpp:270
static string NumericToString(TNumeric value, TNumToStringFlags flags=0, int base=10)
Convert numeric value to string.
Definition: ncbistr.hpp:664
TObjectType * GetPointer(void) THROWS_NONE
Get pointer,.
Definition: ncbiobj.hpp:989
unsigned int TSeqPos
Type for sequence locations and lengths.
Definition: ncbimisc.hpp:855
bool CanGetSample_id(void) const
Check if it is safe to call GetSample_id method.
const TStr & GetStr(void) const
Get the variant data.
const TData & GetData(void) const
Get the Data member data.
User-defined methods of the data storage class.
same location as variation-ref itself
const TParent_id & GetParent_id(void) const
Get the Parent_id member data.
list< CRef< CDelta_item > > TDelta
CConstRef< objects::CSeq_feat > m_Feat
#define kEmptyStr
Definition: ncbistr.hpp:121
vector< CRef< CUser_field > > TData
CRef< objects::CScope > m_Scope
#define ITERATE(Type, Var, Cont)
ITERATE macro to sequence through container elements.
Definition: ncbimisc.hpp:795
int i
static string Join(const TContainer &arr, const CTempString &delim)
Join strings using the specified delimiter.
Definition: ncbistr.hpp:2632
bool CanGetId(void) const
Check if it is safe to call GetId method.
virtual void Append(const ITooltipFormatter &tooltip)=0
appends another formatter to this one
static string IntToString(int value, TNumToStringFlags flags=0, int base=10)
Convert int to string.
Definition: ncbistr.hpp:4807
#define END_NCBI_SCOPE
End previously defined NCBI scope.
Definition: ncbistl.hpp:101
TId GetId(void) const
Get the variant data.
Definition: Object_id_.hpp:270
CConstRef< CUser_field > GetFieldRef(const string &str, const string &delim=".", NStr::ECase use_case=NStr::eCase) const
Return a field reference representing the tokenized key, or a NULL reference if the key doesn't exist...
Definition: User_field.cpp:226
const TStr & GetStr(void) const
Get the variant data.
Definition: Object_id_.hpp:297
list< CRef< CPhenotype > > TPhenotype
virtual void GetToolTip(ITooltipFormatter &tooltip, string &t_title, TSeqPos at_p=(TSeqPos)-1) const
Get tooltip.
User-defined methods of the data storage class.
virtual CIRef< ITooltipFormatter > CreateInstance()=0
creates another instance of the same tooltip formatter
static int s_GetChildNum(const objects::CSeq_feat &feat)
virtual void GetLinks(ITooltipFormatter &links, bool no_ncbi_base) const
Get a set of links.
bool IsId(void) const
Check if variant Id is selected.
Definition: Object_id_.hpp:264
static const char label[]
CVariation_inst –.
list< CRef< CUser_object > > TExts
Definition: Seq_feat_.hpp:127
Int4 delta(size_t dimension_, const Int4 *score_)
primitive interface to arrange tabular data in the tooltips
Definition: tooltip.hpp:54
Definition: map.hpp:337
const TId & GetId(void) const
Get the Id member data.
User-defined methods of the data storage class.
static void GetLabel(const CObject &obj, string *label, ELabelType type=eDefault)
Definition: label.cpp:140
CConstRef< objects::CSeq_loc > m_Location
Mapped location in top sequence coordinate (can be set externally).
list< CRef< C_E_Somatic_origin > > TSomatic_origin
const TTag & GetTag(void) const
Get the Tag member data.
Definition: Dbtag_.hpp:259
static bool EqualNocase(const CTempString str, SIZE_TYPE pos, SIZE_TYPE n, const char *pattern)
Case-insensitive equality of a substring with a pattern.
Definition: ncbistr.hpp:5078
USING_SCOPE(objects)
bool CanGetParent_id(void) const
Check if it is safe to call GetParent_id method.
virtual void AddRow(const string &sContents="", unsigned colspan=2)=0
add a row with a cell, spanning across all columns
User-defined methods of the data storage class.
static string ClinSigAsString(const CVariation_ref &var, ELetterCase LetterCase=eLetterCase_Mixed)
get a human-readable text for various clinical significance types
Definition: snp_utils.cpp:165
const_iterator begin() const
Definition: map.hpp:151
User-defined methods of the data storage class.
static const string kBaseUrl
virtual string GetSubtype() const
#define BEGIN_NCBI_SCOPE
Define ncbi namespace.
Definition: ncbistl.hpp:98
bool IsStr(void) const
Check if variant Str is selected.
Definition: Object_id_.hpp:291
virtual void AddLinksTitle(const string &sTitle)=0
add a row with the links title
const TPrim & Get(void) const
Definition: serialbase.hpp:347
const TSample_id & GetSample_id(void) const
Get the Sample_id member data.
User-defined methods of the data storage class.
static int StringToInt(const CTempString str, TStringToNumFlags flags=0, int base=10)
Convert string to int.
Definition: ncbistr.cpp:576
const TIupacna & GetIupacna(void) const
Get the variant data.
Definition: Seq_data_.hpp:510
Modified on Thu Jun 21 12:32:59 2018 by modify_doxy.py rev. 546573