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
38using namespace pappso;
39
40MassSpectrumWidget::MassSpectrumWidget(QWidget *parent)
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);
53 qDebug();
54}
56{
57}
58
59bool
60MassSpectrumWidget::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
74void
75MassSpectrumWidget::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}
86void
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}
118void
120{
121 qDebug();
123 qDebug();
124 _custom_plot->clearItems();
126 qDebug();
127}
128
129void
130MassSpectrumWidget::setPeptideCharge(unsigned int parent_ion_charge)
131{
132 _peptide_charge = parent_ion_charge;
133}
134void
135MassSpectrumWidget::setIonList(const std::list<PeptideIon> &ion_list)
136{
137 _ion_list = ion_list;
138}
139
140void
141MassSpectrumWidget::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 {
154 }
155
156 //_precision._precision = precision._precision;
157}
158void
160{
161 qDebug() << "precision->toString()=" << precision->toString();
162 _p_ms1_precision = precision;
163 //_precision._precision = precision._precision;
164}
165void
167{
168 qDebug() << "precision->toString()=" << precision->toString();
169 _p_ms2_precision = precision;
170 //_precision._precision = precision._precision;
171}
172
173void
174MassSpectrumWidget::setMaximumIsotopeNumber(unsigned int max_isotope_number)
175{
176 _max_isotope_number = max_isotope_number;
177}
178
179void
180MassSpectrumWidget::setMaximumIsotopeRank(unsigned int max_isotope_rank)
181{
182 _max_isotope_rank = max_isotope_rank;
183}
184void
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 qDebug();
198 PeptideIsotopeSpectrumMatch psm_match(*(_spectrum_sp.get()),
202 _ion_list,
205
207 qDebug() << "_peak_ion_isotope_match_list.size()="
209 }
210 else
211 {
212 }
214 }
215 qDebug();
216}
217
218void
220{
221 qDebug();
222 _peptide_sp = peptide_sp;
223
224 // clearData();
225 qDebug();
226}
227
228void
230{
231 qDebug();
232 _spectrum_sp = spectrum;
233
234 clearData();
235 qDebug();
236}
237
238void
240{
241 qDebug();
242
244
245 /*
246 if (_p_delta_axis_rect != nullptr) {
247 _p_delta_axis_rect->axis(QCPAxis::AxisType::atLeft)->rescale();
248 }
249 */
250 _custom_plot->replot();
251 qDebug();
252}
253
254void
256 const QualifiedMassSpectrum &spectrum)
257{
258 qDebug() << "spectrum.getPrecursorCharge()=" << spectrum.getPrecursorCharge();
259
260 setMsLevel(spectrum.getMsLevel());
262
263 qDebug();
264}
265
266void
268{
269
270 qDebug() << "_ms_level=" << _ms_level;
272 if(_ms_level == 1)
273 {
274 qDebug();
275 if(_spectrum_sp != nullptr)
276 {
277 qDebug();
278 if(_isotope_mass_list.size() > 0)
279 {
280
281 qDebug() << "_isotope_mass_list.size()="
282 << _isotope_mass_list.size();
283 std::sort(_isotope_mass_list.begin(),
284 _isotope_mass_list.end(),
287 return a.get()->getMz() < b.get()->getMz();
288 });
289
290 if(_isotope_mass_list.size() > 0)
291 {
292 PeptideNaturalIsotopeAverageSp precursor_peptide =
293 _isotope_mass_list.at(0);
294 qDebug() << "precursor_peptide.get()->getMz()="
295 << precursor_peptide.get()->getMz();
296 MzRange precursor_mass(precursor_peptide.get()->getMz(),
298 DataPoint monoisotope_peak;
299 monoisotope_peak.y = 0;
300
301 for(const DataPoint &peak : *(_spectrum_sp.get()))
302 {
303 if(precursor_mass.contains(peak.x))
304 {
305 if(peak.y > monoisotope_peak.y)
306 {
307 qDebug() << "SpectrumWidget::plot "
308 "(peak.intensity > "
309 "monoisotope_peak.intensity) ";
310 monoisotope_peak = peak;
311 }
312 }
313 }
314 if(monoisotope_peak.y > 0)
315 {
316 qDebug() << "addMs1IsotopePattern";
318 monoisotope_peak.y);
319 }
320 }
321 }
322 }
323 }
324 else
325 {
326 qDebug() << "_peak_ion_isotope_match_list.size()="
329 [](const PeakIonIsotopeMatch &a, const PeakIonIsotopeMatch &b) {
330 return a.getPeak().y > b.getPeak().y;
331 });
332 unsigned int i = 0;
333 for(const PeakIonIsotopeMatch &peak_ion_match :
335 {
336 _custom_plot->addPeakIonIsotopeMatch(peak_ion_match);
337
338 _custom_plot->addMassDelta(peak_ion_match);
339 //_p_delta_graph->addData(peak_ion_match.getPeak().x,
340 // peak_ion_match.getPeak().y);
341 if(i < _tag_nmost_intense)
342 {
343 QCPItemText *text_label = new QCPItemText(_custom_plot);
344 text_label->setVisible(true);
345 //_custom_plot->addItem(text_label);
346 text_label->setPositionAlignment(Qt::AlignBottom |
347 Qt::AlignHCenter);
348 text_label->position->setType(QCPItemPosition::ptPlotCoords);
349 text_label->position->setCoords(
350 peak_ion_match.getPeak().x,
351 peak_ion_match.getPeak()
352 .y); // place position at center/top of axis rect
353 text_label->setFont(QFont(font().family(), 8));
354 text_label->setText(
355 peak_ion_match.getPeptideFragmentIonSp()
356 .get()
357 ->getCompletePeptideIonName(peak_ion_match.getCharge()));
358 // text_label->setPen(QPen(PeptideFragmentIon::getPeptideIonColor(peak_ion_match.getPeptideIonType()),
359 // 1)); // show black border around text
360 text_label->setColor(
362 peak_ion_match.getPeptideIonType())));
363 }
364 i++;
365 }
366 }
367
368 _custom_plot->replot();
369 qDebug();
370}
371void
373{
374 emit mzChanged(mz);
375}
376
377void
379{
380 qDebug() << "p_peak_match=" << p_peak_match;
381 if(_p_mouse_peak != p_peak_match)
382 {
383 _p_mouse_peak = p_peak_match;
384 DataPointCstSPtr peak_shp;
385 // emit peakChanged(peak_shp);
386 if(_p_mouse_peak != nullptr)
387 {
388 qDebug() << "_p_mouse_peak->x=" << _p_mouse_peak->x;
390 emit peakChanged(peak_shp);
391 // try to find matched ion (if it exists)
392 bool found = false;
393 for(const PeakIonIsotopeMatch &peak_ion_match :
395 {
396 if(peak_ion_match.getPeak().x == _p_mouse_peak->x)
397 {
398 // found
399 emit ionChanged(std::make_shared<const PeakIonIsotopeMatch>(
400 PeakIonIsotopeMatch(peak_ion_match)));
401 found = true;
402 }
403 }
404 if(!found)
405 {
406 emit ionChanged(std::shared_ptr<const PeakIonIsotopeMatch>());
407 }
408 }
409 else
410 {
411 qDebug() << "no peak";
412 emit peakChanged(peak_shp);
413 }
414 }
415}
416
417void
419{
420 qDebug() << "_p_ms1_precision->toString()=" << _p_ms1_precision->toString();
421 _isotope_mass_list.resize(0);
422 // compute isotope masses :
423 if(_peptide_sp != nullptr)
424 {
426 std::map<unsigned int, pappso::pappso_double> map_isotope_number =
428
429 for(unsigned int i = 0; i < map_isotope_number.size(); i++)
430 {
431
432 unsigned int asked_rank = 0;
433 unsigned int given_rank = 0;
434 bool more_rank = true;
435 while(more_rank)
436 {
437 asked_rank++;
438 pappso::PeptideNaturalIsotopeAverage isotopeAverageMono(
439 isotope_list, asked_rank, i, _peptide_charge, _p_ms1_precision);
440 given_rank = isotopeAverageMono.getIsotopeRank();
441 if(given_rank < asked_rank)
442 {
443 more_rank = false;
444 }
445 else if(isotopeAverageMono.getIntensityRatio() == 0)
446 {
447 more_rank = false;
448 }
449 else
450 {
451 // isotopeAverageMono.makePeptideNaturalIsotopeAverageSp();
452 _isotope_mass_list.push_back(
453 isotopeAverageMono.makePeptideNaturalIsotopeAverageSp());
454 }
455 }
456 }
457 }
458 qDebug() << "_isotope_mass_list.size()=" << _isotope_mass_list.size();
459}
460
461void
463{
464
465 if(_ms_level > 1)
466 {
467 pappso_double precursor_mz_1 = _peptide_sp->getMz(1);
468 _custom_plot->highlightPrecursorPeaks(
469 precursor_mz_1, 1, _p_ms2_precision);
470 pappso_double precursor_mz_charge = _peptide_sp->getMz(_peptide_charge);
471 _custom_plot->highlightPrecursorPeaks(
472 precursor_mz_charge, _peptide_charge, _p_ms2_precision);
473 }
474}
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)
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.
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:18
pappso_double x
Definition: datapoint.h:23
pappso_double y
Definition: datapoint.h:24
DataPointCstSPtr makeDataPointCstSPtr() const
Definition: datapoint.cpp:73