libpappsomspp
Library for mass spectrometry
Loading...
Searching...
No Matches
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"
35#include <QDebug>
36#include <QWidget>
37
38
39using namespace pappso;
40
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}
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();
122 _custom_plot->clearData();
123 qDebug();
124 _custom_plot->clearItems();
125 _custom_plot->setSpectrumP(_spectrum_sp.get());
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<Enums::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()=" << _peak_ion_isotope_match_list.size();
208 }
209 else
210 {
211 }
213 }
214 qDebug();
215}
216
217void
219{
220 qDebug();
221 _peptide_sp = peptide_sp;
222
223 // clearData();
224 qDebug();
225}
226
227void
229{
230 qDebug();
231 _spectrum_sp = spectrum;
232
233 clearData();
234 qDebug();
235}
236
237void
239{
240 qDebug();
241
242 _custom_plot->rescale();
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
253void
255{
256 qDebug() << "spectrum.getPrecursorCharge()=" << spectrum.getPrecursorCharge();
257
258 setMsLevel(spectrum.getMsLevel());
260
261 qDebug();
262}
263
264void
266{
267
268 qDebug() << "_ms_level=" << _ms_level;
270 if(_ms_level == 1)
271 {
272 qDebug();
273 if(_spectrum_sp != nullptr)
274 {
275 qDebug();
276 if(_isotope_mass_list.size() > 0)
277 {
278
279 qDebug() << "_isotope_mass_list.size()=" << _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 = _isotope_mass_list.at(0);
290 qDebug() << "precursor_peptide.get()->getMz()="
291 << precursor_peptide.get()->getMz();
292 MzRange precursor_mass(precursor_peptide.get()->getMz(), _p_ms1_precision);
293 DataPoint monoisotope_peak;
294 monoisotope_peak.y = 0;
295
296 for(const DataPoint &peak : *(_spectrum_sp.get()))
297 {
298 if(precursor_mass.contains(peak.x))
299 {
300 if(peak.y > monoisotope_peak.y)
301 {
302 qDebug() << "SpectrumWidget::plot "
303 "(peak.intensity > "
304 "monoisotope_peak.intensity) ";
305 monoisotope_peak = peak;
306 }
307 }
308 }
309 if(monoisotope_peak.y > 0)
310 {
311 qDebug() << "addMs1IsotopePattern";
312 _custom_plot->addMs1IsotopePattern(_isotope_mass_list, monoisotope_peak.y);
313 }
314 }
315 }
316 }
317 }
318 else
319 {
320 qDebug() << "_peak_ion_isotope_match_list.size()=" << _peak_ion_isotope_match_list.size();
322 [](const PeakIonIsotopeMatch &a, const PeakIonIsotopeMatch &b) {
323 return a.getPeak().y > b.getPeak().y;
324 });
325 unsigned int i = 0;
326 for(const PeakIonIsotopeMatch &peak_ion_match : _peak_ion_isotope_match_list)
327 {
328 _custom_plot->addPeakIonIsotopeMatch(peak_ion_match);
329
330 _custom_plot->addMassDelta(peak_ion_match);
331 //_p_delta_graph->addData(peak_ion_match.getPeak().x,
332 // peak_ion_match.getPeak().y);
333 if(i < _tag_nmost_intense)
334 {
335 QCPItemText *text_label = new QCPItemText(_custom_plot);
336 text_label->setVisible(true);
337 //_custom_plot->addItem(text_label);
338 text_label->setPositionAlignment(Qt::AlignBottom | Qt::AlignHCenter);
339 text_label->position->setType(QCPItemPosition::ptPlotCoords);
340 text_label->position->setCoords(
341 peak_ion_match.getPeak().x,
342 peak_ion_match.getPeak().y); // place position at center/top of axis rect
343 text_label->setFont(QFont(font().family(), 8));
344 text_label->setText(
345 peak_ion_match.getPeptideFragmentIonSp().get()->getCompletePeptideIonName(
346 peak_ion_match.getCharge()));
347 // text_label->setPen(QPen(PeptideFragmentIon::getPeptideIonColor(peak_ion_match.getPeptideIonType()),
348 // 1)); // show black border around text
349 text_label->setColor(
350 QColor(PeptideFragmentIon::getPeptideIonColor(peak_ion_match.getPeptideIonType())));
351 }
352 i++;
353 }
354 }
355
356 _custom_plot->replot();
357 qDebug();
358}
359void
364
365void
367{
368 qDebug() << "p_peak_match=" << p_peak_match;
369 if(_p_mouse_peak != p_peak_match)
370 {
371 _p_mouse_peak = p_peak_match;
372 DataPointCstSPtr peak_shp;
373 // emit peakChanged(peak_shp);
374 if(_p_mouse_peak != nullptr)
375 {
376 qDebug() << "_p_mouse_peak->x=" << _p_mouse_peak->x;
377 peak_shp = _p_mouse_peak->makeDataPointCstSPtr();
378 emit peakChanged(peak_shp);
379 // try to find matched ion (if it exists)
380 bool found = false;
381 for(const PeakIonIsotopeMatch &peak_ion_match : _peak_ion_isotope_match_list)
382 {
383 if(peak_ion_match.getPeak().x == _p_mouse_peak->x)
384 {
385 // found
386 emit ionChanged(std::make_shared<const PeakIonIsotopeMatch>(
387 PeakIonIsotopeMatch(peak_ion_match)));
388 found = true;
389 }
390 }
391 if(!found)
392 {
393 emit ionChanged(std::shared_ptr<const PeakIonIsotopeMatch>());
394 }
395 }
396 else
397 {
398 qDebug() << "no peak";
399 emit peakChanged(peak_shp);
400 }
401 }
402}
403
404void
406{
407 qDebug() << "_p_ms1_precision->toString()=" << _p_ms1_precision->toString();
408 _isotope_mass_list.resize(0);
409 // compute isotope masses :
410 if(_peptide_sp != nullptr)
411 {
413 std::map<unsigned int, pappso::pappso_double> map_isotope_number =
415
416 for(unsigned int i = 0; i < map_isotope_number.size(); i++)
417 {
418
419 unsigned int asked_rank = 0;
420 unsigned int given_rank = 0;
421 bool more_rank = true;
422 while(more_rank)
423 {
424 asked_rank++;
425 pappso::PeptideNaturalIsotopeAverage isotopeAverageMono(
426 isotope_list, asked_rank, i, _peptide_charge, _p_ms1_precision);
427 given_rank = isotopeAverageMono.getIsotopeRank();
428 if(given_rank < asked_rank)
429 {
430 more_rank = false;
431 }
432 else if(isotopeAverageMono.getIntensityRatio() == 0)
433 {
434 more_rank = false;
435 }
436 else
437 {
438 // isotopeAverageMono.makePeptideNaturalIsotopeAverageSp();
439 _isotope_mass_list.push_back(
440 isotopeAverageMono.makePeptideNaturalIsotopeAverageSp());
441 }
442 }
443 }
444 }
445 qDebug() << "_isotope_mass_list.size()=" << _isotope_mass_list.size();
446}
447
448void
450{
451
452 if(_ms_level > 1)
453 {
454 pappso_double precursor_mz_1 = _peptide_sp->getMz(1);
455 _custom_plot->highlightPrecursorPeaks(precursor_mz_1, 1, _p_ms2_precision);
456 pappso_double precursor_mz_charge = _peptide_sp->getMz(_peptide_charge);
457 _custom_plot->highlightPrecursorPeaks(precursor_mz_charge, _peptide_charge, _p_ms2_precision);
458 }
459}
460
461
462QJsonObject
464{
465 QJsonObject psm_json;
466
467 try
468 {
469
470 if(_peptide_sp.get() != nullptr)
471 {
472 psm_json.insert("proforma", _peptide_sp.get()->toProForma());
473 }
474
475 if(_spectrum_sp.get() != nullptr)
476 {
477 struct data_plot
478 {
479 pappso::DataPoint point;
480 double mz_th;
481 int charge;
482 int size;
483 int isotope_number;
484 int isotope_rank;
485 };
486
487 std::map<pappso::Enums::PeptideIon, std::vector<data_plot>> ion_map;
488
489 QJsonObject spectrum_json;
490 spectrum_json.insert("mz", pappso::Utils::toJson(_spectrum_sp.get()->xValues()));
491 spectrum_json.insert("intensity", pappso::Utils::toJson(_spectrum_sp.get()->yValues()));
492
493
495 {
496 data_plot one_ion_match;
497 one_ion_match.charge = (int)peakion_match.getCharge();
498 one_ion_match.isotope_number =
499 (int)peakion_match.getPeptideNaturalIsotopeAverageSp().get()->getIsotopeNumber();
500 one_ion_match.isotope_rank =
501 (int)peakion_match.getPeptideNaturalIsotopeAverageSp().get()->getIsotopeRank();
502 one_ion_match.mz_th =
503 peakion_match.getPeptideNaturalIsotopeAverageSp().get()->getMz();
504 one_ion_match.point = peakion_match.getPeak();
505 one_ion_match.size = (int)peakion_match.getPeptideFragmentIonSp().get()->size();
506
507 auto it = ion_map.insert({peakion_match.getPeptideIonType(), {}});
508 it.first->second.push_back(one_ion_match);
509 }
510
511 QJsonObject psm_ion_json;
512 for(auto &cle_valeur : ion_map)
513 {
514 std::vector<data_plot> &current_vector = cle_valeur.second;
515
516 std::sort(
517 current_vector.begin(),
518 current_vector.end(),
519 [](const data_plot &a, const data_plot &b) { return a.point.x < b.point.x; });
520 QJsonArray current_ion_json_arr;
521
522 for(const data_plot &one_point : current_vector)
523 {
524 QJsonObject current_ion;
525 current_ion.insert("mz", one_point.point.x);
526 current_ion.insert("mzth", one_point.mz_th);
527 current_ion.insert("intensity", one_point.point.y);
528 current_ion.insert("size", one_point.size);
529 current_ion.insert("charge", one_point.charge);
530 current_ion.insert("isotope", one_point.isotope_number);
531 current_ion.insert("rank", one_point.isotope_rank);
532
533 current_ion_json_arr.push_back(current_ion);
534 }
535
536
537 psm_ion_json.insert(pappso::Utils::toString(cle_valeur.first), current_ion_json_arr);
538 }
539
540 psm_json.insert("ion-series", psm_ion_json);
541 psm_json.insert("spectra", spectrum_json);
542 }
543 }
544 catch(const pappso::PappsoException &error)
545 {
547 QObject::tr("Unable to build JSON PSM object:\n%1").arg(error.qwhat()));
548 }
549 return psm_json;
550}
GraphicDeviceWidget(QWidget *parent)
void toQPaintDevice(QPaintDevice *device, const QSize &size) override
void setIonList(const std::list< Enums::PeptideIon > &ion_list)
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 setMs2Precision(PrecisionPtr precision)
std::list< PeakIonIsotopeMatch > _peak_ion_isotope_match_list
QJsonObject getJsonPsmIsotope() const
void setPeptideCharge(unsigned int parent_ion_charge)
void setMaximumIsotopeRank(unsigned int max_isotope_rank)
MassSpectrumCstSPtr _spectrum_sp
std::list< Enums::PeptideIon > _ion_list
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)
bool contains(pappso_double) const
Definition mzrange.cpp:115
virtual const QString & qwhat() const
static std::list< Enums::PeptideIon > getCIDionList()
static const QColor getPeptideIonColor(Enums::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
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 precursor charge
static QString toString(specglob::SpectralAlignmentType type)
Convenience function to return a string describing the specglob alingment type.
Definition utils.cpp:544
static QJsonArray toJson(const std::vector< double > &myVec)
convert vector of double into json array
Definition utils.cpp:774
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:60
std::shared_ptr< const PeptideNaturalIsotopeAverage > PeptideNaturalIsotopeAverageSp
std::shared_ptr< const MassSpectrum > MassSpectrumCstSPtr
const PrecisionBase * PrecisionPtr
Definition precision.h:122
std::shared_ptr< const DataPoint > DataPointCstSPtr
Definition datapoint.h:18
pappso_double y
Definition datapoint.h:25