libpappsomspp
Library for mass spectrometry
qcpspectrum.cpp
Go to the documentation of this file.
1 /**
2  * \file pappsomspp/widget/spectrumwidget/qcpspectrum.cpp
3  * \date 31/12/2017
4  * \author Olivier Langella
5  * \brief Custom plot derivative to plot a spectrum
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 
32 #include "qcpspectrum.h"
33 #include "massspectrumwidget.h"
34 
35 using namespace pappso;
36 
38  : QCustomPlot(parent)
39 {
40  qDebug() << "QCPSpectrum::QCPSpectrum begin";
41 
42  setFocusPolicy(Qt::ClickFocus);
43  _parent = parent;
44  _mz_range.lower = 0;
45  _mz_range.upper = 0;
46  _intensity_range.lower = 0;
47  _intensity_range.upper = 0;
48  _mass_delta_range.upper = -100;
49  _mass_delta_range.lower = 100;
50 
51 
52  // make axis rects' left side line up:
53  QCPMarginGroup *group = new QCPMarginGroup(this);
54  this->axisRect()->setMarginGroup(QCP::msLeft | QCP::msRight, group);
55 
56 
57  _p_peak_bars = new QCPBars(xAxis, yAxis);
58  _p_peak_bars->setWidthType(QCPBars::WidthType::wtAbsolute);
59  _p_peak_bars->setWidth(_bar_width);
60  _p_peak_bars->setPen(QPen(Qt::black, 1));
61  _p_peak_bars->setVisible(true);
62 
63  _p_peak_bars_isotope = new QCPBars(xAxis, yAxis);
64  _p_peak_bars_isotope->setWidthType(QCPBars::WidthType::wtAbsolute);
65  _p_peak_bars_isotope->setWidth(_bar_width * 10);
66  QColor red(Qt::red);
67  red.setAlpha(100);
68  _p_peak_bars_isotope->setPen(QPen(red, 1));
69  _p_peak_bars_isotope->setBrush(QBrush(red));
70 
71  connect(this->xAxis,
72  SIGNAL(rangeChanged(QCPRange)),
73  this,
74  SLOT(setMzRangeChanged(QCPRange)));
75 
76 
77  std::vector<PeptideIon> all_ion_list = {
78  PeptideIon::b,
79  PeptideIon::bstar,
80  PeptideIon::bo,
81  PeptideIon::a,
82  PeptideIon::astar,
83  PeptideIon::ao,
84  PeptideIon::bp,
85  PeptideIon::c,
86  PeptideIon::y, ///< Cter amino ions
87  PeptideIon::ystar, ///< Cter amino ions + NH3 loss
88  PeptideIon::yo, ///< Cter amino ions + H2O loss
89  PeptideIon::z, ///< Cter carbocations
90  PeptideIon::yp,
92  qDebug() << "SpectrumWidget::setVisibleMassDelta 5";
93 
94  for(PeptideIon ion_type : all_ion_list)
95  {
96  QCPBars *p_peak_bars = new QCPBars(xAxis, yAxis);
97  p_peak_bars->setWidthType(QCPBars::WidthType::wtAbsolute);
98  p_peak_bars->setWidth(_bar_width);
99  p_peak_bars->setPen(
100  QPen(PeptideFragmentIon::getPeptideIonColor(ion_type), 1));
101 
102  p_peak_bars->setVisible(true);
103  _map_ion_type_bars.insert(
104  std::pair<PeptideIon, QCPBars *>(ion_type, p_peak_bars));
105  }
106  qDebug() << "SpectrumWidget::setVisibleMassDelta visible ?";
107  setInteractions(QCP::iRangeDrag | QCP::iRangeZoom);
108  if(visible)
109  {
110 
111  _p_delta_axis_rect = new QCPAxisRect(this);
112  this->plotLayout()->addElement(1, 0, _p_delta_axis_rect);
113  _p_delta_axis_rect->axis(QCPAxis::atBottom)->setLayer("axes");
114  _p_delta_axis_rect->axis(QCPAxis::atBottom)->grid()->setLayer("grid");
115  _p_delta_axis_rect->axis(QCPAxis::atLeft)->setLabel("mass delta");
116  // bring bottom and main axis rect closer together:
117  this->plotLayout()->setRowSpacing(0);
118  _p_delta_axis_rect->setAutoMargins(QCP::msLeft | QCP::msRight |
119  QCP::msBottom);
120  _p_delta_axis_rect->setMargins(QMargins(0, 0, 0, 0));
121  this->setAutoAddPlottableToLegend(false);
122  _p_delta_graph = new QCPGraph(_p_delta_axis_rect->axis(QCPAxis::atBottom),
123  _p_delta_axis_rect->axis(QCPAxis::atLeft));
124  _p_delta_graph->setLineStyle(QCPGraph::LineStyle::lsNone);
125  _p_delta_graph->setScatterStyle(
126  QCPScatterStyle(QCPScatterStyle::ssDisc, 4.0));
127 
128  _p_delta_axis_rect->setMarginGroup(QCP::msLeft | QCP::msRight, group);
129  _p_delta_axis_rect->setMaximumSize(QSize(QWIDGETSIZE_MAX, 100));
130 
131 
132  //_p_delta_axis_rect->setInteractions(QCP::iRangeDrag | QCP::iRangeZoom );
133  _p_delta_axis_rect->setRangeDrag(Qt::Horizontal | Qt::Vertical);
134  _p_delta_axis_rect->setRangeZoom(Qt::Vertical);
135 
136 
137  connect(_p_delta_axis_rect->axis(QCPAxis::atBottom),
138  SIGNAL(rangeChanged(QCPRange)),
139  this,
140  SLOT(setMzRangeChanged(QCPRange)));
141  }
142  else
143  {
144  _p_delta_axis_rect = nullptr;
145  }
146  qDebug() << "QCPSpectrum::QCPSpectrum end";
147 }
149 {
150 }
151 
152 void
154 {
155  _mass_delta_range.upper = -100;
156  _mass_delta_range.lower = 100;
157  // generate basic peaks:
158  _p_spectrum = spectrum;
159  if((spectrum != nullptr) && (spectrum->size() != 0))
160  {
161  // throw PappsoException(QObject::tr("Error in
162  // SpectrumWidget::setSpectrumSp :\n_spectrum_sp.get() == nullptr"));
163  //}
164  _p_peak_bars->setVisible(true);
165  for(const DataPoint &peak : *spectrum)
166  {
167  _p_peak_bars->addData(peak.x, peak.y);
168  }
169  _mz_range.lower = spectrum->front().x - 1;
170  _mz_range.upper = spectrum->back().x + 1;
171  _intensity_range.lower = 0;
172  _intensity_range.upper = spectrum->maxY();
173  }
174  else
175  {
176  _mz_range.lower = 0;
177  _mz_range.upper = 0;
178  _intensity_range.lower = 0;
179  _intensity_range.upper = 0;
180  }
181 }
182 
183 void
185 {
186  _p_peak_bars->setVisible(true);
187 
188  //_p_peak_bars->rescaleAxes(false);
189  // this->rescaleAxes(false);
190 
191 
192  if(_mz_range.lower < 0)
193  {
194  _mz_range.lower = 0;
195  }
196  if(_mz_range.upper < 0)
197  {
198  _mz_range.upper = 1000;
199  }
200  else
201  {
202  xAxis->setRange(_mz_range);
203  yAxis->setRange(_intensity_range);
204  if(_p_delta_axis_rect != nullptr)
205  {
206  _p_delta_axis_rect->axis(QCPAxis::AxisType::atLeft)
207  ->setRange(_mass_delta_range);
208  }
209  }
210 }
211 
212 void
214 {
215  qDebug() << "QCPSpectrum::setMzRangeChanged _mz_range.lower"
216  << _mz_range.lower;
217  if(_mz_range.lower > 0)
218  {
219  if(range.lower < _mz_range.lower)
220  {
221  range.lower = _mz_range.lower;
222  }
223  if(range.upper > _mz_range.upper)
224  {
225  range.upper = _mz_range.upper;
226  }
227  }
228 
229  xAxis->setRange(range);
230 
231  if(_p_delta_axis_rect != nullptr)
232  {
233  _p_delta_axis_rect->axis(QCPAxis::atBottom)->setRange(range);
234  }
235 }
236 
237 void
239 {
240  qDebug();
241  _p_peak_bars->setData(QVector<double>(), QVector<double>());
242  _p_peak_bars->data().clear();
243  qDebug();
244  _p_peak_bars_isotope->setData(QVector<double>(), QVector<double>());
245  _p_peak_bars_isotope->data().clear();
246  qDebug();
247  for(std::pair<PeptideIon, QCPBars *> pair_ion_bar : _map_ion_type_bars)
248  {
249  pair_ion_bar.second->setData(QVector<double>(), QVector<double>());
250  pair_ion_bar.second->data().clear();
251  }
252  // this->clearPlottables();
253  // this->clearItems();
254  if(_p_delta_axis_rect != nullptr)
255  {
256  _p_delta_graph->setData(QVector<double>(), QVector<double>());
257  _p_delta_graph->data().clear();
258  }
259 
260  _mz_range.lower = 0;
261  _mz_range.upper = 0;
262 
263  _mass_delta_range.upper = -100;
264  _mass_delta_range.lower = 100;
265  qDebug();
266 }
267 
268 void
269 QCPSpectrum::keyPressEvent(QKeyEvent *event)
270 {
271  if(event->key() == Qt::Key_Control)
272  {
273  _control_key = true;
274  }
275  qDebug() << "QCPSpectrum::keyPressEvent end";
276 }
277 
278 void
280 {
281  if(event->key() == Qt::Key_Control)
282  {
283  _control_key = false;
284  }
285  qDebug() << "QCPSpectrum::keyReleaseEvent end";
286 }
287 
288 void
289 QCPSpectrum::mousePressEvent(QMouseEvent *event)
290 {
291  /*qDebug() << "QCPSpectrum::mousePressEvent begin "
292  << xAxis->pixelToCoord(event->x()) << " "
293  << yAxis->pixelToCoord(event->y());*/
294  _click = true;
295  _old_x = event->x();
296  _old_y = yAxis->pixelToCoord(event->y());
297  if(_old_y < 0)
298  _old_y = 0;
299  /* qDebug() << "QCPSpectrum::mousePressEvent end";*/
300 }
301 void
302 QCPSpectrum::mouseReleaseEvent(QMouseEvent *event [[maybe_unused]])
303 {
304  /*qDebug() << "QCPSpectrum::mouseReleaseEvent begin "
305  << xAxis->pixelToCoord(event->x()) << " "
306  << yAxis->pixelToCoord(event->y());*/
307  _click = false;
308  // qDebug() << "QCPSpectrum::mouseReleaseEvent end";
309 }
310 void
311 QCPSpectrum::mouseMoveEvent(QMouseEvent *event)
312 {
313  pappso::pappso_double x = xAxis->pixelToCoord(event->x());
314  if(_click)
315  {
316  /* qDebug() << "QCPSpectrum::mouseMoveEvent begin "
317  << xAxis->pixelToCoord(event->x()) << " "
318  << yAxis->pixelToCoord(event->y());*/
319  pappso::pappso_double y = yAxis->pixelToCoord(event->y());
320  if(y < 0)
321  {
322  y = 0;
323  }
324  if(_control_key)
325  {
326  if(y > 0)
327  {
328  this->yAxis->scaleRange(_old_y / y, 0);
329  }
330  }
331  else
332  {
333  this->xAxis->moveRange(xAxis->pixelToCoord(_old_x) -
334  xAxis->pixelToCoord(event->x()));
335  }
336  _old_x = event->x();
337  _old_y = y;
338  replot();
339  // qDebug() << "QCPSpectrum::mouseMoveEvent end";
340  }
341  else
342  {
343  if(_p_spectrum != nullptr)
344  {
345  pappso::pappso_double mouse_mz_range =
346  xAxis->pixelToCoord(10) - xAxis->pixelToCoord(8);
347  getMostIntensePeakBetween(x, mouse_mz_range);
349  }
350  }
351 }
352 
353 void
355  pappso_double mouse_mz_range) const
356 {
357  /*qDebug() << "QCPSpectrum::getNearestPeakBetween begin " << mz << " "
358  << mouse_mz_range;*/
359  const DataPoint *p_peak_match;
360  p_peak_match = nullptr;
361  pappso_double min = mz - mouse_mz_range;
362  pappso_double max = mz + mouse_mz_range;
363 
364  for(const DataPoint &peak : *_p_spectrum)
365  {
366  if((peak.x > min) && (peak.x < max))
367  {
368  if(p_peak_match == nullptr)
369  {
370  p_peak_match = &peak;
371  }
372  else
373  {
374  if(fabs(mz - peak.x) < fabs(mz - p_peak_match->x))
375  {
376  p_peak_match = &peak;
377  }
378  }
379  }
380  }
381  _parent->peakChangeEvent(p_peak_match);
382  // qDebug() << "QCPSpectrum::getNearestPeakBetween end";
383 }
384 
385 
386 void
388  pappso_double mouse_mz_range) const
389 {
390  /*qDebug() << "QCPSpectrum::getNearestPeakBetween begin " << mz << " "
391  << mouse_mz_range;*/
392  const DataPoint *p_peak_match;
393  p_peak_match = nullptr;
394  pappso_double min = mz - mouse_mz_range;
395  pappso_double max = mz + mouse_mz_range;
396 
397  for(const DataPoint &peak : *_p_spectrum)
398  {
399  if((peak.x > min) && (peak.x < max))
400  {
401  if(p_peak_match == nullptr)
402  {
403  p_peak_match = &peak;
404  }
405  else
406  {
407  if(p_peak_match->y < peak.y)
408  {
409  p_peak_match = &peak;
410  }
411  }
412  }
413  }
414  _parent->peakChangeEvent(p_peak_match);
415  // qDebug() << "QCPSpectrum::getNearestPeakBetween end";
416 }
417 
418 void
420 {
421  if(_p_delta_axis_rect != nullptr)
422  {
423  // observed - theoretical
424  double diff =
425  peak_ion_match.getPeak().x -
426  peak_ion_match.getPeptideNaturalIsotopeAverageSp().get()->getMz();
427  _p_delta_graph->addData(peak_ion_match.getPeak().x, diff);
428 
429  if(diff > _mass_delta_range.upper)
430  _mass_delta_range.upper = diff;
431  if(diff < _mass_delta_range.lower)
432  _mass_delta_range.lower = diff;
433 
434  _p_delta_axis_rect->axis(QCPAxis::AxisType::atLeft)
435  ->setRange(_mass_delta_range);
436  }
437 }
438 
439 void
441 {
442  _map_ion_type_bars[peak_ion_match.getPeptideIonType()]->addData(
443  peak_ion_match.getPeak().x, peak_ion_match.getPeak().y);
444 }
445 
446 void
448  const std::vector<pappso::PeptideNaturalIsotopeAverageSp> &isotope_mass_list,
449  pappso_double intensity)
450 {
451  pappso_double total_intensity =
452  ((pappso_double)1.0 / isotope_mass_list.at(0).get()->getIntensityRatio()) *
453  intensity;
454  for(PeptideNaturalIsotopeAverageSp peptide : isotope_mass_list)
455  {
456  _p_peak_bars_isotope->addData(peptide.get()->getMz(),
457  peptide.get()->getIntensityRatio() *
458  total_intensity);
459  }
460 }
pappso::pappso_double
double pappso_double
A type definition for doubles.
Definition: types.h:48
pappso::QCPSpectrum::setSpectrumP
void setSpectrumP(const MassSpectrum *spectrum)
Definition: qcpspectrum.cpp:153
pappso::QCPSpectrum::mouseReleaseEvent
virtual void mouseReleaseEvent(QMouseEvent *event) override
Definition: qcpspectrum.cpp:302
massspectrumwidget.h
pappso::QCPSpectrum::_map_ion_type_bars
std::map< PeptideIon, QCPBars * > _map_ion_type_bars
Definition: qcpspectrum.h:86
pappso::QCPSpectrum::mousePressEvent
virtual void mousePressEvent(QMouseEvent *event) override
Definition: qcpspectrum.cpp:289
pappso::MassSpectrumWidget::mzChangeEvent
void mzChangeEvent(pappso_double mz) const
Definition: massspectrumwidget.cpp:371
pappso::DataPoint::y
pappso_double y
Definition: datapoint.h:23
pappso::QCPSpectrum::_old_x
pappso::pappso_double _old_x
Definition: qcpspectrum.h:92
pappso
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...
Definition: aa.cpp:39
pappso::MassSpectrum
Class to represent a mass spectrum.
Definition: massspectrum.h:71
pappso::QCPSpectrum::_control_key
bool _control_key
Definition: qcpspectrum.h:91
pappso::QCPSpectrum::clearData
void clearData()
Definition: qcpspectrum.cpp:238
pappso::QCPSpectrum::keyReleaseEvent
virtual void keyReleaseEvent(QKeyEvent *event) override
Definition: qcpspectrum.cpp:279
pappso::PeakIonMatch::getPeak
const DataPoint & getPeak() const
Definition: peakionmatch.h:55
pappso::PeptideIon::x
@ x
Cter acylium ions.
pappso::QCPSpectrum::QCPSpectrum
QCPSpectrum(MassSpectrumWidget *parent, bool visible)
Definition: qcpspectrum.cpp:37
pappso::DataPoint
Definition: datapoint.h:21
pappso::MassSpectrumWidget
Definition: massspectrumwidget.h:48
pappso::QCPSpectrum::_parent
MassSpectrumWidget * _parent
Definition: qcpspectrum.h:79
pappso::QCPSpectrum::keyPressEvent
virtual void keyPressEvent(QKeyEvent *event) override
Definition: qcpspectrum.cpp:269
pappso::QCPSpectrum::_p_delta_graph
QCPGraph * _p_delta_graph
Definition: qcpspectrum.h:88
pappso::PeptideIonCter::y
@ y
pappso::QCPSpectrum::getNearestPeakBetween
void getNearestPeakBetween(pappso_double mz, pappso_double mouse_mz_range) const
Definition: qcpspectrum.cpp:354
pappso::PeptideIon
PeptideIon
PeptideIon enum defines all types of ions (Nter or Cter)
Definition: types.h:351
pappso::QCPSpectrum::_click
bool _click
Definition: qcpspectrum.h:90
pappso::QCPSpectrum::_bar_width
double _bar_width
Definition: qcpspectrum.h:89
qcpspectrum.h
pappso::QCPSpectrum::_p_peak_bars
QCPBars * _p_peak_bars
Definition: qcpspectrum.h:84
pappso::QCPSpectrum::_intensity_range
QCPRange _intensity_range
Definition: qcpspectrum.h:82
pappso::QCPSpectrum::_p_delta_axis_rect
QCPAxisRect * _p_delta_axis_rect
Definition: qcpspectrum.h:87
pappso::QCPSpectrum::~QCPSpectrum
~QCPSpectrum()
Definition: qcpspectrum.cpp:148
pappso::QCPSpectrum::addMs1IsotopePattern
void addMs1IsotopePattern(const std::vector< pappso::PeptideNaturalIsotopeAverageSp > &isotope_mass_list, pappso_double intensity)
Definition: qcpspectrum.cpp:447
pappso::DataPoint::x
pappso_double x
Definition: datapoint.h:22
pappso::QCPSpectrum::_p_spectrum
const MassSpectrum * _p_spectrum
Definition: qcpspectrum.h:80
pappso::MassSpectrumWidget::peakChangeEvent
void peakChangeEvent(const DataPoint *p_peak_match)
Definition: massspectrumwidget.cpp:377
pappso::PeptideFragmentIon::getPeptideIonColor
static const QColor getPeptideIonColor(PeptideIon ion_type)
Definition: peptidefragmention.cpp:173
pappso::QCPSpectrum::addPeakIonIsotopeMatch
void addPeakIonIsotopeMatch(const PeakIonIsotopeMatch &peak_ion_match)
Definition: qcpspectrum.cpp:440
pappso::PeakIonMatch::getPeptideIonType
PeptideIon getPeptideIonType() const
Definition: peakionmatch.h:67
pappso::QCPSpectrum::getMostIntensePeakBetween
void getMostIntensePeakBetween(pappso_double mz, pappso_double mouse_mz_range) const
Definition: qcpspectrum.cpp:387
pappso::XicExtractMethod::sum
@ sum
sum of intensities
pappso::DataKind::unset
@ unset
not set
pappso::QCPSpectrum::setMzRangeChanged
Q_SLOT void setMzRangeChanged(QCPRange range)
Definition: qcpspectrum.cpp:213
pappso::PeakIonIsotopeMatch::getPeptideNaturalIsotopeAverageSp
virtual const PeptideNaturalIsotopeAverageSp & getPeptideNaturalIsotopeAverageSp() const
Definition: peakionisotopematch.cpp:49
pappso::QCPSpectrum::_mass_delta_range
QCPRange _mass_delta_range
Definition: qcpspectrum.h:83
pappso::QCPSpectrum::_p_peak_bars_isotope
QCPBars * _p_peak_bars_isotope
Definition: qcpspectrum.h:85
pappso::QCPSpectrum::addMassDelta
void addMassDelta(const PeakIonIsotopeMatch &peak_ion_match)
Definition: qcpspectrum.cpp:419
pappso::PeakIonIsotopeMatch
Definition: peakionisotopematch.h:37
pappso::PeptideIon::y
@ y
Cter amino ions.
pappso::QCPSpectrum::_old_y
pappso::pappso_double _old_y
Definition: qcpspectrum.h:93
pappso::QCPSpectrum::mouseMoveEvent
virtual void mouseMoveEvent(QMouseEvent *event) override
Definition: qcpspectrum.cpp:311
pappso::QCPSpectrum::rescale
void rescale()
Definition: qcpspectrum.cpp:184
pappso::QCPSpectrum::_mz_range
QCPRange _mz_range
Definition: qcpspectrum.h:81
pappso::PeptideNaturalIsotopeAverageSp
std::shared_ptr< const PeptideNaturalIsotopeAverage > PeptideNaturalIsotopeAverageSp
Definition: peptidenaturalisotopeaverage.h:37