libpappsomspp
Library for mass spectrometry
trace.cpp
Go to the documentation of this file.
1 #include <numeric>
2 #include <limits>
3 #include <vector>
4 #include <map>
5 #include <cmath>
6 #include <algorithm>
7 #include <iostream>
8 #include <iomanip>
9 
10 #include <QDebug>
11 #include <QObject>
12 
13 #include "trace.h"
14 #include "maptrace.h"
15 #include "../processing/combiners/tracepluscombiner.h"
16 #include "../processing/combiners/traceminuscombiner.h"
17 #include "../types.h"
18 #include "../pappsoexception.h"
19 #include "../exception/exceptionoutofrange.h"
20 #include "../exception/exceptionnotpossible.h"
21 #include "../processing/filters/filterresample.h"
22 #include "../processing/filters/filterpass.h"
23 
24 
25 int traceMetaTypeId = qRegisterMetaType<pappso::Trace>("pappso::Trace");
26 int tracePtrMetaTypeId = qRegisterMetaType<pappso::Trace *>("pappso::Trace *");
27 
28 
29 namespace pappso
30 {
31 
32 QDataStream &
33 operator<<(QDataStream &out, const Trace &trace)
34 {
35  for(auto &dataPoint : trace)
36  {
37  out << dataPoint.x;
38  out << dataPoint.y;
39  out << "\n";
40  }
41  out << "\n";
42 
43  return out;
44 }
45 
46 
47 QDataStream &
48 operator>>(QDataStream &in, Trace &trace)
49 {
50  if(in.atEnd())
51  {
52  throw PappsoException(
53  QString("error in QDataStream unserialize operator>> of trace:\n"
54  "read datastream failed status=%1")
55  .arg(in.status()));
56  }
57 
58  for(auto &dataPoint : trace)
59  {
60  in >> dataPoint.x;
61  in >> dataPoint.y;
62  }
63 
64  return in;
65 }
66 
67 
68 std::vector<DataPoint>::iterator
69 findFirstEqualOrGreaterX(std::vector<DataPoint>::iterator begin,
70  std::vector<DataPoint>::iterator end,
71  const double &value)
72 {
73  return std::find_if(begin, end, [value](const DataPoint &to_compare) {
74  if(to_compare.x < value)
75  {
76  return false;
77  }
78  return true;
79  });
80 }
81 
82 std::vector<DataPoint>::const_iterator
83 findFirstEqualOrGreaterX(std::vector<DataPoint>::const_iterator begin,
84  std::vector<DataPoint>::const_iterator end,
85  const double &value)
86 {
87  return std::find_if(begin, end, [value](const DataPoint &to_compare) {
88  if(to_compare.x < value)
89  {
90  return false;
91  }
92  return true;
93  });
94 }
95 
96 std::vector<DataPoint>::iterator
97 findFirstGreaterX(std::vector<DataPoint>::iterator begin,
98  std::vector<DataPoint>::iterator end,
99  const double &value)
100 {
101  return std::find_if(begin, end, [value](const DataPoint &to_compare) {
102  if(to_compare.x > value)
103  {
104  return true;
105  }
106  return false;
107  });
108 }
109 
110 std::vector<DataPoint>::const_iterator
111 findFirstGreaterX(std::vector<DataPoint>::const_iterator begin,
112  std::vector<DataPoint>::const_iterator end,
113  const double &value)
114 {
115  return std::find_if(begin, end, [value](const DataPoint &to_compare) {
116  if(to_compare.x > value)
117  {
118  return true;
119  }
120  return false;
121  });
122 }
123 
124 std::vector<DataPoint>::iterator
125 findDifferentYvalue(std::vector<DataPoint>::iterator begin,
126  std::vector<DataPoint>::iterator end,
127  const double &y_value)
128 {
129  return std::find_if(begin, end, [y_value](const DataPoint &to_compare) {
130  if(to_compare.y != y_value)
131  {
132  return true;
133  }
134 
135  return false;
136  });
137 }
138 
139 std::vector<DataPoint>::const_iterator
140 findDifferentYvalue(std::vector<DataPoint>::const_iterator begin,
141  std::vector<DataPoint>::const_iterator end,
142  const double &y_value)
143 {
144  return std::find_if(begin, end, [y_value](const DataPoint &to_compare) {
145  if(to_compare.y != y_value)
146  {
147  return true;
148  }
149 
150  return false;
151  });
152 }
153 
154 
155 std::vector<DataPoint>::const_iterator
156 minYDataPoint(std::vector<DataPoint>::const_iterator begin,
157  std::vector<DataPoint>::const_iterator end)
158 {
159  return std::min_element(
160  begin, end, [](const DataPoint &a, const DataPoint &b) {
161  return a.y < b.y;
162  });
163 }
164 
165 
166 std::vector<DataPoint>::iterator
167 minYDataPoint(std::vector<DataPoint>::iterator begin,
168  std::vector<DataPoint>::iterator end)
169 {
170  return std::min_element(
171  begin, end, [](const DataPoint &a, const DataPoint &b) {
172  return a.y < b.y;
173  });
174 }
175 
176 
177 std::vector<DataPoint>::const_iterator
178 maxYDataPoint(std::vector<DataPoint>::const_iterator begin,
179  std::vector<DataPoint>::const_iterator end)
180 {
181  return std::max_element(
182  begin, end, [](const DataPoint &a, const DataPoint &b) {
183  return a.y < b.y;
184  });
185 }
186 
187 
188 std::vector<DataPoint>::iterator
189 maxYDataPoint(std::vector<DataPoint>::iterator begin,
190  std::vector<DataPoint>::iterator end)
191 {
192  return std::max_element(
193  begin, end, [](const DataPoint &a, const DataPoint &b) {
194  return a.y < b.y;
195  });
196 }
197 
198 
199 // As long as next DataPoint has its y value less or equal to prev's,
200 // move along down the container. That is, continue moving is
201 // direction is downhill to the end of the container (its back).
202 std::vector<DataPoint>::const_iterator
204  std::vector<DataPoint>::const_iterator begin)
205 {
206  if(begin == trace.end())
207  return begin;
208  auto it = begin + 1;
209  auto result = begin;
210  // Move along as long as next point's y value is less
211  // or equal to prev point's y value (FR, check).
212  while((it != trace.end()) && (it->y <= result->y))
213  {
214  it++;
215  result++;
216  }
217  return result;
218 }
219 
220 std::vector<DataPoint>::const_iterator
222  std::vector<DataPoint>::const_iterator begin)
223 {
224  if(begin == trace.begin())
225  return begin;
226  auto it = begin - 1;
227  auto result = begin;
228 
229  // As long as prev datapoint has y value less or equal to next,
230  // move along up the container. That is, continue moving if
231  // direction is downhill to the beginning of the container (its front).
232  while((it != trace.begin()) && (it->y <= result->y))
233  {
234  it--;
235  result--;
236  }
237  return result;
238 }
239 
240 
241 double
242 sumYTrace(std::vector<DataPoint>::const_iterator begin,
243  std::vector<DataPoint>::const_iterator end,
244  double init)
245 {
246  return std::accumulate(
247  begin, end, init, [](double a, const DataPoint &b) { return a + b.y; });
248 }
249 
250 double
251 meanYTrace(std::vector<DataPoint>::const_iterator begin,
252  std::vector<DataPoint>::const_iterator end)
253 {
254  pappso_double nb_element = distance(begin, end);
255  if(nb_element == 0)
256  throw ExceptionOutOfRange(
257  QObject::tr("unable to compute mean on a trace of size 0"));
258  return (sumYTrace(begin, end, 0) / nb_element);
259 }
260 
261 
262 double
263 quantileYTrace(std::vector<DataPoint>::const_iterator begin,
264  std::vector<DataPoint>::const_iterator end,
265  double quantile)
266 {
267  std::size_t nb_element = distance(begin, end);
268  if(nb_element == 0)
269  throw ExceptionOutOfRange(
270  QObject::tr("unable to compute quantile on a trace of size 0"));
271 
272 
273  std::size_t ieth_element = std::round((double)nb_element * quantile);
274  if(ieth_element > nb_element)
275  throw ExceptionOutOfRange(
276  QObject::tr("quantile value must be lower than 1"));
277 
278 
279  std::vector<DataPoint> data(begin, end);
280  std::nth_element(
281  data.begin(),
282  data.begin() + ieth_element,
283  data.end(),
284  [](const DataPoint &a, const DataPoint &b) { return a.y < b.y; });
285  return data[ieth_element].y;
286 }
287 
288 double
289 medianYTrace(std::vector<DataPoint>::const_iterator begin,
290  std::vector<DataPoint>::const_iterator end)
291 {
292  std::size_t nb_element = distance(begin, end);
293  if(nb_element == 0)
294  throw ExceptionOutOfRange(
295  QObject::tr("unable to compute median on a trace of size 0"));
296 
297  std::vector<DataPoint> data(begin, end);
298  std::nth_element(
299  data.begin(),
300  data.begin() + data.size() / 2,
301  data.end(),
302  [](const DataPoint &a, const DataPoint &b) { return a.y < b.y; });
303  return data[data.size() / 2].y;
304 }
305 
306 double
307 areaTrace(std::vector<DataPoint>::const_iterator begin,
308  std::vector<DataPoint>::const_iterator end)
309 {
310 
311  if(begin == end)
312  return 0;
313  auto previous = begin;
314  auto next = begin + 1;
315  double area = 0;
316  while(next != end)
317  {
318  area += ((next->x - previous->x) * (previous->y + next->y)) / (double)2;
319  previous++;
320  next++;
321  }
322  return area;
323 }
324 
325 
326 double
327 areaTraceMinusBase(std::vector<DataPoint>::const_iterator begin,
328  std::vector<DataPoint>::const_iterator end)
329 {
330 
331  if(begin == end)
332  return 0;
333  auto previous = begin;
334  auto next = begin + 1;
335  auto last = next;
336  double area = 0;
337  while(next != end)
338  {
339  last = next;
340  area += ((next->x - previous->x) * (previous->y + next->y)) / (double)2;
341  previous++;
342  next++;
343  }
344  if(area > 0)
345  {
346  // remove base peak area
347  area -= (((last->y + begin->y) * (last->x - begin->x)) / 2);
348  if(area < 0)
349  return 0;
350  }
351  return area;
352 }
353 
354 
355 Trace
356 flooredLocalMaxima(std::vector<DataPoint>::const_iterator begin,
357  std::vector<DataPoint>::const_iterator end,
358  double y_floor)
359 {
360  Trace local_maxima_trace;
361 
362  Trace single_peak_trace;
363 
364  DataPoint previous_data_point;
365 
366  for(auto iter = begin; iter != end; ++iter)
367  {
368  DataPoint iterated_data_point(iter->x, iter->y);
369 
370  // qDebug().noquote() << "Current data point:"
371  //<< iterated_data_point.toString();
372 
373  if(iterated_data_point.y < y_floor)
374  {
375  // qDebug() << "under the floor";
376 
377  if(single_peak_trace.size())
378  {
379  // qDebug() << "There was a single peak trace cooking";
380 
381  local_maxima_trace.push_back(single_peak_trace.maxYDataPoint());
382 
383  // qDebug().noquote() << "pushed back local maximum point:"
384  //<< local_maxima_trace.back().toString();
385 
386  // Clean and set the context.
387  single_peak_trace.clear();
388 
389  previous_data_point = iterated_data_point;
390 
391  continue;
392  }
393  else
394  {
395  // qDebug() << "no single peak trace cooking";
396 
397  previous_data_point = iterated_data_point;
398 
399  continue;
400  }
401  }
402  else
403  {
404  // qDebug() << "over the floor";
405 
406  // The iterated value is greater than the y_floor value, so we need to
407  // handle it.
408 
409  if(iterated_data_point.y == previous_data_point.y)
410  {
411  // We are in a flat region, no need to change anything to the
412  // context, just skip the point.
413  continue;
414  }
415  else if(iterated_data_point.y > previous_data_point.y)
416  {
417  // qDebug().noquote() << "ascending in a peak";
418 
419  // The previously iterated y value was smaller than the presently
420  // iterated one, so we are ascending in a peak.
421 
422  // All we need to do is set the context.
423 
424  single_peak_trace.push_back(iterated_data_point);
425 
426  // qDebug().noquote() << "pushed back normal point:"
427  //<< single_peak_trace.back().toString();
428 
429  previous_data_point = iterated_data_point;
430 
431  continue;
432  }
433  else
434  {
435  // qDebug().noquote() << "started descending in a peak";
436 
437  // No, the currently iterated y value is less than the previously
438  // iterated value.
439 
440  single_peak_trace.push_back(iterated_data_point);
441 
442  // qDebug().noquote() << "pushed back normal point:"
443  //<< single_peak_trace.back().toString();
444 
445  previous_data_point = iterated_data_point;
446 
447  continue;
448  }
449  }
450  }
451  // End of
452  // for(auto iter = begin; iter != end; ++iter)
453 
454  // Attention, we might arrive here with a peak being created, we need to get
455  // its maximum if that peak is non-empty;
456 
457  if(single_peak_trace.size())
458  {
459 
460  local_maxima_trace.push_back(single_peak_trace.maxYDataPoint());
461 
462  // qDebug().noquote()
463  //<< "was cooking a peak: pushed back local maximum point:"
464  //<< local_maxima_trace.back().toString();
465  }
466 
467  return local_maxima_trace;
468 }
469 
470 
472 {
473 }
474 
475 
476 Trace::Trace(const std::vector<pappso_double> &xVector,
477  const std::vector<pappso_double> &yVector)
478 {
479  initialize(xVector, yVector);
480 }
481 
482 
484  const std::vector<std::pair<pappso_double, pappso_double>> &dataPoints)
485 {
486  reserve(dataPoints.size());
487 
488  for(auto &dataPoint : dataPoints)
489  {
490  push_back(DataPoint(dataPoint));
491  }
492 
493  sortX();
494  // std::sort(begin(), end(), [](const DataPoint &a, const DataPoint &b) {
495  // return (a.x < b.x);
496  //});
497 }
498 
499 
500 Trace::Trace(const std::vector<DataPoint> &dataPoints)
501  : std::vector<DataPoint>(dataPoints)
502 {
503  sortX();
504  // std::sort(begin(), end(), [](const DataPoint &a, const DataPoint &b) {
505  // return (a.x < b.x);
506  //});
507 }
508 
509 
510 Trace::Trace(const std::vector<DataPoint> &&dataPoints)
511  : std::vector<DataPoint>(std::move(dataPoints))
512 {
513  // This constructor used by the MassSpectrum && constructor.
514 
515  sortX();
516  // std::sort(begin(), end(), [](const DataPoint &a, const DataPoint &b) {
517  // return (a.x < b.x);
518  //});
519 }
520 
521 
522 Trace::Trace(const MapTrace &map_trace)
523 {
524  for(auto &&item : map_trace)
525  push_back(DataPoint(item.first, item.second));
526 
527  // No need to sort, maps are sorted by key (that is, x).
528 }
529 
530 Trace::Trace(const Trace &other) : std::vector<DataPoint>(other)
531 {
532 }
533 
534 
535 Trace::Trace(const Trace &&other)
536  : std::vector<DataPoint>(std::move(other))
537 {
538  // This constructor used by the MassSpectrum && constructor.
539 }
540 
541 
543 {
544  // Calls the destructor for each DataPoint object in the vector.
545  clear();
546 }
547 
548 
549 size_t
550 Trace::initialize(const std::vector<pappso_double> &xVector,
551  const std::vector<pappso_double> &yVector)
552 {
553  // Sanity check
554  if(xVector.size() != yVector.size())
555  throw ExceptionNotPossible(
556  "trace.cpp -- ERROR xVector and yVector must have the same size.");
557 
558  // We are initializing, not appending.
559  erase(begin(), end());
560 
561  for(std::size_t iter = 0; iter < xVector.size(); ++iter)
562  {
563  push_back(DataPoint(xVector.at(iter), yVector.at(iter)));
564  }
565 
566  sortX();
567  // std::sort(begin(), end(), [](const DataPoint &a, const DataPoint &b) {
568  // return (a.x < b.x);
569  //});
570 
571 #if 0
572  for(auto &item : *this)
573  {
574  std::cout << item.x << "-" << item.y;
575  }
576 #endif
577 
578  return size();
579 }
580 
581 
582 size_t
583 Trace::initialize(const std::map<pappso_double, pappso_double> &map)
584 {
585 
586  // We are initializing, not appending.
587  erase(begin(), end());
588 
589  for(auto &&item : map)
590  {
591  push_back(DataPoint(item.first, item.second));
592  }
593 
594  // No need to sort, maps are sorted by key (that is, x).
595 
596  return size();
597 }
598 
599 
600 size_t
602 {
603  *this = other;
604 
605  return size();
606 }
607 
608 
609 size_t
610 Trace::append(const DataPoint &data_point)
611 {
612  push_back(data_point);
613 
614  return size();
615 }
616 
617 
618 Trace &
619 Trace::operator=(const Trace &other)
620 {
621  assign(other.begin(), other.end());
622 
623  return *this;
624 }
625 
626 
627 Trace &
629 {
630  vector<DataPoint>::operator=(std::move(other));
631  return *this;
632 }
633 
634 
635 TraceSPtr
637 {
638  return std::make_shared<Trace>(*this);
639 }
640 
641 
644 {
645  return std::make_shared<const Trace>(*this);
646 }
647 
648 
649 std::vector<pappso_double>
651 {
652  std::vector<pappso_double> values;
653 
654  for(auto &&dataPoint : *this)
655  {
656  values.push_back(dataPoint.x);
657  }
658 
659  return values;
660 }
661 
662 
663 std::vector<pappso_double>
665 {
666  std::vector<pappso_double> values;
667 
668  for(auto &&dataPoint : *this)
669  {
670  values.push_back(dataPoint.y);
671  }
672 
673  return values;
674 }
675 
676 
677 std::map<pappso_double, pappso_double>
679 {
680  std::map<pappso_double, pappso_double> map;
681 
682  std::pair<std::map<pappso_double, pappso_double>::iterator, bool> ret;
683 
684  for(auto &&dataPoint : *this)
685  {
686  ret = map.insert(
687  std::pair<pappso_double, pappso_double>(dataPoint.x, dataPoint.y));
688 
689  if(ret.second == false)
690  {
691  qDebug() << __FILE__ << "@" << __LINE__ << __FUNCTION__ << "()"
692  << "It is odd that the Trace contains multiple same keys.";
693 
694  // No insertion, then increment the y value.
695  ret.first->second += dataPoint.y;
696  }
697  }
698 
699  return map;
700 }
701 
702 
703 // const DataPoint &
704 // Trace::dataPointWithX(pappso_double value) const
705 //{
706 // auto iterator =
707 // std::find_if(begin(), end(), [value](const DataPoint &dataPoint) {
708 // return (dataPoint.x == value);
709 //});
710 
711 // if(iterator != end())
712 //{
713 //// The returned data point is valid.
714 // return *iterator;
715 //}
716 // else
717 //{
718 //// The returned data point is invalid because it is not initialized.
719 // return DataPoint();
720 //}
721 //}
722 
723 
724 std::vector<DataPoint>::iterator
726 {
727  auto iterator =
728  std::find_if(begin(), end(), [value](const DataPoint &dataPoint) {
729  return (dataPoint.x == value);
730  });
731 
732  return iterator;
733 }
734 
735 
736 std::vector<DataPoint>::const_iterator
738 {
739  auto iterator =
740  std::find_if(begin(), end(), [value](const DataPoint &dataPoint) {
741  return (dataPoint.x == value);
742  });
743 
744  return iterator;
745 }
746 
747 
748 std::size_t
750 {
751  std::vector<DataPoint>::const_iterator iterator =
753 
754  if(iterator != end())
755  return std::distance(begin(), iterator);
756 
757  return std::numeric_limits<std::size_t>::max();
758 }
759 
760 
761 DataPoint
762 Trace::containsX(pappso_double value, PrecisionPtr precision_p) const
763 {
764  // std::cout << std::setprecision(10) << "getting value: " << value
765  //<< " and precision: " << precision_p->getNominal() << std::endl;
766 
767  pappso_double delta = precision_p->delta(value);
768 
769  double left_most = value - delta;
770  double right_most = value + delta;
771 
772  // std::cout << std::setprecision(10) << "delta: " << delta
773  //<< " left_most: " << left_most << " right_most: " << right_most
774  //<< std::endl;
775 
776  auto iterator =
777  std::find_if(begin(),
778  end(),
779  [value, precision_p, delta, left_most, right_most](
780  const DataPoint &data_point) {
781  if(precision_p)
782  {
783 
784  // FIXME: unbelievable behaviour: when building in
785  // release mode this code, under i386 (but not x86_64),
786  // this code fails if the following cout statement is
787  // missing.
788 
789  // std::cout << std::setprecision(10)
790  //<< "Testing data_point.x: " << data_point.x
791  //<< std::endl;
792 
793  // For this reason I had to deactivate the related tests
794  // for i386 in tests/test_trace.cpp
795 
796  double diff_to_left_most = data_point.x - left_most;
797  double diff_to_right_most = data_point.x - right_most;
798 
799  // std::cout << std::setprecision(10)
800  //<< "diff_to_left_most: " << diff_to_left_most
801  //<< " diff_to_right_most: " << diff_to_right_most <<
802  // std::endl;
803 
804  // if(diff_to_left_most > 0)
805  //{
806  // std::cout << std::setprecision(10)
807  //<< " point is right of left_most: " <<
808  // diff_to_left_most
809  //<< std::endl;
810  //}
811  // if(diff_to_left_most < 0)
812  //{
813  // std::cout << std::setprecision(10)
814  //<< "point is left of left_most: " << diff_to_left_most
815  //<< std::endl;
816  //}
817  // if(!diff_to_left_most)
818  //{
819  // std::cout << std::setprecision(10)
820  //<< "point is spot on left_most: " << diff_to_left_most
821  //<< std::endl;
822  //}
823 
824  // if(diff_to_right_most > 0)
825  //{
826  // std::cout << std::setprecision(10)
827  //<< "point is right of right_most: " <<
828  // diff_to_right_most
829  //<< std::endl;
830  //}
831  // if(diff_to_right_most < 0)
832  //{
833  // std::cout << std::setprecision(10)
834  //<< "point is left or of right_most: "
835  //<< diff_to_right_most << std::endl;
836  //}
837  // if(!diff_to_right_most)
838  //{
839  // std::cout << std::setprecision(10)
840  //<< "point is spot on right_most: " <<
841  // diff_to_right_most
842  //<< std::endl;
843  //}
844 
845  if(diff_to_left_most >= 0 && diff_to_right_most <= 0)
846  {
847  // std::cout << "The point is inside the range,
848  // should return true."
849  //<< std::endl;
850  return true;
851  }
852  else
853  {
854  // std::cout
855  //<< "The point is outside the range, should return
856  // false."
857  //<< std::endl;
858  return false;
859  }
860  }
861  else
862  {
863  return (data_point.x == value);
864  }
865  });
866 
867  if(iterator != end())
868  {
869  // The returned data point is valid.
870  return *iterator;
871  }
872  else
873  {
874  // The returned data point is invalid because it is not initialized.
875  return DataPoint();
876  }
877 }
878 
879 
880 const DataPoint &
882 {
883  auto dataPoint = std::min_element(
884  begin(), end(), [](const DataPoint &a, const DataPoint &b) {
885  return (a.y < b.y);
886  });
887 
888  if(dataPoint == end())
889  {
890  throw ExceptionOutOfRange(
891  QObject::tr("unable to get min peak intensity on spectrum size %1")
892  .arg(size()));
893  }
894 
895  return (*dataPoint);
896 }
897 
898 
899 const DataPoint &
901 {
902  auto dataPoint = std::max_element(
903  begin(), end(), [](const DataPoint &a, const DataPoint &b) {
904  return (a.y < b.y);
905  });
906 
907  if(dataPoint == end())
908  {
909  throw ExceptionOutOfRange(
910  QObject::tr("unable to get max peak intensity on spectrum size %1")
911  .arg(size()));
912  }
913 
914  return (*dataPoint);
915 }
916 
917 
919 Trace::minY() const
920 {
921  return minYDataPoint().y;
922 }
923 
924 
926 Trace::maxY() const
927 {
928  return maxYDataPoint().y;
929 }
930 
931 
933 Trace::sumY() const
934 {
935  // double sum = 0;
936 
937  // for(auto &&dp : m_dataPoints)
938  // sum += dp.y;
939 
940  // qDebug() << __FILE__ << "@" << __LINE__ << __FUNCTION__ << " ()"
941  //<< "Returning sum/tic:" << sum;
942 
943  // return sum;
944 
945  return std::accumulate(begin(),
946  end(),
947  (double)0,
948  [](pappso_double sum, const DataPoint &dataPoint) {
949  return (sum + dataPoint.y);
950  });
951 }
952 
953 
955 Trace::sumY(double mzStart, double mzEnd) const
956 {
957  auto begin_it = findFirstEqualOrGreaterX(this->begin(), this->end(), mzStart);
958  auto end_it = findFirstGreaterX(begin_it, this->end(), mzEnd);
959 
960  return sumYTrace(begin_it, end_it, 0);
961 }
962 
963 
965 Trace::maxY(double mzStart, double mzEnd) const
966 {
967  std::vector<DataPoint>::const_iterator begin_it =
968  findFirstEqualOrGreaterX(this->begin(), this->end(), mzStart);
969 
970  double max_y = 0;
971 
972  while(begin_it != findFirstGreaterX(begin_it, this->end(), mzEnd))
973  {
974  if(begin_it->y > max_y)
975  max_y = begin_it->y;
976  begin_it++;
977  }
978  return max_y;
979 }
980 
981 
982 void
984 {
985  std::sort(begin(), end(), [](const DataPoint &a, const DataPoint &b) {
986  return (a.x < b.x);
987  });
988 }
989 
990 void
992 {
993  std::sort(begin(), end(), [](const DataPoint &a, const DataPoint &b) {
994  return (a.y > b.y);
995  });
996 }
997 
998 void
1000 {
1001  auto last =
1002  std::unique(begin(), end(), [](const DataPoint &a, const DataPoint &b) {
1003  return (a.x == b.x);
1004  });
1005 
1006  erase(last, end());
1007 }
1008 
1009 
1010 QString
1012 {
1013  // Even if the spectrum is empty, we should return an empty string.
1014  QString text;
1015 
1016  for(auto &&dataPoint : *this)
1017  {
1018  text.append(QString("%1 %2\n")
1019  .arg(dataPoint.x, 0, 'f', 10)
1020  .arg(dataPoint.y, 0, 'f', 10));
1021  }
1022 
1023  return text;
1024 }
1025 
1026 
1027 Trace &
1029 {
1030  return filter.filter(*this);
1031 }
1032 
1033 } // namespace pappso
generic interface to apply a filter on a trace
virtual pappso_double delta(pappso_double value) const =0
A simple container of DataPoint instances.
Definition: trace.h:38
virtual Q_INVOKABLE Trace & operator=(const Trace &x)
Definition: trace.cpp:619
Q_INVOKABLE void unique()
Definition: trace.cpp:999
Q_INVOKABLE pappso_double maxY() const
Definition: trace.cpp:926
Q_INVOKABLE pappso_double sumY() const
Definition: trace.cpp:933
Q_INVOKABLE void sortY()
Definition: trace.cpp:991
Q_INVOKABLE const DataPoint & maxYDataPoint() const
Definition: trace.cpp:900
std::map< pappso_double, pappso_double > toMap() const
Definition: trace.cpp:678
Q_INVOKABLE std::vector< pappso_double > xValues() const
Definition: trace.cpp:650
Q_INVOKABLE void sortX()
Definition: trace.cpp:983
TraceCstSPtr makeTraceCstSPtr() const
Definition: trace.cpp:643
virtual Trace & filter(const FilterInterface &filter) final
apply a filter on this trace
Definition: trace.cpp:1028
DataPoint containsX(pappso_double value, PrecisionPtr precision_p=nullptr) const
Definition: trace.cpp:762
Q_INVOKABLE std::vector< pappso_double > yValues() const
Definition: trace.cpp:664
Q_INVOKABLE pappso_double minY() const
Definition: trace.cpp:919
virtual ~Trace()
Definition: trace.cpp:542
Q_INVOKABLE size_t initialize(const std::vector< pappso_double > &xVector, const std::vector< pappso_double > &yVector)
Definition: trace.cpp:550
Q_INVOKABLE size_t append(const DataPoint &data_point)
Definition: trace.cpp:610
std::size_t dataPointIndexWithX(pappso_double value) const
Definition: trace.cpp:749
std::vector< DataPoint >::const_iterator dataPointCstIteratorWithX(pappso_double value) const
find datapoint with exactly x value
Definition: trace.cpp:737
std::vector< DataPoint >::iterator dataPointIteratorWithX(pappso_double value)
Definition: trace.cpp:725
Q_INVOKABLE const DataPoint & minYDataPoint() const
Definition: trace.cpp:881
TraceSPtr makeTraceSPtr() const
Definition: trace.cpp:636
Q_INVOKABLE Trace()
Definition: trace.cpp:471
Q_INVOKABLE QString toString() const
Definition: trace.cpp:1011
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...
Definition: aa.cpp:39
std::shared_ptr< const Trace > TraceCstSPtr
Definition: trace.h:26
std::vector< DataPoint >::iterator findDifferentYvalue(std::vector< DataPoint >::iterator begin, std::vector< DataPoint >::iterator end, const double &y_value)
find the first element in which Y is different of value
Definition: trace.cpp:125
std::vector< DataPoint >::iterator findFirstEqualOrGreaterX(std::vector< DataPoint >::iterator begin, std::vector< DataPoint >::iterator end, const double &value)
find the first element in which X is equal or greater than the value searched important : it implies ...
Definition: trace.cpp:69
std::vector< DataPoint >::iterator findFirstGreaterX(std::vector< DataPoint >::iterator begin, std::vector< DataPoint >::iterator end, const double &value)
find the first element in which X is greater than the value searched important : it implies that Trac...
Definition: trace.cpp:97
QDataStream & operator<<(QDataStream &outstream, const MassSpectrum &massSpectrum)
QDataStream & operator>>(QDataStream &instream, MassSpectrum &massSpectrum)
std::vector< DataPoint >::const_iterator moveLowerYLeftDataPoint(const Trace &trace, std::vector< DataPoint >::const_iterator begin)
Move left to the lower value.
Definition: trace.cpp:221
std::vector< DataPoint >::const_iterator maxYDataPoint(std::vector< DataPoint >::const_iterator begin, std::vector< DataPoint >::const_iterator end)
Definition: trace.cpp:178
double medianYTrace(std::vector< DataPoint >::const_iterator begin, std::vector< DataPoint >::const_iterator end)
calculate the median of y value of a trace
Definition: trace.cpp:289
double areaTrace(std::vector< DataPoint >::const_iterator begin, std::vector< DataPoint >::const_iterator end)
calculate the area of a trace
Definition: trace.cpp:307
std::shared_ptr< Trace > TraceSPtr
Definition: trace.h:25
double pappso_double
A type definition for doubles.
Definition: types.h:49
double areaTraceMinusBase(std::vector< DataPoint >::const_iterator begin, std::vector< DataPoint >::const_iterator end)
Definition: trace.cpp:327
double meanYTrace(std::vector< DataPoint >::const_iterator begin, std::vector< DataPoint >::const_iterator end)
calculate the mean of y value of a trace
Definition: trace.cpp:251
std::vector< DataPoint >::const_iterator moveLowerYRigthDataPoint(const Trace &trace, std::vector< DataPoint >::const_iterator begin)
Move right to the lower value.
Definition: trace.cpp:203
double sumYTrace(std::vector< DataPoint >::const_iterator begin, std::vector< DataPoint >::const_iterator end, double init)
calculate the sum of y value of a trace
Definition: trace.cpp:242
std::vector< DataPoint >::const_iterator minYDataPoint(std::vector< DataPoint >::const_iterator begin, std::vector< DataPoint >::const_iterator end)
Definition: trace.cpp:156
double quantileYTrace(std::vector< DataPoint >::const_iterator begin, std::vector< DataPoint >::const_iterator end, double quantile)
calculate the quantile of y value of a trace
Definition: trace.cpp:263
@ sum
sum of intensities
Trace flooredLocalMaxima(std::vector< DataPoint >::const_iterator begin, std::vector< DataPoint >::const_iterator end, double y_floor)
Definition: trace.cpp:356
pappso_double x
Definition: datapoint.h:23
pappso_double y
Definition: datapoint.h:24
int traceMetaTypeId
Definition: trace.cpp:25
int tracePtrMetaTypeId
Definition: trace.cpp:26