libpappsomspp
Library for mass spectrometry
Loading...
Searching...
No Matches
psmfeatures.cpp
Go to the documentation of this file.
1/**
2 * \file pappsomspp/psm/features/psmfeatures.cpp
3 * \date 19/07/2022
4 * \author Olivier Langella
5 * \brief comutes various PSM (Peptide Spectrum Match) features
6 */
7
8/*******************************************************************************
9 * Copyright (c) 2022 Olivier Langella <Olivier.Langella@u-psud.fr>.
10 *
11 * This file is part of PAPPSOms-tools.
12 *
13 * PAPPSOms-tools is free software: you can redistribute it and/or modify
14 * it under the terms of the GNU General Public License as published by
15 * the Free Software Foundation, either version 3 of the License, or
16 * (at your option) any later version.
17 *
18 * PAPPSOms-tools is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
22 *
23 * You should have received a copy of the GNU General Public License
24 * along with PAPPSOms-tools. If not, see <http://www.gnu.org/licenses/>.
25 *
26 ******************************************************************************/
27
28
29#include "psmfeatures.h"
30#include <memory>
31#include <cmath>
32
33using namespace pappso;
34
35PsmFeatures::PsmFeatures(PrecisionPtr ms2precision, double minimumMz)
36{
37
38 m_ms2precision = ms2precision;
39
42
43
44 msp_filterKeepGreater = std::make_shared<FilterResampleKeepGreater>(minimumMz);
45
46 // msp_filterChargeDeconvolution =
47 // std::make_shared<FilterChargeDeconvolution>(m_ms2precision);
48 // msp_filterMzExclusion = std::make_shared<FilterMzExclusion>(
49 // PrecisionFactory::getPrecisionPtrFractionInstance(m_ms2precision, 0.5));
50}
51
55
56void
58 const MassSpectrum *p_spectrum,
59 unsigned int parent_charge,
60 unsigned int max_isotope_number)
61{
62 m_peakIonPairs.clear();
63 msp_peptide = peptideSp;
64 MassSpectrum spectrum(*p_spectrum);
65 msp_filterKeepGreater.get()->filter(spectrum);
66 // msp_filterChargeDeconvolution.get()->filter(spectrum);
67 // msp_filterMzExclusion.get()->filter(spectrum);
68
69 msp_peptideSpectrumMatch = std::make_shared<PeptideIsotopeSpectrumMatch>(
70 spectrum, peptideSp, parent_charge, m_ms2precision, m_ionList, max_isotope_number, 1);
71
72 msp_peptideSpectrumMatch.get()->dropPeaksLackingMonoisotope();
73 m_spectrumSumIntensity = spectrum.sumY();
74
75
76 qDebug() << " accumulate";
77 std::vector<double> delta_list;
78
79
80 // TODO compute number of matched complementary peaks having m/z compatible
81 // with the precursor
82
83 m_precursorTheoreticalMz = peptideSp.get()->getMz(parent_charge);
84 m_precursorTheoreticalMass = peptideSp.get()->getMass();
85 m_parentCharge = parent_charge;
86
87
88 findComplementIonPairs(peptideSp);
89
90
91 for(const pappso::PeakIonIsotopeMatch &peak_ion :
92 msp_peptideSpectrumMatch.get()->getPeakIonIsotopeMatchList())
93 {
94 delta_list.push_back(peak_ion.getPeptideFragmentIonSp().get()->getMz(peak_ion.getCharge()) -
95 peak_ion.getPeak().x);
96 }
97 pappso::pappso_double sum = std::accumulate(delta_list.begin(), delta_list.end(), 0);
98
99 qDebug() << " delta_list.size()=" << delta_list.size();
103 if(delta_list.size() > 0)
104 {
105 m_matchedMzDiffMean = sum / ((pappso::pappso_double)delta_list.size());
106
107 std::sort(delta_list.begin(), delta_list.end());
108 m_matchedMzDiffMedian = delta_list[(delta_list.size() / 2)];
109
110
111 qDebug() << " sd";
113 for(pappso::pappso_double val : delta_list)
114 {
115 // sd = sd + ((val - mean) * (val - mean));
116 m_matchedMzDiffSd += std::pow((val - m_matchedMzDiffMean), 2);
117 }
118 m_matchedMzDiffSd = m_matchedMzDiffSd / delta_list.size();
120 }
121 else
122 {
123 }
124}
125
126
127double
129{
130 double sum = 0;
131 for(const PeakIonMatch &peak_ion_match : *msp_peptideSpectrumMatch.get())
132 {
133 if(peak_ion_match.getPeptideIonType() == ion_type)
134 {
135 sum += peak_ion_match.getPeak().y;
136 }
137 }
138 return sum;
139}
140double
142{
143 double sum = 0;
144 for(const PeakIonMatch &peak_ion_match : *msp_peptideSpectrumMatch.get())
145 {
146 sum += peak_ion_match.getPeak().y;
147 }
148 return sum;
149}
150
151double
156
157std::size_t
162
163const std::vector<std::pair<pappso::PeakIonIsotopeMatch, pappso::PeakIonIsotopeMatch>> &
168
169double
171{
172
173 double sum = 0;
174 for(auto &peak_pairs : m_peakIonPairs)
175 {
176 sum += peak_pairs.first.getPeak().y;
177 sum += peak_pairs.second.getPeak().y;
178 }
179 return sum;
180}
181
182double
187
188double
193
194
195std::size_t
197{
198 return msp_peptideSpectrumMatch.get()->getPeakIonIsotopeMatchList().size();
199}
200
201std::size_t
203{
204 std::size_t max = 0;
205 auto peak_ion_match_list = msp_peptideSpectrumMatch.get()->getPeakIonIsotopeMatchList();
206
207 peak_ion_match_list.erase(
208 std::remove_if(peak_ion_match_list.begin(),
209 peak_ion_match_list.end(),
210 [ion_type](const PeakIonIsotopeMatch &a) {
211 if(a.getPeptideIonType() != ion_type)
212 return true;
213 if(a.getPeptideNaturalIsotopeAverageSp().get()->getIsotopeNumber() > 0)
214 return true;
215 return false;
216 }),
217 peak_ion_match_list.end());
218
219 peak_ion_match_list.sort([](const PeakIonIsotopeMatch &a, const PeakIonIsotopeMatch &b) {
220 if(a.getCharge() < b.getCharge())
221 return true;
222 if(a.getPeptideIonType() < b.getPeptideIonType())
223 return true;
224 if(a.getPeptideFragmentIonSp().get()->size() < b.getPeptideFragmentIonSp().get()->size())
225 return true;
226 return false;
227 });
228
229 unsigned int charge = 0;
230 std::size_t size = 0;
231 std::size_t count = 0;
232 for(std::list<PeakIonIsotopeMatch>::iterator it = peak_ion_match_list.begin();
233 it != peak_ion_match_list.end();
234 it++)
235 {
236 qDebug() << it->toString() << max << " " << it->getPeak().x << " "
237 << it->getPeptideNaturalIsotopeAverageSp().get()->getIsotopeNumber();
238 count++;
239 if((charge != it->getCharge()) || (size != (it->getPeptideFragmentIonSp().get()->size() - 1)))
240 {
241 count = 1;
242 charge = it->getCharge();
243 }
244 if(max < count)
245 max = count;
246
247 size = it->getPeptideFragmentIonSp().get()->size();
248 }
249
250 return max;
251}
252
253std::size_t
255{
256 std::vector<bool> covered;
257 covered.resize(msp_peptide.get()->size(), false);
258
259 for(auto &peak : msp_peptideSpectrumMatch.get()->getPeakIonIsotopeMatchList())
260 {
261 if(peak.getPeptideNaturalIsotopeAverageSp().get()->getIsotopeNumber() == 0)
262 { // only count with monotisotopic
263 if(peak.getPeptideIonType() == ion_type)
264 {
265 covered[peak.getPeptideFragmentIonSp().get()->size() - 1] = true;
266 }
267 }
268 }
269 return std::count(covered.begin(), covered.end(), true);
270}
271
272std::size_t
274{
275
276 std::vector<bool> covered;
277 covered.resize(msp_peptide.get()->size(), false);
278
279 for(auto &peak_pair : m_peakIonPairs)
280 {
281 std::size_t pos = peak_pair.first.getPeptideFragmentIonSp().get()->size() - 1;
282 covered[pos] = true;
283 covered[pos + 1] = true;
284 }
285 return std::count(covered.begin(), covered.end(), true);
286}
287
288
289double
291{
292 std::list<pappso::PeakIonIsotopeMatch> peak_ion_type =
293 msp_peptideSpectrumMatch.get()->getPeakIonIsotopeMatchList();
294
295 peak_ion_type.remove_if(
296 [ion_type](const PeakIonIsotopeMatch &a) { return (a.getPeptideIonType() != ion_type); });
297 auto peak_it = std::max_element(peak_ion_type.begin(),
298 peak_ion_type.end(),
299 [](const PeakIonIsotopeMatch &a, const PeakIonIsotopeMatch &b) {
300 return (a.getPeak().y < b.getPeak().y);
301 });
302
303 if(peak_it == peak_ion_type.end())
304 return 0;
305 return peak_it->getPeak().y;
306}
307
308double
310{
311 auto peak_it = std::max_element(
312 m_peakIonPairs.begin(),
313 m_peakIonPairs.end(),
314 [](const std::pair<pappso::PeakIonIsotopeMatch, pappso::PeakIonIsotopeMatch> &a,
315 const std::pair<pappso::PeakIonIsotopeMatch, pappso::PeakIonIsotopeMatch> &b) {
316 return ((a.first.getPeak().y + a.second.getPeak().y) <
317 (b.first.getPeak().y + b.second.getPeak().y));
318 });
319
320 if(peak_it == m_peakIonPairs.end())
321 return 0;
322
323 return getIonPairPrecursorMassDelta(*peak_it);
324}
325
326double
328 const std::pair<pappso::PeakIonIsotopeMatch, pappso::PeakIonIsotopeMatch> &ion_pair) const
329{
330 qDebug() << m_precursorTheoreticalMz << " " << ion_pair.first.getPeak().x << " "
331 << ion_pair.second.getPeak().x << " " << ion_pair.second.getCharge() << " "
332 << ion_pair.first.getCharge() << " " << m_parentCharge;
333 double diff = (m_precursorTheoreticalMass + (MHPLUS * ion_pair.first.getCharge())) /
334 ion_pair.first.getCharge();
335
336
337 return (diff - (ion_pair.first.getPeak().x + ion_pair.second.getPeak().x -
338 ((MHPLUS * ion_pair.first.getCharge())) / ion_pair.first.getCharge()));
339}
340
341
342void
344{
345 std::size_t peptide_size = peptideSp.get()->size();
346 std::vector<PeakIonIsotopeMatch> ion_isotope_list(
347 msp_peptideSpectrumMatch.get()->getPeakIonIsotopeMatchList().begin(),
348 msp_peptideSpectrumMatch.get()->getPeakIonIsotopeMatchList().end());
349 for(const pappso::PeakIonIsotopeMatch &peak_ion_ext : ion_isotope_list)
350 {
351 if(peptideIonIsNter(peak_ion_ext.getPeptideIonType()))
352 {
353 auto it = findComplementIonType(
354 ion_isotope_list.begin(), ion_isotope_list.end(), peak_ion_ext, peptide_size);
355 if(it != ion_isotope_list.end())
356 { // contains the complementary ion
357 m_peakIonPairs.push_back({peak_ion_ext, *it});
358 }
359 }
360 }
361}
362
363
366{
367 std::size_t peptide_size = msp_peptide.get()->size();
368 std::vector<PeakIonIsotopeMatch> ion_isotope_list(
369 msp_peptideSpectrumMatch.get()->getPeakIonIsotopeMatchList().begin(),
370 msp_peptideSpectrumMatch.get()->getPeakIonIsotopeMatchList().end());
371
372 Trace scaterplot;
373
374 for(Enums::PeptideIon ion_type : m_ionList)
375 {
376 std::vector<double> mono_th_intensities(peptide_size, 0);
377 std::vector<double> isotope_th_intensities(peptide_size, 0);
378
379 std::vector<double> mono_exp_intensities(peptide_size, 0);
380 std::vector<double> isotope_exp_intensities(peptide_size, 0);
381 for(const PeakIonIsotopeMatch &peak_ion_match : ion_isotope_list)
382 {
383 if(peak_ion_match.getPeptideIonType() == ion_type)
384 {
385 std::size_t vector_position =
386 peak_ion_match.getPeptideFragmentIonSp().get()->size() - 1;
387 PeptideNaturalIsotopeAverageSp iso_average_sp =
388 peak_ion_match.getPeptideNaturalIsotopeAverageSp();
389 if(iso_average_sp.get()->getIsotopeNumber() == 0)
390 {
391 mono_th_intensities[vector_position] = iso_average_sp.get()->getIntensityRatio();
392 mono_exp_intensities[vector_position] = peak_ion_match.getPeak().y;
393 }
394 else if(iso_average_sp.get()->getIsotopeNumber() == 1)
395 {
396 isotope_th_intensities[vector_position] =
397 iso_average_sp.get()->getIntensityRatio();
398 isotope_exp_intensities[vector_position] = peak_ion_match.getPeak().y;
399 }
400 }
401 }
402
403 for(std::size_t i = 0; i < mono_th_intensities.size(); i++)
404 {
405 if((mono_th_intensities[i] != 0) && (isotope_th_intensities[i] != 0))
406 {
407 DataPoint xy(mono_th_intensities[i] / isotope_th_intensities[i],
408 mono_exp_intensities[i] / isotope_exp_intensities[i]);
409 scaterplot.push_back(xy);
410 }
411 }
412 }
413
414 scaterplot.sortX();
415
416 LinearRegression linear_regression(scaterplot);
417
418 return linear_regression;
419}
virtual pappso_double getMz(unsigned int charge) const final
Definition ion.cpp:45
Class to represent a mass spectrum.
unsigned int size() const override
Definition peptide.cpp:215
pappso_double getMass()
Definition peptide.cpp:322
double getMaxIntensityPeakIonMatch(Enums::PeptideIon ion_type) const
double getIntensityOfMatchedIon(Enums::PeptideIon ion_type)
get the sum of intensity of a specific ion
std::size_t getNumberOfMatchedIons() const
number of matched ions (peaks)
std::size_t getAaSequenceCoverage(Enums::PeptideIon ion_type)
number of amino acid covered by matched ions
void findComplementIonPairs(const pappso::PeptideSp &peptideSp)
double getTotalIntensity() const
sum of all peak intensities (matched or not)
double getMatchedMzDiffMean() const
get mean deviation of matched peak mass delta
double getTotalIntensityOfMatchedIonComplementPairs() const
intensity of matched ion complement
const std::vector< std::pair< pappso::PeakIonIsotopeMatch, pappso::PeakIonIsotopeMatch > > & getPeakIonPairs() const
std::vector< std::pair< pappso::PeakIonIsotopeMatch, pappso::PeakIonIsotopeMatch > > m_peakIonPairs
std::shared_ptr< FilterResampleKeepGreater > msp_filterKeepGreater
double getIonPairPrecursorMassDelta(const std::pair< pappso::PeakIonIsotopeMatch, pappso::PeakIonIsotopeMatch > &ion_pair) const
double m_precursorTheoreticalMz
double getMaxIntensityMatchedIonComplementPairPrecursorMassDelta() const
get the precursor mass delta of the maximum intensity pair of complement ions
std::size_t countMatchedIonComplementPairs() const
count the number of matched ion complement
std::size_t getComplementPairsAaSequenceCoverage()
number of amino acid covered by matched complement pairs of ions
double getTotalIntensityOfMatchedIons() const
sum of matched peak intensities
std::size_t getMaxConsecutiveIon(Enums::PeptideIon ion_type)
get the maximum consecutive fragments of one ion type
LinearRegression getIonIsotopeLinearRegression() const
unsigned int m_parentCharge
std::list< Enums::PeptideIon > m_ionList
std::shared_ptr< PeptideIsotopeSpectrumMatch > msp_peptideSpectrumMatch
void setPeptideSpectrumCharge(const pappso::PeptideSp peptideSp, const MassSpectrum *p_spectrum, unsigned int parent_charge, unsigned int max_isotope_number)
PrecisionPtr m_ms2precision
pappso::PeptideSp msp_peptide
double m_precursorTheoreticalMass
PsmFeatures(PrecisionPtr ms2precision, double minimumMz)
compute psm features
double getMatchedMzDiffSd() const
get standard deviation of matched peak mass delta
double m_spectrumSumIntensity
A simple container of DataPoint instances.
Definition trace.h:148
pappso_double sumY() const
Definition trace.cpp:978
void sortX(Enums::SortOrder sort_order=Enums::SortOrder::ascending)
Definition trace.cpp:1039
PeptideIon
Enums::PeptideIon enum defines all types of ions (Nter or Cter)
Definition types.h:286
@ y
Cter amino ions.
Definition types.h:295
@ b
Nter acylium ions.
Definition types.h:287
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
const pappso_double MHPLUS(1.007276466879)
double pappso_double
A type definition for doubles.
Definition types.h:61
std::shared_ptr< const PeptideNaturalIsotopeAverage > PeptideNaturalIsotopeAverageSp
bool peptideIonIsNter(Enums::PeptideIon ion_type)
tells if an ion is Nter
Definition peptide.cpp:85
std::vector< PeakIonIsotopeMatch >::iterator findComplementIonType(std::vector< PeakIonIsotopeMatch >::iterator begin, std::vector< PeakIonIsotopeMatch >::iterator end, const PeakIonIsotopeMatch &peak_ion, std::size_t peptide_size)
find the first element containing the complementary ion complementary ion of y1 is b(n-1) for instanc...
const PrecisionBase * PrecisionPtr
Definition precision.h:122