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 
57 namespace 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 
72 MassSpectrum::MassSpectrum(std::vector<DataPoint> &data_point_vector)
73  : Trace::Trace(data_point_vector)
74 {
75 }
76 
77 MassSpectrum::MassSpectrum(const Trace &other) : Trace(other)
78 {
79 }
80 
82 {
83 }
84 
85 
86 MassSpectrum::MassSpectrum(Trace &&other) : Trace(std::move(other))
87 {
88 }
89 
90 
92 {
93  // qDebug() << __FILE__ << "@" << __LINE__ << __FUNCTION__ << "()";
94 }
95 
96 
97 MassSpectrum::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 
112 MassSpectrum &
114 {
115  // qDebug() << __FILE__ << "@" << __LINE__ << __FUNCTION__ << " ()";
116 
117  assign(other.begin(), other.end());
118  return *this;
119 }
120 
121 
122 MassSpectrum &
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 
171 MassSpectrum::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  */
182 const 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  */
194 const 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  */
206 void
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  */
223 bool
224 MassSpectrum::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 
264 MassSpectrum::filterSum(const MzRange &range) const
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 
332 void
334 {
335 
336  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__ << size();
337  for(std::size_t i = 0; i < size(); i++)
338  {
339  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
340  qDebug() << "mz = " << this->operator[](i).x
341  << ", int = " << this->operator[](i).y;
342  }
343 
344  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__;
345 }
346 
347 
348 QDataStream &
349 operator<<(QDataStream &outstream, const MassSpectrum &massSpectrum)
350 {
351  quint32 vector_size = massSpectrum.size();
352  outstream << vector_size;
353  for(auto &&peak : massSpectrum)
354  {
355  outstream << peak;
356  }
357 
358  return outstream;
359 }
360 
361 
362 QDataStream &
363 operator>>(QDataStream &instream, MassSpectrum &massSpectrum)
364 {
365 
366  quint32 vector_size;
367  DataPoint peak;
368 
369  if(!instream.atEnd())
370  {
371  instream >> vector_size;
372  qDebug() << __FILE__ << " " << __FUNCTION__ << " " << __LINE__
373  << " vector_size=" << vector_size;
374 
375  for(quint32 i = 0; i < vector_size; i++)
376  {
377 
378  if(instream.status() != QDataStream::Ok)
379  {
380  throw PappsoException(
381  QString("error in QDataStream unserialize operator>> of "
382  "massSpectrum :\nread datastream failed status=%1 "
383  "massSpectrum "
384  "i=%2 on size=%3")
385  .arg(instream.status())
386  .arg(i)
387  .arg(vector_size));
388  }
389  instream >> peak;
390  massSpectrum.push_back(peak);
391  }
392  if(instream.status() != QDataStream::Ok)
393  {
394  throw PappsoException(
395  QString(
396  "error in QDataStream unserialize operator>> of massSpectrum "
397  ":\nread datastream failed status=%1")
398  .arg(instream.status()));
399  }
400  }
401 
402  return instream;
403 }
404 
405 
406 MassSpectrum &
408 {
409  return filter.filter(*this);
410 }
411 
412 } // 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
pappso_double sumY() const
Definition: trace.cpp:906
const DataPoint & maxYDataPoint() const
Definition: trace.cpp:873
void sortX()
Definition: trace.cpp:956
virtual Trace & filter(const FilterInterface &filter) final
apply a filter on this trace
Definition: trace.cpp:1001
const DataPoint & minYDataPoint() const
Definition: trace.cpp:854
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:49
std::shared_ptr< const MassSpectrum > MassSpectrumCstSPtr
Definition: massspectrum.h:55
std::shared_ptr< MassSpectrum > MassSpectrumSPtr
Definition: massspectrum.h:54