REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
src/TRestRawSignal.cxx
1/*************************************************************************
2 * This file is part of the REST software framework. *
3 * *
4 * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) *
5 * For more information see http://gifna.unizar.es/trex *
6 * *
7 * REST is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * REST is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have a copy of the GNU General Public License along with *
18 * REST in $REST_PATH/LICENSE. *
19 * If not, see http://www.gnu.org/licenses/. *
20 * For the list of contributors see $REST_PATH/CREDITS. *
21 *************************************************************************/
22
60#include "TRestRawSignal.h"
61
62#include <TAxis.h>
63#include <TF1.h>
64#include <TMath.h>
65#include <TRandom3.h>
66
67#include <numeric>
68
69using namespace std;
70
71ClassImp(TRestRawSignal);
72
77 fGraph = nullptr;
78
79 Initialize();
80}
81
87 fGraph = nullptr;
88
89 Initialize();
90
91 fSignalData.resize(nBins, 0);
92}
93
98
103 fSignalData.clear();
104 fPointsOverThreshold.clear();
105 fSignalID = -1;
106
108
109 fHeadPoints = 0;
110 fTailPoints = 0;
111
112 fBaseLine = 0;
113 fBaseLineSigma = 0;
114}
115
121 Int_t nBins = GetNumberOfPoints();
122 Initialize();
123 fSignalData.resize(nBins, 0);
124}
125
129void TRestRawSignal::AddPoint(Short_t value) { fSignalData.push_back(value); }
130
134void TRestRawSignal::AddPoint(Double_t value) {
135 if (value > numeric_limits<Short_t>::max()) {
136 value = numeric_limits<Short_t>::max();
137 } else if (value < numeric_limits<Short_t>::min()) {
138 value = numeric_limits<Short_t>::min();
139 }
140 AddPoint((Short_t)value);
141}
142
149 if (n >= GetNumberOfPoints()) {
150 if (fShowWarnings) {
151 std::cout << "TRestRawSignal::GetSignalData: outside limits" << endl;
152 std::cout << "Warnings at TRestRawSignal have been disabled" << endl;
153 fShowWarnings = false;
154 }
155 return 0xFFFF;
156 }
157 return fSignalData[n];
158}
159
169Double_t TRestRawSignal::GetData(Int_t n) const { return (Double_t)fSignalData[n] - fBaseLine; }
170
175Double_t TRestRawSignal::GetRawData(Int_t n) const { return (Double_t)fSignalData[n]; }
176
180void TRestRawSignal::IncreaseBinBy(Int_t bin, Double_t data) {
181 if (bin >= GetNumberOfPoints()) {
182 if (fShowWarnings) {
183 std::cout << "TRestRawSignal::IncreaseBinBy: outside limits" << endl;
184 std::cout << "Warnings at TRestRawSignal have been disabled" << endl;
185 fShowWarnings = false;
186 }
187
188 return;
189 }
190
191 fSignalData[bin] += data;
192}
193
222void TRestRawSignal::InitializePointsOverThreshold(const TVector2& thrPar, Int_t nPointsOver,
223 Int_t nPointsFlat) {
224 if (fRange.X() < 0) fRange.SetX(0);
225 if (fRange.Y() <= 0) fRange.SetY(GetNumberOfPoints());
226
227 fPointsOverThreshold.clear();
228
229 double pointTh = thrPar.X();
230 double signalTh = thrPar.Y();
231
232 double threshold = pointTh * fBaseLineSigma;
233
234 for (int i = fRange.X(); i < fRange.Y(); i++) {
235 // Filling a pulse with consecutive points that are over threshold
236 if (this->GetData(i) > threshold) {
237 int pos = i;
238 std::vector<double> pulse;
239 pulse.push_back(this->GetData(i));
240 i++;
241
242 // If the pulse ends in a flat end above the threshold, the parameter
243 // nPointsFlat will serve to artificially end the pulse.
244 // If nPointsFlat is big enough, this parameter will not affect the
245 // decision to cut this anomalous behaviour. And all points over threshold
246 // will be added to the pulse vector.
247 int flatN = 0;
248 while (i < fRange.Y() && this->GetData(i) > threshold) {
249 if (TMath::Abs(this->GetData(i) - this->GetData(i - 1)) > threshold) {
250 flatN = 0;
251 } else {
252 flatN++;
253 }
254
255 if (flatN < nPointsFlat) {
256 pulse.push_back(this->GetData(i));
257 i++;
258 } else {
259 break;
260 }
261 }
262
263 if (pulse.size() >= (unsigned int)nPointsOver) {
264 // auto stdev = TMath::StdDev(begin(pulse), end(pulse));
265 // calculate stdev
266 double mean = std::accumulate(pulse.begin(), pulse.end(), 0.0) / pulse.size();
267 double sq_sum = std::inner_product(pulse.begin(), pulse.end(), pulse.begin(), 0.0);
268 double stdev = std::sqrt(sq_sum / pulse.size() - mean * mean);
269
270 if (stdev > signalTh * fBaseLineSigma)
271 for (int j = pos; j < i; j++) fPointsOverThreshold.push_back(j);
272 }
273 }
274 }
275
277}
278
285 if (fRange.X() < 0) fRange.SetX(0);
286 if (fRange.Y() <= 0 || fRange.Y() > GetNumberOfPoints()) fRange.SetY(GetNumberOfPoints());
287
289
290 for (unsigned int n = 0; n < fPointsOverThreshold.size(); n++) {
291 if (fPointsOverThreshold[n] >= fRange.X() && fPointsOverThreshold[n] < fRange.Y()) {
293 }
294 }
295}
296
303 if (fRange.X() < 0) fRange.SetX(0);
304 if (fRange.Y() <= 0 || fRange.Y() > GetNumberOfPoints()) fRange.SetY(GetNumberOfPoints());
305
306 Double_t sum = 0;
307 for (int i = fRange.X(); i < fRange.Y(); i++) sum += GetData(i);
308 return sum;
309}
310
315Double_t TRestRawSignal::GetIntegralInRange(Int_t startBin, Int_t endBin) {
316 if (startBin < 0) startBin = 0;
317 if (endBin <= 0 || endBin > GetNumberOfPoints()) endBin = GetNumberOfPoints();
318
319 Double_t sum = 0;
320 for (int i = startBin; i < endBin; i++) sum += GetRawData(i);
321 return sum;
322}
323
330 if (fThresholdIntegral == -1)
331 if (fShowWarnings) {
332 std::cout << "TRestRawSignal::GetThresholdIntegral. "
333 "InitializePointsOverThreshold should be "
334 "called first!"
335 << endl;
336 fShowWarnings = false;
337 }
338 return fThresholdIntegral;
339}
340
347 if (fThresholdIntegral == -1)
348 cout << "REST Warning. TRestRawSignal::GetSlopeIntegral. "
349 "InitializePointsOverThreshold should be called first."
350 << endl;
351
352 Double_t sum = 0;
353 for (unsigned int n = 0; n < fPointsOverThreshold.size(); n++) {
354 if (n + 1 >= fPointsOverThreshold.size()) return sum;
355
356 sum += GetData(fPointsOverThreshold[n]);
357
358 if (GetData(fPointsOverThreshold[n + 1]) - GetData(fPointsOverThreshold[n]) < 0) break;
359 }
360 return sum;
361}
362
370 if (fThresholdIntegral == -1)
371 cout << "REST Warning. TRestRawSignal::GetRiseSlope. "
372 "InitializePointsOverThreshold should be called first."
373 << endl;
374
375 if (fPointsOverThreshold.size() < 2) {
376 // cout << "REST Warning. TRestRawSignal::GetRiseSlope. Less than 2 points!." << endl;
377 return 0;
378 }
379
380 Int_t maxBin = GetMaxPeakBin() - 1;
381
382 Double_t hP = GetData(maxBin);
383
384 Double_t lP = GetData(fPointsOverThreshold[0]);
385
386 return (hP - lP) / (maxBin - fPointsOverThreshold[0]);
387}
388
394 if (fThresholdIntegral == -1)
395 cout << "REST Warning. TRestRawSignal::GetRiseTime. "
396 "InitializePointsOverThreshold should be called first."
397 << endl;
398
399 if (fPointsOverThreshold.size() < 2) {
400 // cout << "REST Warning. TRestRawSignal::GetRiseTime. Less than 2 points!." << endl;
401 return 0;
402 }
403
405}
406
412 if (fRange.X() < 0) fRange.SetX(0);
413 if (fRange.Y() <= 0 || fRange.Y() > GetNumberOfPoints()) fRange.SetY(GetNumberOfPoints());
414
415 if (fThresholdIntegral == -1) {
416 cout << "REST Warning. TRestRawSignal::GetTripleMaxIntegral. "
417 "InitializePointsOverThreshold should be called first."
418 << endl;
419 return 0;
420 }
421
422 if (fPointsOverThreshold.size() < 2) {
423 // cout << "REST Warning. TRestRawSignal::GetTripleMaxIntegral. Points over
424 // "
425 // "threshold = "
426 // << fPointsOverThreshold.size() << endl;
427 return 0;
428 }
429
430 Int_t cBin = GetMaxPeakBin();
431
432 if (cBin + 1 >= GetNumberOfPoints()) return 0;
433
434 Double_t a1 = GetData(cBin);
435 Double_t a2 = GetData(cBin - 1);
436 Double_t a3 = GetData(cBin + 1);
437
438 return a1 + a2 + a3;
439}
440
445Double_t TRestRawSignal::GetAverageInRange(Int_t startBin, Int_t endBin) {
446 if (startBin < 0) startBin = 0;
447 if (endBin <= 0 || endBin > GetNumberOfPoints()) endBin = GetNumberOfPoints();
448
449 Double_t sum = 0;
450 for (int i = startBin; i <= endBin; i++) sum += this->GetData(i);
451
452 return sum / (endBin - startBin + 1);
453}
454
460 Int_t mIndex = this->GetMaxPeakBin();
461 Double_t maxValue = this->GetData(mIndex);
462
463 Double_t value = maxValue;
464 Int_t rightIndex = mIndex;
465 while (value > maxValue / 2) {
466 value = this->GetData(rightIndex);
467 rightIndex++;
468 }
469 Int_t leftIndex = mIndex;
470 value = maxValue;
471 while (value > maxValue / 2) {
472 value = this->GetData(leftIndex);
473 leftIndex--;
474 }
475
476 return rightIndex - leftIndex;
477}
478
485
490 Double_t max = numeric_limits<Double_t>::min();
491
492 Int_t index = 0;
493
494 if (fRange.Y() == 0 || fRange.Y() > GetNumberOfPoints()) fRange.SetY(GetNumberOfPoints());
495 if (fRange.X() < 0) fRange.SetX(0);
496
497 for (int i = fRange.X(); i < fRange.Y(); i++) {
498 if (this->GetData(i) > max) {
499 max = GetData(i);
500 index = i;
501 }
502 }
503
504 return index;
505}
506
513
518 Double_t min = numeric_limits<Double_t>::max();
519 Int_t index = 0;
520
521 if (fRange.Y() == 0 || fRange.Y() > GetNumberOfPoints()) fRange.SetY(GetNumberOfPoints());
522 if (fRange.X() < 0) fRange.SetX(0);
523
524 for (int i = fRange.X(); i < fRange.Y(); i++) {
525 if (this->GetData(i) < min) {
526 min = GetData(i);
527 index = i;
528 }
529 }
530
531 return index;
532}
533
538 if (Nflat <= 0) return false;
539 // GetMaxPeakBin() will always find the first max peak bin if multiple bins are in same max value.
540 int index = GetMaxPeakBin();
541 Short_t value = fSignalData[index];
542
543 bool sat = false;
544 if (index + Nflat <= (int)fSignalData.size()) {
545 for (int i = index; i < index + Nflat; i++) {
546 if (fSignalData[i] != value) {
547 break;
548 }
549 if (i == index + Nflat - 1) {
550 sat = true;
551 }
552 }
553 }
554
555 return sat;
556}
557
567void TRestRawSignal::GetDifferentialSignal(TRestRawSignal* diffSignal, Int_t smearPoints) {
568 if (smearPoints <= 0) smearPoints = 1;
569 diffSignal->Initialize();
570
571 for (int i = 0; i < smearPoints; i++) {
572 diffSignal->AddPoint((Short_t)0);
573 }
574
575 for (int i = smearPoints; i < this->GetNumberOfPoints() - smearPoints; i++) {
576 Double_t value = 0.5 * (this->GetData(i + smearPoints) - GetData(i - smearPoints)) / smearPoints;
577
578 diffSignal->AddPoint((Short_t)value);
579 }
580
581 for (int i = GetNumberOfPoints() - smearPoints; i < GetNumberOfPoints(); i++) {
582 diffSignal->AddPoint((Short_t)0);
583 }
584}
585
594void TRestRawSignal::GetWhiteNoiseSignal(TRestRawSignal* noiseSignal, Double_t noiseLevel) {
595 TRandom3 random(fSeed);
596
597 for (int i = 0; i < GetNumberOfPoints(); i++) {
598 Double_t value = this->GetData(i) + random.Gaus(0, noiseLevel);
599 // do not cast as short so that there are no problems with overflows
600 // (https://github.com/rest-for-physics/rawlib/issues/113)
601 noiseSignal->AddPoint(value);
602 }
603}
604
612void TRestRawSignal::GetSignalSmoothed(TRestRawSignal* smoothedSignal, Int_t averagingPoints) {
613 smoothedSignal->Initialize();
614
615 averagingPoints = (averagingPoints / 2) * 2 + 1; // make it odd >= averagingPoints
616
617 Double_t sumAvg = GetIntegralInRange(0, averagingPoints) / averagingPoints;
618
619 for (int i = 0; i <= averagingPoints / 2; i++) smoothedSignal->AddPoint((Short_t)sumAvg);
620
621 for (int i = averagingPoints / 2 + 1; i < GetNumberOfPoints() - averagingPoints / 2; i++) {
622 sumAvg -= this->GetRawData(i - (averagingPoints / 2 + 1)) / averagingPoints;
623 sumAvg += this->GetRawData(i + averagingPoints / 2) / averagingPoints;
624 smoothedSignal->AddPoint((Short_t)sumAvg);
625 }
626
627 for (int i = GetNumberOfPoints() - averagingPoints / 2; i < GetNumberOfPoints(); i++)
628 smoothedSignal->AddPoint(sumAvg);
629}
630
640std::vector<Float_t> TRestRawSignal::GetSignalSmoothed(Int_t averagingPoints, std::string option) {
641 std::vector<Float_t> result;
642
643 if (option == "") {
644 result.resize(GetNumberOfPoints());
645
646 averagingPoints = (averagingPoints / 2) * 2 + 1; // make it odd >= averagingPoints
647
648 Float_t sumAvg = (Float_t)GetIntegralInRange(0, averagingPoints) / averagingPoints;
649
650 for (int i = 0; i <= averagingPoints / 2; i++) result[i] = sumAvg;
651
652 for (int i = averagingPoints / 2 + 1; i < GetNumberOfPoints() - averagingPoints / 2; i++) {
653 sumAvg -= this->GetRawData(i - (averagingPoints / 2 + 1)) / averagingPoints;
654 sumAvg += this->GetRawData(i + averagingPoints / 2) / averagingPoints;
655 result[i] = sumAvg;
656 }
657
658 for (int i = GetNumberOfPoints() - averagingPoints / 2; i < GetNumberOfPoints(); i++)
659 result[i] = sumAvg;
660 } else if (ToUpper(option) == "EXCLUDE OUTLIERS") {
661 result = GetSignalSmoothed_ExcludeOutliers(averagingPoints);
662 } else {
663 cout << "TRestRawSignal::GetSignalSmoothed. Error! No such option!" << endl;
664 }
665 return result;
666}
667
677std::vector<Float_t> TRestRawSignal::GetSignalSmoothed_ExcludeOutliers(Int_t averagingPoints) {
678 std::vector<Float_t> result(GetNumberOfPoints());
679
680 if (fBaseLine == 0) CalculateBaseLine(5, GetNumberOfPoints() - 5, "ROBUST");
681
682 averagingPoints = (averagingPoints / 2) * 2 + 1; // make it odd >= averagingPoints
683
684 Float_t sumAvg = (Float_t)GetIntegralInRange(0, averagingPoints) / averagingPoints;
685
686 // Points at the beginning, where we can calculate a moving average
687 for (int i = 0; i <= averagingPoints / 2; i++) result[i] = sumAvg;
688
689 // Points in the middle
690 float_t amplitude;
691 for (int i = averagingPoints / 2 + 1; i < GetNumberOfPoints() - averagingPoints / 2; i++) {
692 amplitude = this->GetRawData(i - (averagingPoints / 2 + 1));
693 sumAvg -= (std::abs(amplitude - fBaseLine) > 3 * fBaseLineSigma) ? fBaseLine / averagingPoints
694 : amplitude / averagingPoints;
695 amplitude = this->GetRawData(i + averagingPoints / 2);
696 sumAvg += (std::abs(amplitude - fBaseLine) > 3 * fBaseLineSigma) ? fBaseLine / averagingPoints
697 : amplitude / averagingPoints;
698 result[i] = sumAvg;
699 }
700
701 // Points at the end, where we can calculate a moving average
702 for (int i = GetNumberOfPoints() - averagingPoints / 2; i < GetNumberOfPoints(); i++) result[i] = sumAvg;
703 return result;
704}
705
716void TRestRawSignal::GetBaseLineCorrected(TRestRawSignal* smoothedSignal, Int_t averagingPoints) {
717 smoothedSignal->Initialize();
718
719 std::vector<Float_t> averagedSignal = GetSignalSmoothed(averagingPoints, "EXCLUDE OUTLIERS");
720
721 for (int i = 0; i < GetNumberOfPoints(); i++) {
722 smoothedSignal->AddPoint(GetRawData(i) - averagedSignal[i]);
723 }
724}
725
731void TRestRawSignal::CalculateBaseLineMean(Int_t startBin, Int_t endBin) {
732 if (endBin - startBin <= 0) {
733 fBaseLine = 0.;
734 } else if (endBin > (int)fSignalData.size()) {
735 cout << "TRestRawSignal::CalculateBaseLine. Error! Baseline range exceeds the rawdata depth!!"
736 << endl;
737 endBin = fSignalData.size();
738 } else {
739 Double_t baseLine = 0;
740 for (int i = startBin; i < endBin; i++) baseLine += fSignalData[i];
741 fBaseLine = baseLine / (endBin - startBin);
742 }
743}
744
750void TRestRawSignal::CalculateBaseLineMedian(Int_t startBin, Int_t endBin) {
751 if (endBin - startBin <= 0) {
752 fBaseLine = 0.;
753 } else if (endBin > (int)fSignalData.size()) {
754 cout << "TRestRawSignal::CalculateBaseLine. Error! Baseline range exceeds the rawdata depth!!"
755 << endl;
756 endBin = fSignalData.size();
757 } else {
758 vector<Short_t>::const_iterator first = fSignalData.begin() + startBin;
759 vector<Short_t>::const_iterator last = fSignalData.begin() + endBin;
760 vector<Short_t> v(first, last);
761 const Short_t* signalInRange = &v[0];
762 fBaseLine = TMath::Median(endBin - startBin, signalInRange);
763 }
764}
765
776void TRestRawSignal::CalculateBaseLine(Int_t startBin, Int_t endBin, const std::string& option) {
777 if (ToUpper(option) == "ROBUST") {
778 CalculateBaseLineMedian(startBin, endBin);
779 CalculateBaseLineSigmaIQR(startBin, endBin);
780 } else {
781 CalculateBaseLineMean(startBin, endBin);
782 CalculateBaseLineSigmaSD(startBin, endBin);
783 }
784}
785
791void TRestRawSignal::CalculateBaseLineSigmaSD(Int_t startBin, Int_t endBin) {
792 if (endBin - startBin <= 0) {
793 fBaseLineSigma = 0;
794 } else {
795 Double_t baseLineSigma = 0;
796 for (int i = startBin; i < endBin; i++)
797 baseLineSigma += (fBaseLine - fSignalData[i]) * (fBaseLine - fSignalData[i]);
798 fBaseLineSigma = TMath::Sqrt(baseLineSigma / (endBin - startBin));
799 }
800}
801
808void TRestRawSignal::CalculateBaseLineSigmaIQR(Int_t startBin, Int_t endBin) {
809 if (endBin - startBin <= 0) {
810 fBaseLineSigma = 0;
811 } else {
812 vector<Short_t>::const_iterator first = fSignalData.begin() + startBin;
813 vector<Short_t>::const_iterator last = fSignalData.begin() + endBin;
814 vector<Short_t> v(first, last);
815 std::sort(v.begin(), v.end());
816 Short_t Q1 = v[(int)(endBin - startBin) * 0.25];
817 Short_t Q3 = v[(int)(endBin - startBin) * 0.75];
818 Double_t IQR = Q3 - Q1;
820 IQR / 1.349; // IQR/1.349 equals the standard deviation in case of normally distributed data
821 }
822}
823
827void TRestRawSignal::AddOffset(Short_t offset) {
828 if (fBaseLine != 0 || fBaseLineSigma != 0) fBaseLineSigma += (Double_t)offset;
829 for (int i = 0; i < GetNumberOfPoints(); i++) fSignalData[i] = fSignalData[i] + offset;
830}
831
835void TRestRawSignal::Scale(Double_t value) {
836 for (int i = 0; i < GetNumberOfPoints(); i++) {
837 Double_t scaledValue = value * fSignalData[i];
838 fSignalData[i] = (Short_t)scaledValue;
839 }
840}
841
847 if (this->GetNumberOfPoints() != signal.GetNumberOfPoints()) {
848 cout << "ERROR : TRestRawSignal::SignalAddition." << endl;
849 cout << "I cannot add two signals with different number of points" << endl;
850 return;
851 }
852
853 for (int i = 0; i < GetNumberOfPoints(); i++) {
854 fSignalData[i] += signal.GetData(i);
855 }
856}
857
861void TRestRawSignal::WriteSignalToTextFile(const TString& filename) {
862 // We should check it is writable
863 FILE* file = fopen(filename.Data(), "w");
864 for (int i = 0; i < GetNumberOfPoints(); i++) fprintf(file, "%d\t%lf\n", i, GetData(i));
865 fclose(file);
866}
867
872 cout << "---------------------" << endl;
873 cout << "Signal id : " << this->GetSignalID() << endl;
874 cout << "Baseline : " << fBaseLine << endl;
875 cout << "Baseline sigma : " << fBaseLineSigma << endl;
876 cout << "+++++++++++++++++++++" << endl;
877 for (int i = 0; i < GetNumberOfPoints(); i++)
878 cout << "Bin : " << i << " amplitude : " << GetRawData(i) << endl;
879 cout << "---------------------" << endl;
880}
881
885TGraph* TRestRawSignal::GetGraph(Int_t color) {
886 delete fGraph;
887 fGraph = new TGraph();
888
889 fGraph->SetLineWidth(2);
890 fGraph->SetLineColor(color % 8 + 1);
891 fGraph->SetMarkerStyle(7);
892
893 for (int i = 0; i < GetNumberOfPoints(); i++) {
894 fGraph->SetPoint(i, i, GetData(i));
895 }
896
897 fGraph->GetXaxis()->SetLimits(0, GetNumberOfPoints() - 1);
898
899 /*
900 * To draw x axis in multiples of 2
901 for (int i = 0; i < values.size(); i++) {
902 if (i % 32 != 0 && i != values.size() - 1){
903 continue;
904 }
905 fGraph->GetXaxis()->SetBinLabel(fGraph->GetXaxis()->FindBin(i), std::to_string(i).c_str());
906 }
907 */
908
909 return fGraph;
910}
911
912vector<pair<UShort_t, double>> TRestRawSignal::GetPeaks(double threshold, UShort_t distance) const {
913 vector<pair<UShort_t, double>> peaks;
914
915 for (UShort_t i = 0; i < GetNumberOfPoints(); i++) {
916 const double point = GetRawData(i);
917 if (i > 0 && i < GetNumberOfPoints() - 1) {
918 double prevPoint = GetRawData(i - 1);
919 double nextPoint = GetRawData(i + 1);
920
921 if (point > threshold && point >= prevPoint && point >= nextPoint) {
922 // Check if the peak is spaced far enough from the previous peak
923 if (peaks.empty() || i - peaks.back().first >= distance) {
924 peaks.push_back(std::make_pair(i, point));
925 }
926 }
927 }
928 }
929 return peaks;
930}
It defines a Short_t array with a physical parameter that evolves in time using a fixed time bin.
Int_t GetMinPeakBin()
It returns the bin at which the minimum peak amplitude happens.
void WriteSignalToTextFile(const TString &filename)
This method dumps to a text file the data inside fSignalData.
Double_t GetThresholdIntegral()
It returns the integral of points identified over threshold. InitializePointsOverThreshold should hav...
~TRestRawSignal()
Default destructor.
TGraph * fGraph
A TGraph pointer used to store the TRestRawSignal drawing.
Double_t fBaseLine
This baseline value will be subtracted from GetData for any raw signal observable calculation.
void GetSignalSmoothed(TRestRawSignal *smoothedSignal, Int_t averagingPoints)
It smoothes the existing signal and places it at the signal pointer given by argument.
Double_t GetRiseSlope()
It returns the rate of change or slope from the points that have been identified over threshlold on t...
std::vector< Short_t > fSignalData
Vector with the data of the signal.
void Print() const
It prints the signal data on screen.
Double_t fThresholdIntegral
It stores the integral value obtained from the points identified over threshold.
Int_t fSignalID
An integer value used to attribute a unique identification number to the signal.
Double_t GetMaxPeakValue()
It returns the amplitude of the signal maximum, baseline will be corrected if CalculateBaseLine was c...
std::vector< Float_t > GetSignalSmoothed_ExcludeOutliers(Int_t averagingPoints)
It smooths the existing signal and returns it in a vector of Float_t values. This method excludes poi...
Double_t GetMinPeakValue()
It returns the amplitude of the signal minimum, baseline will be corrected if CalculateBaseLine was c...
void CalculateBaseLine(Int_t startBin, Int_t endBin, const std::string &option="")
This method calculates the average and fluctuation of the baseline in the specified range and writes ...
void CalculateThresholdIntegral()
This method will be called each time InitializePointsOverThreshold is called to re-define the value o...
void Initialize()
Initialization of TRestRawSignal members.
void CalculateBaseLineMean(Int_t startBin, Int_t endBin)
This method is called by CalculateBaseLine and is used to determine the value of the baseline as aver...
void CalculateBaseLineSigmaSD(Int_t startBin, Int_t endBin)
This method is called by CalculateBaseLine to determine the value of the baseline fluctuation as its ...
TRestRawSignal()
Default constructor.
Short_t operator[](Int_t n)
It overloads the operator [] so that we can retrieve a particular point n in the form rawSignal[n].
void InitializePointsOverThreshold(const TVector2 &thrPar, Int_t nPointsOver, Int_t nPointsFlat=512)
It initializes the fPointsOverThreshold array with the indexes of data points that are found over thr...
Double_t GetIntegralInRange(Int_t startBin, Int_t endBin)
It returns the integral of points found in the specific range given by (startBin,endBin).
void Reset()
Initializes the existing signal data and sets it to zero while keeping the array size.
std::vector< std::pair< UShort_t, double > > GetPeaks(double threshold, UShort_t distance=5) const
void SignalAddition(const TRestRawSignal &signal)
This method adds the signal provided by argument to the existing signal.
Int_t fTailPoints
It defines the number of points to include after point over threshold definition. NOT implemented.
void AddOffset(Short_t offset)
This method adds an offset to the signal data.
Int_t GetMaxPeakWidth()
It returns the temporal width of the peak with maximum amplitude inside the signal.
Int_t GetRiseTime()
It returns the time required from the signal to reach the maximum. InitializePointsOverThreshold shou...
Double_t GetAverageInRange(Int_t startBin, Int_t endBin)
It returns the average of the points found in the range (startBin, endBin)
void IncreaseBinBy(Int_t bin, Double_t data)
It adds the content of data to fSignalData[bin].
void GetDifferentialSignal(TRestRawSignal *diffSignal, Int_t smearPoints)
It calculates the differential signal of the existing signal and it will place at the signal pointer ...
void CalculateBaseLineMedian(Int_t startBin, Int_t endBin)
This method is called by CalculateBaseLine with the "ROBUST"-option and is used to determine the valu...
std::vector< Int_t > fPointsOverThreshold
A std::vector containing the index of points that are identified over threshold.
Double_t GetRawData(Int_t n) const
It returns the original data value of point n without baseline correction.
Double_t GetData(Int_t n) const
It returns the data value of point n including baseline correction.
Double_t GetTripleMaxIntegral()
It returns the integral calculated using the maximum signal amplitude and its neightbour points.
void Scale(Double_t value)
This method scales the signal by a given value.
Double_t GetIntegral()
It returns the integral of points found in the region defined by fRange. If fRange was not defined th...
void AddPoint(Short_t)
Adds a new point to the end of the signal data array.
TGraph * GetGraph(Int_t color=1)
It builds a TGraph object that can be used for drawing.
UInt_t fSeed
Seed used for random number generation.
Double_t GetSlopeIntegral()
It returns the integral of points identified over threshold found in the first positive rise of the s...
Double_t fBaseLineSigma
The baseline fluctuation calculated as the standard deviation of the baseline.
void GetWhiteNoiseSignal(TRestRawSignal *noiseSignal, Double_t noiseLevel=1.)
It calculates an arbitrary Gaussian noise placing it at the signal pointer given by argument....
Bool_t IsADCSaturation(int Nflat=3)
It returns whether the signal has ADC saturation.
Int_t fHeadPoints
It defines the number of points to include before point over threshold definition....
Int_t GetMaxPeakBin()
It returns the bin at which the maximum peak amplitude happens.
Int_t GetSignalID() const
Returns the value of signal ID.
void GetBaseLineCorrected(TRestRawSignal *smoothedSignal, Int_t averagingPoints)
It applies the moving average filter (GetSignalSmoothed) to the signal, which is then subtracted from...
TVector2 fRange
Any signal calculation will be restricted to the following range definition.
void CalculateBaseLineSigmaIQR(Int_t startBin, Int_t endBin)
This method is called by CalculateBaseLine with the "ROBUST"-option to determine the value of the bas...
Int_t GetNumberOfPoints() const
Returns the actual number of points, or size of the signal.