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