libpappsomspp
Library for mass spectrometry
massspectrumwidget.cpp
Go to the documentation of this file.
1 /**
2  * \file pappsomspp/widget/spectrumwidget/massspectrumwidget.cpp
3  * \date 22/12/2017
4  * \author Olivier Langella
5  * \brief plot a sectrum and annotate with peptide
6  */
7 
8 
9 /*******************************************************************************
10  * Copyright (c) 2017 Olivier Langella <Olivier.Langella@u-psud.fr>.
11  *
12  * This file is part of the PAPPSOms++ library.
13  *
14  * PAPPSOms++ is free software: you can redistribute it and/or modify
15  * it under the terms of the GNU General Public License as published by
16  * the Free Software Foundation, either version 3 of the License, or
17  * (at your option) any later version.
18  *
19  * PAPPSOms++ is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22  * GNU General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public License
25  * along with PAPPSOms++. If not, see <http://www.gnu.org/licenses/>.
26  *
27  * Contributors:
28  * Olivier Langella <Olivier.Langella@u-psud.fr> - initial API and
29  *implementation
30  ******************************************************************************/
31 #include "massspectrumwidget.h"
32 #include "../../pappsoexception.h"
33 #include "../../peptide/peptidenaturalisotopelist.h"
34 #include <QDebug>
35 #include <QWidget>
36 
37 
38 using namespace pappso;
39 
41  : GraphicDeviceWidget(parent)
42 {
43  qDebug();
44 
45  _ms_level = 1;
47  _custom_plot = nullptr;
48 
49  this->setLayout(new QHBoxLayout(this));
50 
51  this->layout()->setContentsMargins(0,0,0,0);
52  setVisibleMassDelta(false);
53  qDebug();
54 }
56 {
57 }
58 
59 bool
60 MassSpectrumWidget::savePdf(const QString &fileName, int width, int height)
61 {
62 
63  if(_custom_plot != nullptr)
64  {
65  return _custom_plot->savePdf(fileName, width, height);
66  }
67  else
68  {
69  return false;
70  }
71 }
72 
73 
74 void
75 MassSpectrumWidget::toQPaintDevice(QPaintDevice *device, const QSize &size)
76 {
77 
78  if(_custom_plot != nullptr)
79  {
80  QCPPainter painter;
81  painter.begin(device);
82  _custom_plot->toPainter(&painter, size.width(), size.height());
83  painter.end();
84  }
85 }
86 void
88 {
89  qDebug();
90  if(_custom_plot != nullptr)
91  {
92  if(visible == _is_visible_mass_delta)
93  return;
94  delete _custom_plot;
95  }
96  _is_visible_mass_delta = visible;
97  while(auto item = this->layout()->takeAt(0))
98  {
99  delete item->widget();
100  }
101  qDebug();
102  _custom_plot = new QCPSpectrum(this, visible);
103  this->layout()->addWidget(_custom_plot);
104  qDebug();
105  _custom_plot->xAxis->setLabel("m/z");
106  _custom_plot->yAxis->setLabel("intensity");
107  qDebug();
108  _custom_plot->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
109  _custom_plot->axisRect()->setRangeDrag(Qt::Horizontal);
110  _custom_plot->axisRect()->setRangeZoom(Qt::Horizontal);
111  qDebug();
112  // legend->setVisible(false);
113  // legend->setFont(QFont("Helvetica",9));
114  // set locale to english, so we get english decimal separator:
115  // setLocale(QLocale(QLocale::English, QLocale::UnitedKingdom));
116  qDebug();
117 }
118 void
120 {
121  qDebug();
123  qDebug();
124  _custom_plot->clearItems();
126  qDebug();
127 }
128 
129 void
130 MassSpectrumWidget::setPeptideCharge(unsigned int parent_ion_charge)
131 {
132  _peptide_charge = parent_ion_charge;
133 }
134 void
135 MassSpectrumWidget::setIonList(const std::list<PeptideIon> &ion_list)
136 {
137  _ion_list = ion_list;
138 }
139 
140 void
141 MassSpectrumWidget::setMsLevel(unsigned int ms_level)
142 {
143  qDebug() << "ms_level=" << ms_level;
144  _ms_level = ms_level;
145 
146 
147  if(_ms_level == 1)
148  {
149  setVisibleMassDelta(false);
150  }
151  else
152  {
153  setVisibleMassDelta(true);
154  }
155 
156  //_precision._precision = precision._precision;
157 }
158 void
160 {
161  qDebug() << "precision->toString()=" << precision->toString();
162  _p_ms1_precision = precision;
163  //_precision._precision = precision._precision;
164 }
165 void
167 {
168  qDebug() << "precision->toString()=" << precision->toString();
169  _p_ms2_precision = precision;
170  //_precision._precision = precision._precision;
171 }
172 
173 void
174 MassSpectrumWidget::setMaximumIsotopeNumber(unsigned int max_isotope_number)
175 {
176  _max_isotope_number = max_isotope_number;
177 }
178 
179 void
180 MassSpectrumWidget::setMaximumIsotopeRank(unsigned int max_isotope_rank)
181 {
182  _max_isotope_rank = max_isotope_rank;
183 }
184 void
186 {
187  qDebug() << " _max_isotope_number=" << _max_isotope_number;
188  clearData();
190  if((_spectrum_sp == nullptr) || (_peptide_sp == nullptr))
191  {
192  }
193  else
194  {
195  if(_ms_level > 1)
196  {
197  PeptideIsotopeSpectrumMatch psm_match(*(_spectrum_sp.get()),
198  _peptide_sp,
201  _ion_list,
204 
205  _peak_ion_isotope_match_list = std::list<PeakIonIsotopeMatch>(
206  psm_match.getPeakIonIsotopeMatchList().begin(),
207  psm_match.getPeakIonIsotopeMatchList().end());
208  }
209  else
210  {
211  }
213  }
214  qDebug();
215 }
216 
217 void
219 {
220  qDebug();
221  _peptide_sp = peptide_sp;
222 
223  // clearData();
224  qDebug();
225 }
226 
227 void
229 {
230  qDebug();
231  _spectrum_sp = spectrum;
232 
233  clearData();
234  qDebug();
235 }
236 
237 void
239 {
240  qDebug();
241 
243 
244  /*
245  if (_p_delta_axis_rect != nullptr) {
246  _p_delta_axis_rect->axis(QCPAxis::AxisType::atLeft)->rescale();
247  }
248  */
249  _custom_plot->replot();
250  qDebug();
251 }
252 
253 void
255  const QualifiedMassSpectrum &spectrum)
256 {
257  qDebug() << "spectrum.getPrecursorCharge()=" << spectrum.getPrecursorCharge();
258 
259  setMsLevel(spectrum.getMsLevel());
261 
262  qDebug();
263 }
264 
265 void
267 {
268 
269  qDebug();
270  peptideAnnotate();
271  if(_ms_level == 1)
272  {
273  if(_spectrum_sp != nullptr)
274  {
275  if(_isotope_mass_list.size() > 0)
276  {
277 
278  qDebug() << "_isotope_mass_list.size()="
279  << _isotope_mass_list.size();
280  std::sort(_isotope_mass_list.begin(),
281  _isotope_mass_list.end(),
284  return a.get()->getMz() < b.get()->getMz();
285  });
286 
287  if(_isotope_mass_list.size() > 0)
288  {
289  PeptideNaturalIsotopeAverageSp precursor_peptide =
290  _isotope_mass_list.at(0);
291  qDebug() << "precursor_peptide.get()->getMz()="
292  << precursor_peptide.get()->getMz();
293  MzRange precursor_mass(precursor_peptide.get()->getMz(),
295  DataPoint monoisotope_peak;
296  monoisotope_peak.y = 0;
297 
298  for(const DataPoint &peak : *(_spectrum_sp.get()))
299  {
300  if(precursor_mass.contains(peak.x))
301  {
302  if(peak.y > monoisotope_peak.y)
303  {
304  qDebug() << "SpectrumWidget::plot "
305  "(peak.intensity > "
306  "monoisotope_peak.intensity) ";
307  monoisotope_peak = peak;
308  }
309  }
310  }
311  if(monoisotope_peak.y > 0)
312  {
313  qDebug() << "addMs1IsotopePattern";
315  monoisotope_peak.y);
316  }
317  }
318  }
319  }
320  }
321  else
322  {
323  qDebug();
325  [](const PeakIonIsotopeMatch &a, const PeakIonIsotopeMatch &b) {
326  qDebug() << a.getPeak().y << " > ";
327  qDebug() << b.getPeak().y << " . ";
328  return (a.getPeak().y > b.getPeak().y);
329  });
330  qDebug();
331  unsigned int i = 0;
332 
333  qDebug();
334  for(const PeakIonIsotopeMatch &peak_ion_match :
336  {
337  _custom_plot->addPeakIonIsotopeMatch(peak_ion_match);
338 
339  _custom_plot->addMassDelta(peak_ion_match);
340  //_p_delta_graph->addData(peak_ion_match.getPeak().x,
341  // peak_ion_match.getPeak().y);
342  if(i < _tag_nmost_intense)
343  {
344  QCPItemText *text_label = new QCPItemText(_custom_plot);
345  text_label->setVisible(true);
346  //_custom_plot->addItem(text_label);
347  text_label->setPositionAlignment(Qt::AlignBottom |
348  Qt::AlignHCenter);
349  text_label->position->setType(QCPItemPosition::ptPlotCoords);
350  text_label->position->setCoords(
351  peak_ion_match.getPeak().x,
352  peak_ion_match.getPeak()
353  .y); // place position at center/top of axis rect
354  text_label->setFont(QFont(font().family(), 8));
355  text_label->setText(
356  peak_ion_match.getPeptideFragmentIonSp()
357  .get()
358  ->getCompletePeptideIonName(peak_ion_match.getCharge()));
359  // text_label->setPen(QPen(PeptideFragmentIon::getPeptideIonColor(peak_ion_match.getPeptideIonType()),
360  // 1)); // show black border around text
361  text_label->setColor(
363  peak_ion_match.getPeptideIonType())));
364  }
365  i++;
366  }
367  }
368 
369  qDebug();
370  _custom_plot->replot();
371  qDebug();
372 }
373 void
375 {
376  emit mzChanged(mz);
377 }
378 
379 void
381 {
382  qDebug() << "p_peak_match=" << p_peak_match;
383  if(_p_mouse_peak != p_peak_match)
384  {
385  _p_mouse_peak = p_peak_match;
386  DataPointCstSPtr peak_shp;
387  // emit peakChanged(peak_shp);
388  if(_p_mouse_peak != nullptr)
389  {
390  qDebug() << "_p_mouse_peak->x=" << _p_mouse_peak->x;
391  peak_shp = _p_mouse_peak->makeDataPointCstSPtr();
392  emit peakChanged(peak_shp);
393  // try to find matched ion (if it exists)
394  bool found = false;
395  for(const PeakIonIsotopeMatch &peak_ion_match :
397  {
398  if(peak_ion_match.getPeak().x == _p_mouse_peak->x)
399  {
400  // found
401  emit ionChanged(std::make_shared<const PeakIonIsotopeMatch>(
402  PeakIonIsotopeMatch(peak_ion_match)));
403  found = true;
404  }
405  }
406  if(!found)
407  {
408  emit ionChanged(std::shared_ptr<const PeakIonIsotopeMatch>());
409  }
410  }
411  else
412  {
413  qDebug() << "no peak";
414  emit peakChanged(peak_shp);
415  }
416  }
417 }
418 
419 void
421 {
422  qDebug() << "_p_ms1_precision->toString()=" << _p_ms1_precision->toString();
423  _isotope_mass_list.resize(0);
424  // compute isotope masses :
425  if(_peptide_sp != nullptr)
426  {
428  std::map<unsigned int, pappso::pappso_double> map_isotope_number =
429  isotope_list.getIntensityRatioPerIsotopeNumber();
430 
431  for(unsigned int i = 0; i < map_isotope_number.size(); i++)
432  {
433 
434  unsigned int asked_rank = 0;
435  unsigned int given_rank = 0;
436  bool more_rank = true;
437  while(more_rank)
438  {
439  asked_rank++;
440  pappso::PeptideNaturalIsotopeAverage isotopeAverageMono(
441  isotope_list, asked_rank, i, _peptide_charge, _p_ms1_precision);
442  given_rank = isotopeAverageMono.getIsotopeRank();
443  if(given_rank < asked_rank)
444  {
445  more_rank = false;
446  }
447  else if(isotopeAverageMono.getIntensityRatio() == 0)
448  {
449  more_rank = false;
450  }
451  else
452  {
453  // isotopeAverageMono.makePeptideNaturalIsotopeAverageSp();
454  _isotope_mass_list.push_back(
455  isotopeAverageMono.makePeptideNaturalIsotopeAverageSp());
456  }
457  }
458  }
459  }
460 }
461 
462 void
464 {
465 
466  if(_ms_level > 1)
467  {
468  pappso_double precursor_mz_1 = _peptide_sp->getMz(1);
469  _custom_plot->highlightPrecursorPeaks(
470  precursor_mz_1, 1, _p_ms2_precision);
471  pappso_double precursor_mz_charge = _peptide_sp->getMz(_peptide_charge);
472  _custom_plot->highlightPrecursorPeaks(
473  precursor_mz_charge, _peptide_charge, _p_ms2_precision);
474  }
475 }
void toQPaintDevice(QPaintDevice *device, const QSize &size) override
bool savePdf(const QString &fileName, int width=0, int height=0)
std::vector< pappso::PeptideNaturalIsotopeAverageSp > _isotope_mass_list
list of isotope precursors
void setQualifiedMassSpectrum(const QualifiedMassSpectrum &spectrum)
void peakChanged(pappso::DataPointCstSPtr peak_match) const
void setMs1Precision(PrecisionPtr precision)
void setMassSpectrumCstSPtr(const MassSpectrumCstSPtr &spectrum)
void setIonList(const std::list< PeptideIon > &ion_list)
void setMs2Precision(PrecisionPtr precision)
std::list< PeakIonIsotopeMatch > _peak_ion_isotope_match_list
void setPeptideCharge(unsigned int parent_ion_charge)
void setMaximumIsotopeRank(unsigned int max_isotope_rank)
MassSpectrumCstSPtr _spectrum_sp
void mzChanged(double mz) const
void setMsLevel(unsigned int ms_level)
MassSpectrumWidget(QWidget *parent=0)
void setPeptideSp(const PeptideSp &peptide_sp)
void mzChangeEvent(pappso_double mz) const
void ionChanged(pappso::PeakIonIsotopeMatchCstSPtr ion) const
void setVisibleMassDelta(bool visible)
void peakChangeEvent(const DataPoint *p_peak_match)
void setMaximumIsotopeNumber(unsigned int max_isotope_number)
std::list< PeptideIon > _ion_list
bool contains(pappso_double) const
Definition: mzrange.cpp:120
static std::list< PeptideIon > getCIDionList()
static const QColor getPeptideIonColor(PeptideIon ion_type)
const std::list< PeakIonIsotopeMatch > & getPeakIonIsotopeMatchList() const
PeptideNaturalIsotopeAverageSp makePeptideNaturalIsotopeAverageSp() const
const std::map< unsigned int, pappso_double > getIntensityRatioPerIsotopeNumber() const
virtual QString toString() const =0
void addPeakIonIsotopeMatch(const PeakIonIsotopeMatch &peak_ion_match)
void addMassDelta(const PeakIonIsotopeMatch &peak_ion_match)
void setSpectrumP(const MassSpectrum *spectrum)
void addMs1IsotopePattern(const std::vector< pappso::PeptideNaturalIsotopeAverageSp > &isotope_mass_list, pappso_double intensity)
Class representing a fully specified mass spectrum.
uint getMsLevel() const
Get the mass spectrum level.
MassSpectrumCstSPtr getMassSpectrumCstSPtr() const
Get the MassSpectrumCstSPtr.
uint getPrecursorCharge(bool *ok=nullptr) const
Get the precursor charge.
plot a sectrum and annotate with peptide
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...
Definition: aa.cpp:39
std::shared_ptr< const Peptide > PeptideSp
double pappso_double
A type definition for doubles.
Definition: types.h:49
std::shared_ptr< const PeptideNaturalIsotopeAverage > PeptideNaturalIsotopeAverageSp
std::shared_ptr< const MassSpectrum > MassSpectrumCstSPtr
Definition: massspectrum.h:55
std::shared_ptr< const DataPoint > DataPointCstSPtr
Definition: datapoint.h:17
pappso_double x
Definition: datapoint.h:23
pappso_double y
Definition: datapoint.h:24
DataPointCstSPtr makeDataPointCstSPtr() const
Definition: datapoint.cpp:70