libpappsomspp
Library for mass spectrometry
Loading...
Searching...
No Matches
posttreatment.cpp
Go to the documentation of this file.
1/**
2 * \file pappsomspp/processing/specglob/sgposttreatment.cpp
3 * \date 15/11/2023
4 * \author Olivier Langella
5 * \brief SpecGlobTool peptide model post treatment
6 *
7 * C++ implementation of the SpecGlob algorithm described in :
8 * 1. Prunier, G. et al. Fast alignment of mass spectra in large proteomics
9 * datasets, capturing dissimilarities arising from multiple complex
10 * modifications of peptides. BMC Bioinformatics 24, 421 (2023).
11 *
12 * HAL Id : hal-04296170 , version 1
13 * Mot de passe : hxo20cl
14 * DOI : 10.1186/s12859-023-05555-y
15 */
16
17
18/*
19 * SpecGlobTool, Spectra to peptide alignment tool
20 * Copyright (C) 2023 Olivier Langella
21 * <olivier.langella@universite-paris-saclay.fr>
22 *
23 * This program is free software: you can redistribute ipetide to spectrum
24 * alignmentt and/or modify it under the terms of the GNU General Public License
25 * as published by the Free Software Foundation, either version 3 of the
26 * License, or (at your option) any later version.
27 *
28 * This program is distributed in the hope that it will be useful,
29 * but WITHOUT ANY WARRANTY; without even the implied warranty of
30 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31 * GNU General Public License for more details.
32 *
33 * You should have received a copy of the GNU General Public License
34 * along with this program. If not, see <http://www.gnu.org/licenses/>.
35 *
36 */
37
38#include "posttreatment.h"
39
40
41namespace pappso
42{
43namespace specglob
44{
46 : m_originalPeptideModel(peptide_model), m_betterPeptideModel(peptide_model)
47{
48 m_precision = precision;
49 m_originalPeptideModel.matchExperimentalPeaks(m_precision);
50
52}
53
57
58const PeptideModel &
63
64void
66{
67 if(std::abs(m_originalPeptideModel.getMassDelta()) > m_precision->getNominal())
68 {
69 // calculate the number of shared peaks with the deltaM on the last aa
70 m_betterPeptideModel.assignResidualMass2Cter();
71 m_betterPeptideModel.matchExperimentalPeaks(m_precision);
72 if(m_betterPeptideModel.getCountSharedPeaks() > m_originalPeptideModel.getCountSharedPeaks())
73 {
74 }
75 else
76 {
77 // not better, get back to original peptide
79 }
80 }
81 else
82 {
83 m_betterPeptideModel.matchExperimentalPeaks(m_precision);
84 }
85
86
87 // Try to remove complementary mass offset
88 // Not done if the number of peaks is increased by more than two peaks
89 // If the number of peaks > +2, it is considered as an information that must
90 // be kept in the alignment Could be modified...the information is in the
91 // preAligned column
92 PeptideModel test_peptide_model_remove_complementary(m_betterPeptideModel);
93 if(test_peptide_model_remove_complementary.eliminateComplementaryDelta(m_precision))
94 {
95
96 test_peptide_model_remove_complementary.matchExperimentalPeaks(m_precision);
97
98 qDebug() << "test_peptide_model_remove_complementary.getCountSharedPeaks()="
99 << test_peptide_model_remove_complementary.getCountSharedPeaks()
100 << " m_betterPeptideModel.getCountSharedPeaks()="
101 << m_betterPeptideModel.getCountSharedPeaks();
102 if(test_peptide_model_remove_complementary.getCountSharedPeaks() <
103 m_betterPeptideModel.getCountSharedPeaks() + 2)
104 {
105 qDebug() << "replace with " << test_peptide_model_remove_complementary.toString();
106 m_betterPeptideModel.copyDeep(test_peptide_model_remove_complementary);
107 }
108 }
109
110 // if bestModified contains negative offSet, try to remove amino acids to
111 // explain it
112 PeptideModel test_peptide_model_remove_negative = m_betterPeptideModel;
113 if(test_peptide_model_remove_negative.eliminateNegativeOffset(m_precision))
114 {
115 test_peptide_model_remove_negative.matchExperimentalPeaks(m_precision);
116 if(test_peptide_model_remove_negative.getCountSharedPeaks() >=
117 m_betterPeptideModel.getCountSharedPeaks())
118 {
119 qDebug() << "replace with " << test_peptide_model_remove_negative.toString();
120 m_betterPeptideModel.copyDeep(test_peptide_model_remove_negative);
121 }
122 }
123
124 // findBetterMassDifferencePosition
127
128
129 if(m_betterPeptideModel.getMassDelta() < -m_precision->getNominal())
130 {
132 }
133
134 m_betterPeptideModel.removeBracketsForAlignedAA();
135}
136
137void
139{
140
141 PeptideModel better_peptide_model_move_offset = m_betterPeptideModel;
142 std::size_t best_count_shared_peaks = m_betterPeptideModel.getCountSharedPeaks();
143 qDebug() << best_count_shared_peaks;
144
145 qDebug() << m_betterPeptideModel.toString();
146 bool move = false;
147 for(std::size_t i = 0; i < m_betterPeptideModel.size(); i++)
148 {
149
150 qDebug() << "i =" << i;
151 if(m_betterPeptideModel.at(i).remove == true)
152 continue;
153 if(m_betterPeptideModel.at(i).mass_difference == 0.0)
154 continue;
155 if(m_betterPeptideModel.at(i).bracket == true)
156 {
157 // try to move if
158 double mass_diff = m_betterPeptideModel.at(i).mass_difference;
159 PeptideModel test_peptide_model_move_offset = better_peptide_model_move_offset;
160 test_peptide_model_move_offset.at(i).mass_difference = 0;
161 qDebug() << test_peptide_model_move_offset.toString();
162
163 std::size_t j = i;
164 while(j > 0)
165 {
166 j -= 1;
167 if(test_peptide_model_move_offset.at(j).bracket == false)
168 break;
169 if(test_peptide_model_move_offset.at(j).mass_difference != 0.0)
170 break;
171
172 test_peptide_model_move_offset.at(j).mass_difference = mass_diff;
173 test_peptide_model_move_offset.matchExperimentalPeaks(m_precision);
174
175 qDebug() << test_peptide_model_move_offset.toString() << " "
176 << test_peptide_model_move_offset.getCountSharedPeaks() << " "
177 << best_count_shared_peaks;
178 if(test_peptide_model_move_offset.getCountSharedPeaks() > best_count_shared_peaks)
179 {
180 best_count_shared_peaks = test_peptide_model_move_offset.getCountSharedPeaks();
181 better_peptide_model_move_offset.copyDeep(test_peptide_model_move_offset);
182 move = true;
183 }
184 else
185 {
186 test_peptide_model_move_offset = better_peptide_model_move_offset;
187 }
188 }
189 }
190 }
191
192 if(move)
193 {
194 m_betterPeptideModel.copyDeep(better_peptide_model_move_offset);
195 }
196 qDebug() << m_betterPeptideModel.toString();
197}
198
199
200void
202{
203
204 // We'll try to evaluate for each deltaM if it can be a neutral loss or not
205 // For this, we compare the number of shared peaks with and without the shift
206
207 PeptideModel better_peptide_model_for_neutral_loss;
208 std::size_t best_count_shared_peaks = m_betterPeptideModel.getCountSharedPeaks();
209 qDebug() << best_count_shared_peaks;
210 for(std::size_t i = 0; i < m_betterPeptideModel.size(); i++)
211 {
212 if(m_betterPeptideModel.at(i).remove == true)
213 continue;
214 if(m_betterPeptideModel.at(i).mass_difference == 0.0)
215 continue;
216
217
218 // try in the case we remove the offset
219 PeptideModel test_peptide_model_for_neutral_loss = m_betterPeptideModel;
220 test_peptide_model_for_neutral_loss.at(i).mass_difference = 0;
221 test_peptide_model_for_neutral_loss.matchExperimentalPeaks(m_precision);
222
223 qDebug() << test_peptide_model_for_neutral_loss.toString() << " "
224 << test_peptide_model_for_neutral_loss.getCountSharedPeaks() << " "
225 << best_count_shared_peaks;
226 if(test_peptide_model_for_neutral_loss.getCountSharedPeaks() >= best_count_shared_peaks)
227 {
228 best_count_shared_peaks = test_peptide_model_for_neutral_loss.getCountSharedPeaks();
229 better_peptide_model_for_neutral_loss.copyDeep(test_peptide_model_for_neutral_loss);
230 }
231 }
232
233 if(better_peptide_model_for_neutral_loss.size() > 0)
234 {
235 m_betterPeptideModel.copyDeep(better_peptide_model_for_neutral_loss);
236 }
237}
238
239void
241{
242 double mass_delta = m_betterPeptideModel.getMassDelta();
243 std::size_t best_count_shared_peaks = m_betterPeptideModel.getCountSharedPeaks();
244 PeptideModel better_peptide_model_cumulating_residual_mass_delta;
245 for(std::size_t i = 0; i < m_betterPeptideModel.size(); i++)
246 {
247 if(m_betterPeptideModel.at(i).remove == true)
248 continue;
249 if(m_betterPeptideModel.at(i).mass_difference == 0.0)
250 continue;
251
252 PeptideModel test_peptide_model_cumulating_residual_mass_delta = m_betterPeptideModel;
253 // try to cumulate the current mass difference with unexplained mass delta
254 // :
255 test_peptide_model_cumulating_residual_mass_delta.at(i).mass_difference += mass_delta;
256 test_peptide_model_cumulating_residual_mass_delta.matchExperimentalPeaks(m_precision);
257 if(test_peptide_model_cumulating_residual_mass_delta.getCountSharedPeaks() >=
258 best_count_shared_peaks)
259 {
260 best_count_shared_peaks =
261 test_peptide_model_cumulating_residual_mass_delta.getCountSharedPeaks();
262 better_peptide_model_cumulating_residual_mass_delta.copyDeep(
263 test_peptide_model_cumulating_residual_mass_delta);
264 }
265 }
266
267 if(better_peptide_model_cumulating_residual_mass_delta.size() > 0)
268 {
269 m_betterPeptideModel.copyDeep(better_peptide_model_cumulating_residual_mass_delta);
270 }
271}
272
273
274const PeptideModel &
279
280bool
282{
283 auto peptide_model = m_betterPeptideModel;
284
285 bool modif = false;
286 std::vector<Enums::AminoAcidChar> aa_list = {Enums::AminoAcidChar::alanine,
305 if(peptide_model.checkForMutations(aa_list, m_precision))
306 {
307 modif = true;
308 }
309 pappso::Aa cysteine('C');
310 cysteine.addAaModification(pappso::AaModification::getInstance("MOD:00397")); // carbamido
311 if(peptide_model.checkForMutation(cysteine, m_precision))
312 {
313 modif = true;
314 }
315 pappso::Aa methionine('M');
316 methionine.addAaModification(pappso::AaModification::getInstance("MOD:00719")); // oxydation
317 if(peptide_model.checkForMutation(methionine, m_precision))
318 {
319 modif = true;
320 }
321 if(modif)
322 {
323 m_betterPeptideModel = peptide_model;
324 }
325 return modif;
326}
327} // namespace specglob
328} // namespace pappso
static AaModificationP getInstance(const QString &accession)
std::size_t getCountSharedPeaks() const
void matchExperimentalPeaks(pappso::PrecisionPtr precision)
bool eliminateNegativeOffset(pappso::PrecisionPtr precision)
bool eliminateComplementaryDelta(pappso::PrecisionPtr precision)
PeptideModel & copyDeep(const PeptideModel &other)
PostTreatment(pappso::PrecisionPtr precision, const PeptideModel &peptide_model)
const PeptideModel & getOriginalPeptideModel() const
pappso::PrecisionPtr m_precision
void findBetterPeptideModel()
whole processus to find a better peptide model
void tryToCumulateOffSets()
try to assign residual mass delta to non aligned elements
const PeptideModel & getBetterPeptideModel() const
void tryToRemoveOffsets()
try to remove offset (mass difference)
void tryBetterPositionOffsets()
try to move offset (mass difference)
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...
Definition aa.cpp:39
const PrecisionBase * PrecisionPtr
Definition precision.h:122