libpappsomspp
Library for mass spectrometry
Loading...
Searching...
No Matches
mzintegrationparams.cpp
Go to the documentation of this file.
1/* BEGIN software license
2 *
3 * msXpertSuite - mass spectrometry software suite
4 * -----------------------------------------------
5 * Copyright(C) 2009,...,2018 Filippo Rusconi
6 *
7 * http://www.msxpertsuite.org
8 *
9 * This file is part of the msXpertSuite project.
10 *
11 * The msXpertSuite project is the successor of the massXpert project. This
12 * project now includes various independent modules:
13 *
14 * - massXpert, model polymer chemistries and simulate mass spectrometric data;
15 * - mineXpert, a powerful TIC chromatogram/mass spectrum viewer/miner;
16 *
17 * This program is free software: you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation, either version 3 of the License, or
20 * (at your option) any later version.
21 *
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * You should have received a copy of the GNU General Public License
28 * along with this program. If not, see <http://www.gnu.org/licenses/>.
29 *
30 * END software license
31 */
32
33/////////////////////// StdLib includes
34#include <cmath>
35#include <map>
36
37/////////////////////// Qt includes
38#include <QDateTime>
39#include <QDebug>
40#include <QFile>
41#include <QString>
42#include <QJSEngine>
43
44/////////////////////// pappsomspp includes
47
48/////////////////////// Local includes
50
51/*
52int mzIntegrationParamsMetaTypeId =
53 qRegisterMetaType<pappso::MzIntegrationParams>("pappso::MzIntegrationParams");
54int mzIntegrationParamsPtrMetaTypeId =
55 qRegisterMetaType<pappso::MzIntegrationParams *>("pappso::MzIntegrationParams
56*");*/
57
58namespace pappso
59{
60
61//! Map relating the BinningType to a textual representation
62std::map<MzIntegrationParams::BinningType, QString> binningTypeMap{
66
68getBinningTypeFromString(const QString &text)
69{
70 std::map<MzIntegrationParams::MzIntegrationParams::BinningType,
71 QString>::const_iterator the_iterator_const =
72 std::find_if(
73 binningTypeMap.begin(),
74 binningTypeMap.end(),
75 [text](const std::pair<MzIntegrationParams::BinningType, QString> &pair) {
76 return pair.second == text;
77 });
78
79 if(the_iterator_const != binningTypeMap.end())
80 return the_iterator_const->first;
81
83}
84
85MzIntegrationParams::MzIntegrationParams(QObject *parent): QObject(parent)
86{
87}
88
89MzIntegrationParams::MzIntegrationParams(const QString &text, QObject *parent)
90 : QObject(parent)
91{
92 initialize(text);
93}
94
96 double min_mz,
97 double max_mz,
99 pappso::PrecisionPtr bin_size_model,
100 int bin_size_divisor,
101 int decimal_places,
102 bool remove_zero_val_data_points,
103 QObject *parent)
104 : QObject(parent),
105 m_smallestMz(min_mz),
106 m_greatestMz(max_mz),
107 m_binningType(binning_type),
108 m_binSizeModel(bin_size_model),
109 m_binSizeDivisor(bin_size_divisor),
110 m_decimalPlaces(decimal_places),
111 m_removeZeroValDataPoints(remove_zero_val_data_points)
112{
113 if(m_binSizeModel == nullptr)
115
116 // qDebug() << "MetaObject?" << this->metaObject()->className();
117}
118
122
124MzIntegrationParams::clone(QObject *parent) const
125{
126 MzIntegrationParams *mz_integration_params_p =
134 parent);
135
136 return mz_integration_params_p;
137}
138
141{
142 // qDebug() << "Initializing MzIntegrationParams using text:" << text;
143
145
146 if(text.isEmpty())
147 return initialization_result;
148
149 reset();
150
151 // Expected text: "Smallest (first) m/z:294.725158\nGreatest (last)
152 // m/z:2055.002453\nDecimal places:-1\nBinning type:2\nBin size model:0.05
153 // dalton\nBin size divisor:1\nRemove 0-val data points:1\n"
154
155 // In order to consider that the parameters were correctly read, we need
156 // some of the members to effectively be set from the settings values.
157
158 bool binning_type_set = false;
159 bool decimal_places_set = false;
160 bool bin_size_model_set = false;
161 bool bin_size_divisor_set = false;
162 bool remove_zero_data_points_set = false;
163
164 QStringList string_list = text.split("\n");
165
166 for(int iter = 0; iter < string_list.size(); ++iter)
167 {
168 QString iter_string = string_list.at(iter);
169
170 // qDebug() << "Iterating in string:" << iter_string;
171
172 if(iter_string.contains("Binning type:"))
173 {
175 getBinningTypeFromString(iter_string.split(':').last()));
176 binning_type_set = true;
177 }
178 else if(iter_string.contains("Bin size model:"))
179 {
181 PrecisionFactory::fromString(iter_string.split(':').last()));
182 bin_size_model_set = true;
183 }
184 else if(iter_string.contains("Bin size divisor:"))
185 {
186 setBinSizeDivisor(iter_string.split(':').last().toInt());
187 bin_size_divisor_set = true;
188 }
189 else if(iter_string.contains("Decimal places:"))
190 {
191 setDecimalPlaces(iter_string.split(':').last().toInt());
192 decimal_places_set = true;
193 }
194 else if(iter_string.contains("Remove 0-val data points:"))
195 {
196 setRemoveZeroValDataPoints(iter_string.split(':').last().toInt());
197 remove_zero_data_points_set = true;
198 }
199 }
200
201 // qDebug() << "At this point the initialization is done and this"
202 // " MzIntegrationParams instance is: "
203 // << toString();
204
205 if(binning_type_set)
206 initialization_result |= InitializationResult::BINNING_TYPE;
207 if(bin_size_model_set)
208 initialization_result |= InitializationResult::BIN_SIZE_MODEL;
209 if(bin_size_divisor_set)
210 initialization_result |= InitializationResult::BIN_SIZE_DIVISOR;
211 if(decimal_places_set)
212 initialization_result |= InitializationResult::DECIMAL_PLACES;
213
214 if(remove_zero_data_points_set)
215 initialization_result |= InitializationResult::REMOVE_ZERO_DATA_POINTS;
216
217 return initialization_result;
218}
219
220void
222 double max_mz,
224 pappso::PrecisionPtr bin_size_model,
225 int bin_size_divisor,
226 int decimal_places,
227 bool remove_zero_val_data_points,
228 QObject *parent)
229{
230 setSmallestMz(min_mz);
231 setGreatestMz(max_mz);
232 setBinningType(binning_type);
233 setBinSizeModel(bin_size_model);
234 setBinSizeDivisor(bin_size_divisor);
235 setDecimalPlaces(decimal_places);
236 setRemoveZeroValDataPoints(remove_zero_val_data_points);
237
238 setParent(parent);
239}
240
241void
255
256// For use in JavaScript.
257void
259 QObject *parent)
260{
261 Q_ASSERT(other_p != nullptr);
262 initialize(*other_p, parent);
263}
264
265// Initialize this MzIntegrationParams using other but only for members that
266// were effectively set upon reading from a text string (see initialize
267// (QString)).
268void
270 InitializationResult initialization_results)
271{
272 if(static_cast<bool>(
273 initialization_results &
276
277 if(static_cast<bool>(
278 initialization_results &
281
282 if(static_cast<bool>(
283 initialization_results &
286
287 if(static_cast<bool>(
288 initialization_results &
291}
292
293void
295{
296 if(m_smallestMz != value)
297 m_smallestMz = value;
298
299 emit smallestMzChanged();
300}
301
302void
304{
305 if(value == m_smallestMz)
306 return;
307
308 m_smallestMz = value;
309 emit smallestMzChanged();
310}
311
312double
317
318void
320{
321 if(m_greatestMz == value)
322 return;
323
324 m_greatestMz = value;
325 emit greatestMzChanged();
326}
327
328void
330{
331 if(value > m_greatestMz)
332 {
333 m_greatestMz = value;
334 emit greatestMzChanged();
335 }
336}
337
338double
343
344// This m/z value is used to create bins phased with another previously
345// performed integration. Note that the lowerAnchor m/z value might be
346// smaller than the m_smallestMz value. See the bins creation function.
347void
349{
350 if(m_lowerAnchorMz == value)
351 return;
352
353 m_lowerAnchorMz = value;
355}
356
357void
359{
360 if(value == m_lowerAnchorMz)
361 return;
362
363 m_lowerAnchorMz = value;
365}
366
367double
372
373// This m/z value is used to create bins phased with another previously
374// performed integration. Note that the upperAnchor m/z value might be
375// greater than the m_greatestMz value. See the bins creation function.
376void
378{
379 if(m_upperAnchorMz == value)
380 return;
381
382 m_upperAnchorMz = value;
384}
385
386void
388{
389 if(value == m_upperAnchorMz)
390 return;
391
392 m_upperAnchorMz = value;
394}
395
396double
401
402void
403MzIntegrationParams::setMzValues(double smallest, double greatest)
404{
405 setSmallestMz(smallest);
406 setGreatestMz(greatest);
407}
408
409void
412{
413 if(m_binningType == binning_type)
414 return;
415
416 m_binningType = binning_type;
417 emit binningTypeChanged();
418}
419
425
426int
431
432void
434{
435 if(m_binSizeModel == bin_size_model_p)
436 return;
437
438 m_binSizeModel = bin_size_model_p;
439
440 if(m_binSizeModel == nullptr)
442
443 emit binSizeModelChanged();
444}
445
451
452void
454{
455 if(m_binSizeDivisor == divisor)
456 return;
457
458 m_binSizeDivisor = divisor;
460}
461
462int
467
468void
470{
471 if(m_decimalPlaces == decimal_places)
472 return;
473
474 m_decimalPlaces = decimal_places;
476}
477
478void
480{
481 if(m_removeZeroValDataPoints == removeOrNot)
482 return;
483
484 m_removeZeroValDataPoints = removeOrNot;
486}
487
488bool
493
494//! Reset the instance to default values.
495void
497{
498 // Each function handles the emission of the corresponding changed
499 // notification.
500 setSmallestMz(std::numeric_limits<double>::max());
501 setGreatestMz(std::numeric_limits<double>::min());
507}
508
509bool
511{
512 int errors = 0;
513
515 {
516 // qDebug() << "m_smallestMz:" << m_smallestMz;
517 // qDebug() << "smallest is max:" << (m_smallestMz ==
518 // std::numeric_limits<double>::max());
519 errors += (m_smallestMz == std::numeric_limits<double>::max() ? 1 : 0);
520
521 // qDebug() << "m_greatestMz:" << m_greatestMz;
522 // qDebug() << "greatest is min:" << (m_greatestMz ==
523 // std::numeric_limits<double>::min());
524 errors += (m_greatestMz == std::numeric_limits<double>::min() ? 1 : 0);
525 }
526
527 if(errors)
528 {
529 qCritical() << "The m/z integration parameters are invalid.";
530 }
531
532 return !errors;
533}
534
535bool
537{
538 return (m_smallestMz < std::numeric_limits<double>::max()) &&
539 (m_greatestMz >= std::numeric_limits<double>::min());
540}
541
542std::vector<double>
544{
545 // qDebug() << "mp_precision:" << mp_precision->toString();
546
547 std::vector<double> bins;
548
550 {
551 // If no binning is to be performed, fine.
552 return bins;
553 }
555 {
556 // Use only data in the MzIntegrationParams member data.
557 return createArbitraryBins();
558 }
560 {
561 qFatal() << "Programming error. "
562 "Please use the createBins(pappso::MassSpectrumCstSPtr "
563 "mass_spectrum_csp) overload.";
564 }
565
566 return bins;
567}
568
569std::vector<double>
571{
572 // qDebug();
573
574 std::vector<double> bins;
575
577 {
578 // If no binning is to be performed, fine.
579 return bins;
580 }
582 {
583 // Use only data in the MzIntegrationParams member data.
584 return createArbitraryBins();
585 }
587 {
588 // qDebug();
589
590 // Use the first spectrum to perform the data-based bins
591
592 return createDataBasedBins(mass_spectrum_csp);
593 }
594
595 return bins;
596}
597
598std::vector<double>
600{
601 // Now starts the tricky stuff. Depending on the binning size model, we need
602 // to take diverse actions.
603
604 if(!isValid())
605 qFatal() << "Programming error. The MzIntegrationParams::BinningLogic is "
606 "not valid, cannot "
607 "create bins.";
608
609 // qDebug() << "Binning logic:" << toString();
610
611 double min_mz = m_smallestMz;
612 double max_mz = m_greatestMz;
613
614 qDebug() << qSetRealNumberPrecision(6) << "The smallest and greatest m/z values:" << m_smallestMz
615 << "-" << m_greatestMz;
616
617 // Compute the number of decimals required to faithfully account for the
618 // precision needed to represent the binned data. We do this by computing
619 // some sort of bin size and checking how many decimals we need to described it.
620
621 // We cannot have a smallest m/z that is 0 because that impairs the computation of the
622 // bins (see below). In case the m_smallestMz value is 0 we craft one temporary value
623 // by computing half of the range:
624
625 // We will need to account for the bin size divisor, that is set to 6 as the
626 // default because that is the empirical observation that it gives the most
627 // nicely shaped peaks.
628 Q_ASSERT(m_binSizeDivisor >= 1);
629
630 double bin_size;
631 double smallest_bin_size;
632
633 double half_way_mz = 0;
634
635 if(!m_smallestMz)
636 {
637 half_way_mz = (m_greatestMz - m_smallestMz) / 2;
638
639 qDebug() << " Target min_mz:" << min_mz << "and max_mz:" << max_mz
640 << "half_way_mz:" << half_way_mz;
641 bin_size = m_binSizeModel->delta(half_way_mz) / m_binSizeDivisor;
642 smallest_bin_size = bin_size;
643 }
644 else
645 {
646 bin_size = m_binSizeModel->delta(m_smallestMz) / m_binSizeDivisor;
647 smallest_bin_size = bin_size;
648 }
649
650 qDebug() << qSetRealNumberPrecision(6) << "The bin size was computed to be" << bin_size;
651
652 // Only compute the decimal places if they were not configured already.
653 if(m_decimalPlaces == -1)
654 {
655 // qDebug() << "Now checking how many decimal places are needed.";
656
657 // We want as many decimal places as there are 0s between the integral
658 // part of the double and the first non-0 cipher. For example, if
659 // binSize is 0.004, zero decimals is 2 and m_decimalPlaces is set to 3,
660 // because we want decimals up to 4 included.
661
663
664 qDebug() << "With binSize" << bin_size
665 << " m_decimalPlaces was computed to be:" << m_decimalPlaces;
666 }
667
668 qDebug() << "m_decimalPlaces: " << m_decimalPlaces;
669
670 // Now that we have computed the decimal places, we can set the multiplier
671 // value that is used to computed the rounded values.
672
673 double multiplier = std::pow(10.0, m_decimalPlaces);
674
675 // Now that we have defined the value of m_decimalPlaces, let's use that
676 // value.
677 double first_mz = Utils::roundValueToDecimalPlaces(min_mz, m_decimalPlaces, /*round_up*/ false);
678 double last_mz = Utils::roundValueToDecimalPlaces(max_mz, m_decimalPlaces, /*round_up*/ true);
679
680 qDebug() << qSetRealNumberPrecision(10)
681 << "After having accounted for the decimals, new min/max values:"
682 << "Very first data point to start from:" << first_mz
683 << "Very last data point to reach : " << last_mz
684 << "Lower anchor m/z:" << m_lowerAnchorMz << "Upper anchor m/z:" << m_upperAnchorMz;
685
686 // Instantiate the vector of mz double_s that we'll feed with the bins.
687
688 std::vector<double> bins;
689 double previous_mz_bin;
690 double current_mz;
691
692 // There is a gotcha here: if the user has set the m_lowerAnchorMz value,
693 // then that means that we want to start phasing the bins at that value.
694 if(m_lowerAnchorMz != std::numeric_limits<double>::max())
695 {
696 qDebug() << qSetRealNumberPrecision(6) << "A lower anchor was set at" << m_lowerAnchorMz;
697
698 double lower_anchor_mz = std::round(m_lowerAnchorMz * multiplier + 1e-9) / multiplier;
699
700 qDebug() << qSetRealNumberPrecision(6)
701 << "After decimals accounting, that lower anchor becomes:" << lower_anchor_mz;
702
703
704 double reverse_bin_creation_start_mz;
705 double reverse_bin_creation_stop_mz;
706
707 // There are two situations:
708
709 if(lower_anchor_mz < first_mz)
710 {
711 qDebug() << "Lower anchor m/z is smaller than min_mz.";
712
713 // This is the typical situation where the user just enters 0.0 as the
714 // lower anchor and in fact the mass data have m_smallestMz much greater
715 // than 0.0, say 300.00, for example. It is NOT possible that the first
716 // m/z value in the range be 0.0 because that impairs the calculation of the bins
717 // (see below).
718
719 // We thus need to craft the first bins in reverse from first_mz to
720 // lower anchor.
721
722 reverse_bin_creation_start_mz = first_mz;
723 reverse_bin_creation_stop_mz = lower_anchor_mz;
724
725 // When we will resume the computation of the bins later
726 // we'll start first_mz ---> last_mz;
727 // first_mz = first_mz;
728 }
729 else
730 {
731 // That is, lower_anchor_mz >= first_mz
732
733 qDebug() << "Lower anchor m/z is greater than min_mz.";
734
735 reverse_bin_creation_start_mz = lower_anchor_mz;
736 reverse_bin_creation_stop_mz = first_mz;
737
738 // When we will resume the computation of the bins later
739 // we'll start first_mz ---> last_mz;
740 first_mz = lower_anchor_mz;
741 }
742
743 QList<double> prepended_bins;
744
745 // Seed the first m/z value at which to iterate.
746 previous_mz_bin = reverse_bin_creation_start_mz;
747
748 // At this point, reverse iterate the m/z values.
749 // Note how the starting point (reverse_bin_creation_start_mz)
750 // is not added to the bins, since right at the first iteration
751 // we compute an new value that is going to be prepended.
752
753 qDebug() << qSetRealNumberPrecision(6)
754 << "The reverse_bin_creation_stop_mz value:" << reverse_bin_creation_stop_mz;
755
756 // Due to the calculation of the bin size based on the resolution, the going down to
757 // reverse_bin_creation_stop_mz = 0 (if the user has set that value for left hand side
758 // of the m/z range), the progression is asymptotical. This means that testing
759 // while(previous_mz_bin - reverse_bin_creation_stop_mz >
760 // std::numeric_limits<double>::epsilon()) is not enough. So the limit for the
761 // while loop is that we reach a difference between current mz and previous mz
762 // that is lower than the bin size calculated for the smallest m/z.
763
764 while(previous_mz_bin - reverse_bin_creation_stop_mz > smallest_bin_size)
765 {
766 qDebug() << qSetRealNumberPrecision(6)
767 << "previous_mz_bin - reverse_bin_creation_stop_mz:"
768 << previous_mz_bin - reverse_bin_creation_stop_mz;
769
770 current_mz =
771 previous_mz_bin - (m_binSizeModel->delta(previous_mz_bin) / m_binSizeDivisor);
772
773 // Now apply on the obtained mz value the decimals that were
774 // either set or computed earlier.
775
776 double current_rounded_mz =
777 Utils::roundValueToDecimalPlaces(current_mz, m_decimalPlaces, /*round_up*/ false);
778
779 qDebug() << QString::asprintf(
780 "current_mz: %.6f and current_rounded_mz: %.6f and previous_mzBin: %.6f with delta: "
781 "%.6f\n ",
782 current_mz,
783 current_rounded_mz,
784 previous_mz_bin,
785 current_rounded_mz - previous_mz_bin);
786
787 // If rounding makes the new value identical to the previous one,
788 // then that means that we need to decrease roughness.
789
790 if(current_rounded_mz == previous_mz_bin)
791 {
793 // HERE
794 qDebug() << "It was required to increment decimal places to" << m_decimalPlaces;
795
796 current_rounded_mz =
797 Utils::roundValueToDecimalPlaces(current_mz, m_decimalPlaces, /*round_up*/ true);
798
799 // qDebug().noquote()
800 //<< "Had to increment decimal places by one while creating
801 // the bins " "in MzIntegrationParams::BinningType::ARBITRARY
802 // mode..";
803 }
804
805 // qDebug() << qSetRealNumberPrecision(6) << "Prepending bin"
806 // << current_rounded_mz;
807
808 prepended_bins.prepend(current_rounded_mz);
809
810 // Use the local_mz value for the storage of the previous mz bin.
811 previous_mz_bin = current_rounded_mz;
812 }
813 // End of
814 // while(previous_mz_bin > anchor_mz)
815
816 // Now set the bins to the vector that we'll use later.
817 bins.assign(prepended_bins.begin(), prepended_bins.end());
818
819 // #if 0
820
821 QString bins_with_delta = binsToStringWithDeltas(bins);
822
823 QString file_name =
824 "/tmp/prependedMassSpecBins.txt-at-" +
825 QDateTime::currentDateTime().toString("yyyyMMdd-HH-mm-ss");
826
827 // qDebug() << "Writing the list of prepended bins setup in the "
828 // "mass spectrum in file "
829 // << file_name;
830
831 Q_ASSERT(Utils::writeToFile(bins_with_delta, file_name));
832
833 // #endif
834 }
835 // End of
836 // if(m_lowerAnchorMz != std::numeric_limits<double>::max())
837
838 // At this point, either we have already set some bins because
839 // there was a lower anchor m/z value set or we start fresh.
840
841 // We have the same gotcha as for the lower anchor m/z value, but this
842 // time with the upper anchor m/z value. This case is easier than the former
843 // case because all we need is set a new last_mz value.
844
845 if(m_upperAnchorMz != std::numeric_limits<double>::min())
846 {
847 qDebug() << qSetRealNumberPrecision(6) << "An upper anchor was set at" << m_upperAnchorMz;
848
849 double upper_anchor_mz = Utils::roundValueToDecimalPlaces(m_upperAnchorMz,
851 /*round_up*/ true);
852
853 qDebug() << qSetRealNumberPrecision(6)
854 << "after decimals accounting, that upper anchor becomes:" << upper_anchor_mz;
855
856 if(upper_anchor_mz > last_mz)
857 {
858 qDebug() << "Since upper anchor m/z is greater than last_mz,"
859 "last_mz becomes upper_anchor_mz.";
860
861 last_mz = upper_anchor_mz;
862 }
863 }
864
865 // We may have set some bins already at the beginning of the
866 // bin list because m_lowerAnchorMz was set by the user.
867
868 // At this point we just continue the normal process. In the code above,
869 // first_mz was:
870
871 // 1. Unmodified if there was no lower anchor m/z
872 // 2. Set to m_lowAnchorMz if that was greater than m_smallestMz
873 // 3. Unmodified if m_lowAnchorMz was lower than m_smallestMz.
874
875
876 // Store that very first value for later use in the loop.
877 // The bins are nothing more than:
878 //
879 // 1. The first mz (that is the smallest mz value found in all the spectra
880 // 2. A sequence of mz values corresponding to that first mz value
881 // incremented by the bin size.
882
883 // Seed the root of the bin vector with the first mz value rounded above as
884 // requested. that first mz value is actually anchor_mz.
885 previous_mz_bin = first_mz;
886
887 // As said earlier, the first_mz has not been pushed in the bins vector. So
888 // we need to do that right away.
889 bins.push_back(previous_mz_bin);
890
891 qDebug() << qSetRealNumberPrecision(6) << "Pushed back first rounded mz:" << previous_mz_bin;
892
893 // Now continue adding mz values until we have reached the end of the
894 // spectrum, that is the max_mz value, as converted using the decimals to
895 // last_mz.
896
897 // debugCount value used below for debugging purposes.
898 // int debugCount = 0;
899
900 qDebug() << "Now starting the bin creation loop.";
901
902 while(previous_mz_bin <= last_mz)
903 {
904
905 // Calculate dynamically the precision delta according to the current mz
906 // value.
907
908 // double precision_delta = mp_precision->delta(previous_mz_bin);
909 // qDebug() << "precision_delta: " << precision_delta;
910
911 // In certain circumstances, the bin size is not enough to properly render
912 // hyper-high resolution data (like the theoretical isotopic cluster data
913 // generated in silico). In that case, the bin size, computed using the
914 // precision object, is divided by the m_binSizeDivisor, which normally is
915 // set to 6 as the default because that is the empirical observation that
916 // it gives the most nicely shaped peaks.
917
918 double delta = m_binSizeModel->delta(previous_mz_bin);
919 double manual_delta = previous_mz_bin / 40000;
920 double corrected_delta = delta / m_binSizeDivisor;
921
922 qDebug() << qSetRealNumberPrecision(50) << "The delta is:" << delta
923 << "and the corrected delta is:" << corrected_delta
924 << "while the manual delta is:" << manual_delta;
925
926 current_mz = previous_mz_bin + corrected_delta;
927
928 qDebug() << qSetRealNumberPrecision(6) << "previous mz bin: " << previous_mz_bin
929 << "and current mz: " << current_mz;
930
931 // Now apply on the obtained mz value the decimals that were either set
932 // or computed earlier.
933
934 double current_rounded_mz = Utils::roundValueToDecimalPlaces(current_mz,
936 /*round_up*/ true);
937
938 qDebug() << qSetRealNumberPrecision(50)
939 << "after rounding, current mz becomes: " << current_rounded_mz;
940
941 // If rounding makes the new value identical to the previous one, then
942 // that means that we need to decrease roughness.
943
944 if(current_rounded_mz == previous_mz_bin)
945 {
947
948 qDebug() << "It was required to increment decimal places to" << m_decimalPlaces;
949 current_rounded_mz = Utils::roundValueToDecimalPlaces(current_mz,
951 /*round_up*/ true);
952
953 qDebug().noquote() << "Because current rounded mz is equal to previous mz bin, we had to "
954 "increment decimal places by one while creating the bins "
955 "in MzIntegrationParams::BinningType::ARBITRARY mode.";
956 }
957
958 bins.push_back(current_rounded_mz);
959
960 qDebug() << qSetRealNumberPrecision(50)
961 << "Pushed back current rounded mz:" << current_rounded_mz;
962
963
964 // Use the local_mz value for the storage of the previous mz bin.
965 previous_mz_bin = current_rounded_mz;
966 }
967
968 // #if 0
969
970 QString bins_with_delta = binsToStringWithDeltas(bins);
971
972 QString file_name = "/tmp/massSpecArbitraryBins.txt-at-" +
973 QDateTime::currentDateTime().toString("yyyyMMdd-HH-mm-ss");
974
975 qDebug() << "Writing the list of bins setup in the mass spectrum in file " << file_name;
976
977 Q_ASSERT(Utils::writeToFile(bins_with_delta, file_name));
978
979 // #endif
980
981 qDebug() << "Prepared " << bins.size() << "arbitrary bins starting with mz" << bins.front()
982 << "ending with mz" << bins.back();
983
984 return bins;
985}
986
987std::vector<double>
989 pappso::MassSpectrumCstSPtr mass_spectrum_csp)
990{
991 // The mass spectrum passed as parameters has intrinsic bins in it. These bins
992 // are nothing else than the succession of m/z values in it.
993
994 // The very first thing to do is replicate that spectrum into a local copy
995 // of bins (simple double values), and during that step recompute the m/z
996 // value (x value) according to the decimals settings in this instance, if
997 // that is required (that is m_decimalPlaces != -1).
998
999 QList<double> bins;
1000 QList<double> deltas;
1001 QList<double> resolutions;
1002
1003 double left_mz_value = 0;
1004 double right_mz_value = 0;
1005 double mz_delta = 0;
1006 double resolution = 0;
1007
1008 // We need three bins to compute a number of values.
1009 if(mass_spectrum_csp->size() < 3)
1010 {
1011 std::vector<double> bins_vector(bins.constBegin(), bins.constEnd());
1012 return bins_vector;
1013 }
1014
1015 // Make sure the spectrum is sorted, as this function takes for granted
1016 // that the DataPoint instances are sorted in ascending x (== mz) value
1017 // order.
1018 pappso::MassSpectrum mass_spectrum_copy = *mass_spectrum_csp;
1019 mass_spectrum_copy.sortMz();
1020
1021 std::vector<pappso::DataPoint>::const_iterator iterator_const =
1022 mass_spectrum_copy.cbegin();
1023
1024 // We need to see the first value
1025 left_mz_value = iterator_const->x;
1026 if(m_decimalPlaces != -1)
1027 left_mz_value = ceil((left_mz_value * pow(10, m_decimalPlaces)) - 0.49) /
1028 pow(10, m_decimalPlaces);
1029
1030 qDebug() << qSetRealNumberPrecision(6)
1031 << "left_mz_value in the template mass spectrum:" << left_mz_value;
1032
1033 bins.append(left_mz_value);
1034 // No delta nor resolution can be computed for the first m/z
1035 // because their computation requires to compare the second m/z with
1036 // the first m/z, and in turn for all the remaining m/z values.
1037 deltas.append(0.0);
1038 resolutions.append(0.0);
1039
1040 // We used the first bin, go to the next!
1041 ++iterator_const;
1042 while(iterator_const != mass_spectrum_copy.cend())
1043 {
1044 right_mz_value = iterator_const->x;
1045
1046 qDebug() << qSetRealNumberPrecision(6)
1047 << "right_mz_value:" << right_mz_value;
1048
1049 if(m_decimalPlaces != -1)
1050 right_mz_value =
1051 ceil((right_mz_value * pow(10, m_decimalPlaces)) - 0.49) /
1052 pow(10, m_decimalPlaces);
1053
1054 bins.append(right_mz_value);
1055
1056 mz_delta = right_mz_value - left_mz_value;
1057 deltas.append(mz_delta);
1058 Q_ASSERT(mz_delta != 0.0);
1059
1060 resolution = right_mz_value / mz_delta;
1061 resolutions.append(resolution);
1062
1063 left_mz_value = right_mz_value;
1064 ++iterator_const;
1065 }
1066
1067 // At this point we have the bins that match those in the template mass
1068 // spectrum.
1069
1070 // #if 0
1071
1072 // We want to check them.
1073 std::vector<double> bins_vector(bins.constBegin(), bins.constEnd());
1074
1075 QString bins_with_delta = binsToStringWithDeltas(bins_vector);
1076
1077 QString file_name =
1078 "/tmp/massSpecDataBasedTemplateBinsWithDeltas.txt-at-" +
1079 QDateTime::currentDateTime().toString("yyyyMMdd-HH-mm-ss");
1080
1081 // qDebug() << "Writing the list of bins setup in the mass spectrum in file "
1082 // << file_name;
1083
1084 Q_ASSERT(Utils::writeToFile(bins_with_delta, file_name));
1085
1086 // #endif
1087
1088 // Done, we now have bins and deltas in between each bin and its following
1089 // bin.
1090
1091 // Now, there are specificities:
1092 //
1093 // If the user has set m_lowerAnchorMz and/or m_upperAnchorMz, then we
1094 // still have to work to do. That is because the user wants us to keep
1095 // the binning as found in the template mass spectrum passed as parameter, but
1096 // they also want that the m/z range of the bins be potentially larger, if
1097 // either m_lowerAnchorMz is smaller than the first bin value or if
1098 // m_upperAnchorMz is larger than the last bin value, or BOTH.
1099
1100 // The difficulty here is that we need to know the logic that has been used
1101 // in the first place for the generation of the bins in the template mass
1102 // spectrum.
1103
1104 // Some metrics:
1105
1106 // We could check if the bins have the same width all along the m/z range.
1107
1108 // Delta should be constant if the bins were calculated with dalton logic.
1109
1110 bool uniform_deltas = false;
1111 std::size_t deltas_count = deltas.size();
1112 // We cannot really take the first delta because it is 0.00000.
1113 double first_delta = deltas.at(1);
1114 double middle_delta = deltas.at(deltas_count / 2);
1115 double last_delta = deltas.at(deltas_count - 1);
1116
1117 if(first_delta == middle_delta && middle_delta == last_delta)
1118 uniform_deltas = true;
1119
1120 // qDebug() << "Deltas are uniform or not?" << uniform_deltas;
1121 // qDebug() << qSetRealNumberPrecision(6) << "First delta:" << first_delta
1122 // << "Middle delta:" << middle_delta << "Last delta:" << last_delta;
1123
1124 // Resolution should be constant if the bins were calculated with resolution
1125 // logic. Remember : Res = m/z / Delta m/z.
1126 bool uniform_resolutions = false;
1127 std::size_t resolutions_count = resolutions.size();
1128 // We cannot really take the first resolution because it is 0.00000.
1129 double first_resolution = resolutions.at(01);
1130 double middle_resolution = resolutions.at(resolutions_count / 2);
1131 double last_resolution = resolutions.at(resolutions_count - 1);
1132
1133 if(first_resolution == middle_resolution &&
1134 middle_resolution == last_resolution)
1135 uniform_resolutions = true;
1136
1137 // qDebug() << "Deltas are uniform or not?" << uniform_resolutions;
1138 // qDebug() << qSetRealNumberPrecision(6) << "First resolution:" <<
1139 // first_resolution
1140 // << "Middle resolution:" << middle_resolution << "Last resolution:"
1141 // << last_resolution;
1142
1143 // Now that we have the metric about the bins, we can start checking the other
1144 // parameters of the creation of bins:
1145 // There are two pairs of values in this instance:
1146 // m_smallestMz vs m_greatestMz
1147 // and
1148 // m_lowerAnchorMz vs m_upperAnchorMz
1149
1150 // Which one of these pairs should we account for, or both ?
1151
1152 // In theory, m_smallestMz and m_greatestMz were designed for the arbitrary
1153 // binning method, but it is imaginable that one would want to combine to and
1154 // existing spectrum a new spectrum that is larger than the existing
1155 // one, either on the left or on the right.
1156
1157 // Then, there is the other pair: m_lowerAnchorMz vs m_upperAnchorMz. In the
1158 // end what could be done is to take the smallest of all the values for the
1159 // left end of the integration bins and the greatest for the right end of the
1160 // integration bins.
1161
1162 double first_bin_mz = bins.first();
1163 double last_bin_mz = bins.last();
1164
1165 double smallest_mz = std::min(m_smallestMz, m_lowerAnchorMz);
1166 double greatest_mz = std::max(m_greatestMz, m_upperAnchorMz);
1167
1168 // qDebug() << qSetRealNumberPrecision(6) << "smallest_mz:" << smallest_mz
1169 // << "greatest_mz:" << greatest_mz;
1170
1171 // Now we can check if the [smallest_mz -- greatest_mz] m/z value range
1172 // extends farther on the left or on the right or both compared to the bins
1173 // range.
1174
1175 // Now that we have the real smallest and greatest m/z values that might be
1176 // std::max() and std::min() respectively if not set by the user. So all we
1177 // have to do is check them against the first and last bin values.
1178
1179 // The list of prepended bins on the left of the existing bins. By starting
1180 // with first_bin_mz, we maintain the phase with the bins in the mass spectrum
1181 // passed as parameter.
1182
1183 if(smallest_mz < first_bin_mz)
1184 {
1185 // qDebug() << "A starting m/z value is smaller than the first bin in the
1186 // "
1187 // "spectrum";
1188
1189 // We will have to craft bins to the left of first_bin_mz up to
1190 // smallest_mz. There are going to be different strategies depending on
1191 // what we discovered above. We will prepend the newly created bins to the
1192 // bins QList (thanks QList).
1193
1194 double bin_mz = first_bin_mz;
1195
1196 if(uniform_deltas)
1197 {
1198 // That is the simplest situation.
1199
1200 while(bin_mz > smallest_mz)
1201 {
1202 double new_bin_mz = bin_mz - first_delta;
1203 bins.prepend(new_bin_mz);
1204 bin_mz = new_bin_mz;
1205 }
1206 }
1207 else if(uniform_resolutions)
1208 {
1209 // Remember: Res = m/z / Delta m/z.
1210
1211 while(bin_mz > smallest_mz)
1212 {
1213 double new_bin_mz = bin_mz - (bin_mz / first_resolution);
1214 bins.prepend(new_bin_mz);
1215 bin_mz = new_bin_mz;
1216 }
1217 }
1218 }
1219
1220 // Now make sure we append any necessary bin (same logic as above).
1221 // By starting with last_bin_mz, we maintain the phase with the bins in the
1222 // mass spectrum passed as parameter.
1223
1224 if(greatest_mz > last_bin_mz)
1225 {
1226 // qDebug() << "A stopping m/z value is greater than the last bin in the "
1227 // "spectrum";
1228
1229 // Craft bins to the right of the bins m/z range, that is append
1230 // new bins.
1231
1232 double bin_mz = last_bin_mz;
1233
1234 if(uniform_deltas)
1235 {
1236 // That is the simplest situation.
1237
1238 while(bin_mz < greatest_mz)
1239 {
1240 double new_bin_mz = bin_mz + first_delta;
1241 bins.append(new_bin_mz);
1242 bin_mz = new_bin_mz;
1243 }
1244 }
1245 else if(uniform_resolutions)
1246 {
1247 // Remember: Res = m/z / Delta m/z.
1248
1249 while(bin_mz > smallest_mz)
1250 {
1251 double new_bin_mz = bin_mz + (bin_mz / first_resolution);
1252 bins.append(new_bin_mz);
1253 bin_mz = new_bin_mz;
1254 }
1255 }
1256 }
1257
1258 // At this point we should have bins over the full range of m/z values
1259 // required by the user and in phase with those transmitted via the
1260 // mass spectrum argument.
1261
1262 // Convert to std::vector<double> and return.
1263 std::vector<double> full_bins_vector(bins.constBegin(), bins.constEnd());
1264
1265#if 0
1266
1267 bins_with_delta = binsToStringWithDeltas(full_bins_vector);
1268
1269 file_name = "/tmp/massSpecDataBasedFullBinsWithDeltas.txt-at-" +
1270 QDateTime::currentDateTime().toString("yyyyMMdd-HH-mm-ss");
1271
1272 qDebug() << "Writing the list of bins setup in the mass spectrum in file "
1273 << file_name;
1274
1275 Q_ASSERT(Utils::writeToFile(bins_with_delta, file_name));
1276
1277#endif
1278
1279 // qDebug() << "Prepared " << bins.size() << "data-based bins starting with
1280 // mz"
1281 // << bins.front() << "ending with mz" << bins.back();
1282
1283 return full_bins_vector;
1284}
1285
1286std::vector<double>
1288 pappso::MassSpectrumCstSPtr mass_spectrum_csp)
1289{
1290 // The bins must be calculated using those in mass_spectrum_csp as a template.
1291
1292 // qDebug();
1293
1294 std::vector<double> bins;
1295
1296 if(mass_spectrum_csp->size() < 2)
1297 return bins;
1298
1299 // Make sure the spectrum is sorted, as this function takes for granted
1300 // that the DataPoint instances are sorted in ascending x (== mz) value
1301 // order.
1302 pappso::MassSpectrum sorted_mass_spectrum = *mass_spectrum_csp;
1303 sorted_mass_spectrum.sortMz();
1304
1305 double min_mz = m_smallestMz;
1306
1307 // qDebug() << "The min_mz:" << min_mz;
1308
1309 if(m_decimalPlaces != -1)
1310 min_mz = ceil((min_mz * pow(10, m_decimalPlaces)) - 0.49) /
1311 pow(10, m_decimalPlaces);
1312
1313 // Two values for the definition of a MassSpectrumBin.
1314
1315 // The first value of the mz range that defines the bin. This value is part
1316 // of the bin.
1317 double start_mz_in = min_mz;
1318
1319 // The second value of the mz range that defines the bin. This value is
1320 // *not* part of the bin.
1321 double end_mz_out;
1322
1323 std::vector<pappso::DataPoint>::const_iterator it =
1324 sorted_mass_spectrum.begin();
1325
1326 double prev_mz = it->x;
1327
1328 if(m_decimalPlaces != -1)
1329 prev_mz = ceil((prev_mz * pow(10, m_decimalPlaces)) - 0.49) /
1330 pow(10, m_decimalPlaces);
1331
1332 ++it;
1333
1334 while(it != sorted_mass_spectrum.end())
1335 {
1336 double next_mz = it->x;
1337
1338 if(m_decimalPlaces != -1)
1339 next_mz = ceil((next_mz * pow(10, m_decimalPlaces)) - 0.49) /
1340 pow(10, m_decimalPlaces);
1341
1342 double step = next_mz - prev_mz;
1343 end_mz_out = start_mz_in + step;
1344
1345 if(m_decimalPlaces != -1)
1346 end_mz_out = ceil((end_mz_out * pow(10, m_decimalPlaces)) - 0.49) /
1347 pow(10, m_decimalPlaces);
1348
1349 // The data point that is crafted has a 0 y-value. The binning must
1350 // indeed not create artificial intensity data.
1351
1352 // qDebug() << "Pushing back bin:" << start_mz_in << end_mz_out;
1353
1354 bins.push_back(start_mz_in);
1355
1356 // Prepare next bin
1357 start_mz_in = end_mz_out;
1358
1359 // Update prev_mz to be the current one for next iteration.
1360 prev_mz = next_mz;
1361
1362 // Now go to the next DataPoint instance.
1363 ++it;
1364 }
1365
1366#if 0
1367
1368 QString fileName = "/tmp/massSpecDataBasedBins.txt";
1369
1370 qDebug() << "Writing the list of bins setup in the "
1371 "mass spectrum in file "
1372 << fileName;
1373
1374 QFile file(fileName);
1375 file.open(QIODevice::WriteOnly);
1376
1377 QTextStream fileStream(&file);
1378
1379 for(auto &&bin : m_bins)
1380 fileStream << QString("[%1-%2]\n")
1381 .arg(bin.startMzIn, 0, 'f', 10)
1382 .arg(bin.endMzOut, 0, 'f', 10);
1383
1384 fileStream.flush();
1385 file.close();
1386
1387 qDebug() << "elements."
1388 << "starting with mz" << m_bins.front().startMzIn << "ending with mz"
1389 << m_bins.back().endMzOut;
1390
1391#endif
1392
1393 return bins;
1394}
1395
1396// This is for documentation, not for outputting the string used in the
1397// settings that are saved on disk.
1398QString
1399MzIntegrationParams::toString(int offset, const QString &spacer) const
1400{
1401 // The space-containing string that reflects the offset at which
1402 // new text lines should be added to start with.
1403 QString offset_lead;
1404
1405 for(int iter = 0; iter < offset; ++iter)
1406 offset_lead += spacer;
1407
1408 QString text = offset_lead;
1409 text += "m/z integration parameters:\n";
1410
1411 QString new_lead = QString("%1%2").arg(offset_lead, spacer);
1412
1413 text += new_lead;
1414 if(m_smallestMz != std::numeric_limits<double>::max())
1415 text.append(
1416 QString::asprintf("Smallest (first) m/z: %.6f\n", m_smallestMz));
1417
1418 text += new_lead;
1419 if(m_greatestMz != std::numeric_limits<double>::min())
1420 text.append(QString::asprintf("Greatest (last) m/z: %.6f\n", m_greatestMz));
1421
1422 text += new_lead;
1423 if(m_lowerAnchorMz != std::numeric_limits<double>::max())
1424 text.append(QString::asprintf("Lower anchor m/z: %.6f\n", m_lowerAnchorMz));
1425
1426 text += new_lead;
1427 if(m_upperAnchorMz != std::numeric_limits<double>::min())
1428 text.append(QString::asprintf("Upper anchor m/z: %.6f\n", m_upperAnchorMz));
1429
1430 text += new_lead;
1431 text += QString("Remove 0-val data points: %1\n")
1432 .arg(m_removeZeroValDataPoints ? "true" : "false");
1433
1434 text += new_lead;
1435 text.append("Binning logic:\n");
1436
1437 new_lead += spacer;
1438
1439 text += new_lead;
1440 text.append(
1441 QString("Binning type:%1\n").arg(::pappso::binningTypeMap[m_binningType]));
1442
1443 text += new_lead;
1444 text.append(QString("Bin size model: %1\n").arg(m_binSizeModel->toString()));
1445
1446 text += new_lead;
1447 text.append(QString("Bin size divisor: %2\n").arg(m_binSizeDivisor));
1448
1449 text += new_lead;
1450 text.append(QString("Decimal places: %1\n").arg(m_decimalPlaces));
1451
1452 return text;
1453}
1454
1455// This version is used to craft the string that enables the initialization.
1456QString
1458{
1459 QString text;
1460
1461 // In the string for saving settings, we do not ouput the m/z values.
1462 text.append(
1463 QString("Binning type:%1\n").arg(::pappso::binningTypeMap[m_binningType]));
1464 text.append(QString("Bin size model: %1\n").arg(m_binSizeModel->toString()));
1465 text.append(QString("Bin size divisor: %2\n").arg(m_binSizeDivisor));
1466 text.append(QString("Decimal places:%1\n").arg(m_decimalPlaces));
1467 text.append(
1468 QString("Remove 0-val data points:%1\n").arg(m_removeZeroValDataPoints));
1469
1470 // qDebug().noquote() << "Returning text:\n" << text;
1471
1472 return text;
1473}
1474
1475QString
1477 const std::vector<double> bins) const
1478{
1479 QString bins_with_delta;
1480 double previous_bin_value = 0;
1481
1482 for(auto &&value : bins)
1483 {
1484 double delta = value - previous_bin_value;
1485 bins_with_delta += QString("%1 - %2\n")
1486 .arg(value, 0, 'f', m_decimalPlaces)
1487 .arg(delta, 0, 'f', m_decimalPlaces);
1488 previous_bin_value = value;
1489 }
1490
1491 return bins_with_delta;
1492}
1493
1494void
1496{
1497 // qDebug() << "registerJsConstructor for MzIntegrationParams to QJSEngine.";
1498
1499 if(engine == nullptr)
1500 {
1501 qFatal() << "Cannot register class: engine is null";
1502 }
1503
1504 QJSValue pappso_root_property;
1505 QJSValue pappso_enums_property;
1506
1507 if(engine->globalObject().hasProperty("pappso"))
1508 {
1509 qDebug() << "Global object property 'pappso' already exists.";
1510 pappso_root_property = engine->globalObject().property("pappso");
1511
1512 if(pappso_root_property.hasProperty("Enums"))
1513 {
1514 pappso_enums_property = pappso_root_property.property("Enums");
1515 }
1516 else
1517 {
1518 pappso_enums_property = engine->newObject();
1519 pappso_root_property.setProperty("Enums", pappso_enums_property);
1520 }
1521 }
1522 else
1523 {
1524 qDebug() << "Global object property 'pappso' not found.";
1525 pappso_root_property = engine->newObject();
1526 pappso_enums_property = engine->newObject();
1527 pappso_root_property.setProperty("Enums", pappso_enums_property);
1528 engine->globalObject().setProperty("pappso", pappso_root_property);
1529 }
1530
1531 QJSValue enumObject;
1532
1533 // First the BinningType enum
1534 enumObject = engine->newObject();
1535
1536 enumObject.setProperty(
1537 "NONE", static_cast<int>(pappso::MzIntegrationParams::BinningType::NONE));
1538 enumObject.setProperty(
1539 "DATA_BASED",
1541 enumObject.setProperty(
1542 "ARBITRARY",
1544
1545 pappso_enums_property.setProperty("BinningType", enumObject);
1546
1547 // Second the InitializationResult enum
1548 enumObject = engine->newObject();
1549 enumObject.setProperty(
1550 "DEFAULT",
1551 static_cast<int>(
1553 enumObject.setProperty(
1554 "fromSettingsBinSizeModelPartial",
1557 enumObject.setProperty(
1558 "fromSettingsBinSizeModelFull",
1559 static_cast<int>(
1561 enumObject.setProperty(
1562 "fromSettingsFull",
1564
1565 pappso_enums_property.setProperty("InitializationResult", enumObject);
1566
1567 // Finally gegister the class meta object as a constructor for the class
1568 QJSValue jsMetaObject =
1569 engine->newQMetaObject(&MzIntegrationParams::staticMetaObject);
1570 engine->globalObject().setProperty("MzIntegrationParams", jsMetaObject);
1571}
1572
1573} // namespace pappso
Class to represent a mass spectrum.
void sortMz()
Sort the DataPoint instances of this spectrum.
The MzIntegrationParams class provides the parameters definining how m/z integrations must be perform...
Q_INVOKABLE int getDecimalPlaces() const
Q_INVOKABLE MzIntegrationParams(QObject *parent=nullptr)
Q_INVOKABLE void updateGreatestMz(double value)
Q_INVOKABLE int getBinSizeDivisor() const
Q_INVOKABLE InitializationResult initialize(const QString &text)
std::vector< double > createDataBasedBinsOld(pappso::MassSpectrumCstSPtr massSpectrum)
Q_INVOKABLE double getLowerAnchorMz() const
Q_INVOKABLE void setBinSizeModel(pappso::PrecisionPtr bin_size_model_p)
Q_INVOKABLE void setBinSizeDivisor(int divisor)
std::vector< double > createArbitraryBins()
Q_INVOKABLE double getUpperAnchorMz() const
Q_INVOKABLE void setGreatestMz(double value)
Q_INVOKABLE void setSmallestMz(double value)
Q_INVOKABLE QString binsToStringWithDeltas(const std::vector< double > bins) const
Q_INVOKABLE void updateLowerAnchorMz(double value)
Q_INVOKABLE bool isRemoveZeroValDataPoints() const
Q_INVOKABLE double getSmallestMz() const
pappso::PrecisionPtr m_binSizeModel
Q_INVOKABLE bool isValid() const
Q_INVOKABLE BinningType getBinningType() const
Q_INVOKABLE pappso::PrecisionPtr getBinSizeModel() const
Q_INVOKABLE void setUpperAnchorMz(double value)
Q_INVOKABLE bool hasValidMzRange() const
@ DATA_BASED
binning based on mass spectral data
@ ARBITRARY
binning based on arbitrary bin size value
static void registerJsConstructor(QJSEngine *engine)
Q_INVOKABLE void updateSmallestMz(double value)
Q_INVOKABLE MzIntegrationParams * clone(QObject *parent=nullptr) const
Q_INVOKABLE void setMzValues(double smallest, double greatest)
Q_INVOKABLE void setBinningType(BinningType binningType)
Q_INVOKABLE void reset()
Reset the instance to default values.
std::vector< double > createDataBasedBins(pappso::MassSpectrumCstSPtr massSpectrum)
Q_INVOKABLE QString toString() const
Q_INVOKABLE void setDecimalPlaces(int decimal_places)
Q_INVOKABLE std::vector< double > createBins()
Q_INVOKABLE void setRemoveZeroValDataPoints(bool removeOrNot=true)
Q_INVOKABLE void updateUpperAnchorMz(double value)
Q_INVOKABLE double getGreatestMz() const
Q_INVOKABLE void setLowerAnchorMz(double value)
static PrecisionPtr getResInstance(pappso_double value)
get a resolution precision pointer
static PrecisionPtr fromString(const QString &str)
get a precision pointer from a string
Definition precision.cpp:80
static PrecisionPtr getPpmInstance(pappso_double value)
get a ppm precision pointer
static double roundValueToDecimalPlaces(double value, int decimal_places, bool round_up=true)
Definition utils.cpp:371
static bool writeToFile(const QString &text, const QString &file_name)
Definition utils.cpp:216
static int zeroDecimalsInValue(pappso_double value)
Determine the number of zero decimals between the decimal point and the first non-zero decimal.
Definition utils.cpp:102
tries to keep as much as possible monoisotopes, removing any possible C13 peaks and changes multichar...
Definition aa.cpp:39
MzIntegrationParams::BinningType getBinningTypeFromString(const QString &text)
std::map< MzIntegrationParams::BinningType, QString > binningTypeMap
Map relating the BinningType to a textual representation.
std::shared_ptr< const MassSpectrum > MassSpectrumCstSPtr
const PrecisionBase * PrecisionPtr
Definition precision.h:122