libpappsomspp
Library for mass spectrometry
massspectrum.cpp
Go to the documentation of this file.
1/**
2 * \file pappsomspp/massspectrum/massspectrum.cpp
3 * \date 15/3/2015
4 * \author Olivier Langella
5 * \brief basic mass spectrum
6 */
7
8/*******************************************************************************
9 * Copyright (c) 2015 Olivier Langella <Olivier.Langella@moulon.inra.fr>.
10 *
11 * This file is part of the PAPPSOms++ library.
12 *
13 * PAPPSOms++ 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++ 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++. If not, see <http://www.gnu.org/licenses/>.
25 *
26 * Contributors:
27 * Olivier Langella <Olivier.Langella@moulon.inra.fr> - initial API and
28 *implementation
29 ******************************************************************************/
30
31#include <cmath>
32#include <numeric>
33#include <limits>
34#include <vector>
35#include <map>
36
37#include <QDebug>
38
39#include "../trace/datapoint.h"
40#include "../trace/trace.h"
41#include "massspectrum.h"
42#include "../processing/combiners/massspectrumcombiner.h"
43#include "../mzrange.h"
44#include "../pappsoexception.h"
45
46#include "../peptide/peptidefragmentionlistbase.h"
47#include "../exception/exceptionoutofrange.h"
48#include "../processing/filters/filterresample.h"
49
50
52 qRegisterMetaType<pappso::MassSpectrum>("pappso::MassSpectrum");
54 qRegisterMetaType<pappso::MassSpectrum *>("pappso::MassSpectrum *");
55
56
57namespace pappso
58{
59
60
62{
63}
64
65
67 std::vector<std::pair<pappso_double, pappso_double>> &data_point_vector)
68 : Trace::Trace(data_point_vector)
69{
70}
71
72MassSpectrum::MassSpectrum(std::vector<DataPoint> &data_point_vector)
73 : Trace::Trace(data_point_vector)
74{
75}
76
78{
79}
80
82{
83}
84
85
86MassSpectrum::MassSpectrum(Trace &&other) : Trace(std::move(other))
87{
88}
89
90
92{
93 // qDebug() << __FILE__ << "@" << __LINE__ << __FUNCTION__ << "()";
94}
95
96
97MassSpectrum::MassSpectrum(MassSpectrum &&other) : Trace(std::move(other))
98{
99 // Specify std::move so that && reference is passed to the Trace constructor
100 // that takes std::vector<DataPoint> && as rvalue reference.
101
102 // qDebug() << __FILE__ << "@" << __LINE__ << __FUNCTION__ << "()"
103 //<< "Moving MassSpectrum::MassSpectrum(MassSpectrum &&)";
104}
105
106
108{
109}
110
111
114{
115 // qDebug() << __FILE__ << "@" << __LINE__ << __FUNCTION__ << " ()";
116
117 assign(other.begin(), other.end());
118 return *this;
119}
120
121
124{
125 vector<DataPoint>::operator=(std::move(other));
126 return *this;
127}
128
129
132{
133 return std::make_shared<MassSpectrum>(*this);
134}
135
136
139{
140 return std::make_shared<const MassSpectrum>(*this);
141}
142
143
144//! Compute the total ion current of this mass spectrum
145/*!
146 * The sum of all the separate ion currents carried by the ions of different
147 * m/z contributing to a complete mass massSpectrum or in a specified m/z
148 * range of a mass massSpectrum. MS:1000285
149 *
150 * \return <pappso_double> The total ion current.
151 */
154{
155 return Trace::sumY();
156}
157
158
159//! Compute the total ion current of this mass spectrum
160/*!
161 * Convenience function that returns totalIonCurrent();
162 */
165{
166 return totalIonCurrent();
167}
168
169
171MassSpectrum::tic(double mzStart, double mzEnd)
172{
173 return Trace::sumY(mzStart, mzEnd);
174}
175
176
177//! Find the DataPoint instance having the greatest intensity (y) value.
178/*!
179 * \return <const DataPoint &> The data point having the maximum intensity (y)
180 * value of the whole mass spectrum.
181 */
182const DataPoint &
184{
185 return Trace::maxYDataPoint();
186}
187
188
189//! Find the DataPoint instance having the smallest intensity (y) value.
190/*!
191 * \return <const DataPoint &> The data point having the minimum intensity (y)
192 * value of the whole mass spectrum.
193 */
194const DataPoint &
196{
197 return Trace::minYDataPoint();
198}
199
200
201//! Sort the DataPoint instances of this spectrum.
202/*!
203 * The DataPoint instances are sorted according to the x value (the m/z
204 * value) and in increasing order.
205 */
206void
208{
209 Trace::sortX();
210}
211
212
213//! Tells if \c this MassSpectrum is equal to \p massSpectrum.
214/*!
215 * To compare \c this to \p massSpectrum, a tolerance is applied to both the x
216 * and y values, that is defined using \p precision.
217 *
218 * \param massSpectrum Mass spectrum to compare to \c this.
219 *
220 * \param precision Precision to be used to perform the comparison of the x
221 * and y values of the data points in \c this and \massSpectrum mass spectra.
222 */
223bool
224MassSpectrum::equals(const MassSpectrum &other, PrecisionPtr precision) const
225{
226 if(size() != other.size())
227 {
228 qDebug() << __FILE__ << "@" << __LINE__ << __FUNCTION__ << "()"
229 << "The other mass spectrum size is not equal to *this size"
230 << "*this size:" << size() << "trace size:" << other.size();
231
232 return false;
233 }
234
236
237 auto trace_it = other.begin();
238
239 for(auto &&data_point : *this)
240 {
241 qDebug() << "first:" << data_point.x << "," << data_point.y
242 << " second:" << trace_it->x << "," << trace_it->y;
243
244 if(!MzRange(data_point.x, precision).contains(trace_it->x))
245 {
246 qDebug() << "x:" << data_point.x << " != " << trace_it->x;
247 return false;
248 }
249
250 if(!MzRange(data_point.y, precint).contains(trace_it->y))
251 {
252 qDebug() << "y:" << data_point.y << " != " << trace_it->y;
253 return false;
254 }
255
256 trace_it++;
257 }
258
259 return true;
260}
261
262
265{
266 MassSpectrum massSpectrum;
267
268 std::vector<DataPoint>::const_iterator it = begin();
269 std::vector<DataPoint>::const_iterator itEnd = end();
270
271 std::vector<DataPoint>::const_reverse_iterator itRev = rbegin();
272 std::vector<DataPoint>::const_reverse_iterator itRevEnd = rend();
273
274 pappso_double lower = range.lower();
275 pappso_double upper = range.upper();
276
277 while((it != itEnd) && (it->x <= itRev->x) && (itRev != itRevEnd))
278 {
279 pappso_double sumX = it->x + itRev->x;
280
281 if(sumX < lower)
282 {
283 it++;
284 }
285 else if(sumX > upper)
286 {
287 itRev++;
288 }
289 else
290 {
291 massSpectrum.push_back(*it);
292 massSpectrum.push_back(*itRev);
293
294 std::vector<DataPoint>::const_reverse_iterator itRevIn = itRev;
295 itRevIn++;
296
297 // FIXME Attention buggy code FR 20180626.
298 sumX = it->x + itRevIn->x;
299 while((sumX > lower) && (it->x <= itRevIn->x) &&
300 (itRevIn != itRevEnd))
301 {
302 sumX = it->x + itRevIn->x;
303 // trace.push_back(*it);
304 massSpectrum.push_back(*itRevIn);
305 itRevIn++;
306 }
307 it++;
308 }
309 }
310
311 // Sort all the data points in increasing order by x
312 std::sort(massSpectrum.begin(),
313 massSpectrum.end(),
314 [](const DataPoint &a, const DataPoint &b) { return (a.x < b.x); });
315
316 // Remove all the but the first element of a series of elements that are
317 // considered equal. Sort of deduplication.
318 std::vector<DataPoint>::iterator itEndFix =
319 std::unique(massSpectrum.begin(),
320 massSpectrum.end(),
321 [](const DataPoint &a, const DataPoint &b) {
322 // Return true if both elements should be considered equal.
323 return (a.x == b.x) && (a.y == b.y);
324 });
325
326 massSpectrum.resize(std::distance(massSpectrum.begin(), itEndFix));
327
328 return massSpectrum;
329}
330
331
332void
334{
335
336 qDebug() << size();
337 for(std::size_t i = 0; i < size(); i++)
338 {
339 qDebug() << "(" << this->operator[](i).x << "," << this->operator[](i).y
340 << ")";
341 }
342}
343
344
345QDataStream &
346operator<<(QDataStream &outstream, const MassSpectrum &massSpectrum)
347{
348 quint32 vector_size = massSpectrum.size();
349 outstream << vector_size;
350 for(auto &&peak : massSpectrum)
351 {
352 outstream << peak;
353 }
354
355 return outstream;
356}
357
358
359QDataStream &
360operator>>(QDataStream &instream, MassSpectrum &massSpectrum)
361{
362
363 quint32 vector_size;
364 DataPoint peak;
365
366 if(!instream.atEnd())
367 {
368 instream >> vector_size;
369 qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__
370 << " vector_size=" << vector_size;
371
372 for(quint32 i = 0; i < vector_size; i++)
373 {
374
375 if(instream.status() != QDataStream::Ok)
376 {
377 throw PappsoException(
378 QString("error in QDataStream unserialize operator>> of "
379 "massSpectrum :\nread datastream failed status=%1 "
380 "massSpectrum "
381 "i=%2 on size=%3")
382 .arg(instream.status())
383 .arg(i)
384 .arg(vector_size));
385 }
386 instream >> peak;
387 massSpectrum.push_back(peak);
388 }
389 if(instream.status() != QDataStream::Ok)
390 {
391 throw PappsoException(
392 QString(
393 "error in QDataStream unserialize operator>> of massSpectrum "
394 ":\nread datastream failed status=%1")
395 .arg(instream.status()));
396 }
397 }
398
399 return instream;
400}
401
402
403MassSpectrum &
405{
406 return filter.filter(*this);
407}
408
409} // namespace pappso
generic interface to apply a filter on a MassSpectrum This is the same as FilterInterface,...
Class to represent a mass spectrum.
Definition: massspectrum.h:71
void sortMz()
Sort the DataPoint instances of this spectrum.
void debugPrintValues() const
MassSpectrumCstSPtr makeMassSpectrumCstSPtr() const
bool equals(const MassSpectrum &other, PrecisionPtr precision) const
Tells if this MassSpectrum is equal to massSpectrum.
MassSpectrumSPtr makeMassSpectrumSPtr() const
pappso_double tic() const
Compute the total ion current of this mass spectrum.
const DataPoint & minIntensityDataPoint() const
Find the DataPoint instance having the smallest intensity (y) value.
virtual MassSpectrum & massSpectrumFilter(const MassSpectrumFilterInterface &filter) final
apply a filter on this MassSpectrum
MassSpectrum filterSum(const MzRange &mass_range) const
virtual MassSpectrum & operator=(const MassSpectrum &other)
pappso_double totalIonCurrent() const
Compute the total ion current of this mass spectrum.
const DataPoint & maxIntensityDataPoint() const
Find the DataPoint instance having the greatest intensity (y) value.
pappso_double lower() const
Definition: mzrange.h:71
pappso_double upper() const
Definition: mzrange.h:77
bool contains(pappso_double) const
Definition: mzrange.cpp:120
static PrecisionPtr getPpmInstance(pappso_double value)
get a ppm precision pointer
Definition: precision.cpp:150
A simple container of DataPoint instances.
Definition: trace.h:148
void sortX(SortOrder sort_order=SortOrder::ascending)
Definition: trace.cpp:1086
pappso_double sumY() const
Definition: trace.cpp:1023
const DataPoint & maxYDataPoint() const
Definition: trace.cpp:976
virtual Trace & filter(const FilterInterface &filter) final
apply a filter on this trace
Definition: trace.cpp:1211
const DataPoint & minYDataPoint() const
Definition: trace.cpp:957
int massSpectrumPtrMetaTypeId
int massSpectrumMetaTypeId
basic mass spectrum
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...
Definition: aa.cpp:39
QDataStream & operator<<(QDataStream &outstream, const MassSpectrum &massSpectrum)
QDataStream & operator>>(QDataStream &instream, MassSpectrum &massSpectrum)
double pappso_double
A type definition for doubles.
Definition: types.h:50
std::shared_ptr< const MassSpectrum > MassSpectrumCstSPtr
Definition: massspectrum.h:55
std::shared_ptr< MassSpectrum > MassSpectrumSPtr
Definition: massspectrum.h:54