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