26#include "TRestDetectorSignal.h"
28#include "TFitResult.h"
40TRestDetectorSignal::TRestDetectorSignal() {
45 fSignalCharge.clear();
47 fPointsOverThreshold.clear();
50TRestDetectorSignal::~TRestDetectorSignal() {
54void TRestDetectorSignal::NewPoint(Float_t time, Float_t data) {
55 fSignalTime.push_back(time);
56 fSignalCharge.push_back(data);
75 Int_t index = GetTimeIndex(p.X());
80 fSignalTime[index] = x;
81 fSignalCharge[index] += y;
83 fSignalTime.push_back(x);
84 fSignalCharge.push_back(y);
96 Int_t index = GetTimeIndex(p.X());
101 fSignalTime[index] = x;
102 fSignalCharge[index] = y;
104 fSignalTime.push_back(x);
105 fSignalCharge.push_back(y);
126 fSignalTime[index] = t;
127 fSignalCharge[index] = d;
130Double_t TRestDetectorSignal::GetIntegral(Int_t startBin, Int_t endBin) {
131 if (startBin < 0) startBin = 0;
132 if (endBin <= 0 || endBin > GetNumberOfPoints()) endBin = GetNumberOfPoints();
135 for (
int i = startBin; i < endBin; i++) sum += GetData(i);
140void TRestDetectorSignal::Normalize(Double_t scale) {
141 Double_t sum = GetIntegral();
143 for (
int i = 0; i < GetNumberOfPoints(); i++) fSignalCharge[i] = scale * GetData(i) / sum;
146Double_t TRestDetectorSignal::GetIntegralWithTime(Double_t startTime, Double_t endTime) {
148 for (
int i = 0; i < GetNumberOfPoints(); i++)
149 if (GetTime(i) >= startTime && GetTime(i) < endTime) sum += GetData(i);
154Double_t TRestDetectorSignal::GetMaxPeakWithTime(Double_t startTime, Double_t endTime) {
155 Double_t max = -1E10;
157 for (
int i = 0; i < GetNumberOfPoints(); i++)
158 if (GetTime(i) >= startTime && GetTime(i) < endTime) {
159 if (this->GetData(i) > max) max = GetData(i);
225Double_t TRestDetectorSignal::GetAverage(Int_t start, Int_t end) {
228 if (end == 0) end = this->GetNumberOfPoints();
231 for (
int i = start; i <= end; i++) {
232 sum += this->GetData(i);
234 return sum / (end - start + 1);
237Int_t TRestDetectorSignal::GetMaxPeakWidth() {
240 Int_t mIndex = this->GetMaxIndex();
241 Double_t maxValue = this->GetData(mIndex);
243 Double_t value = maxValue;
244 Int_t rightIndex = mIndex;
245 while (value > maxValue / 2) {
246 value = this->GetData(rightIndex);
249 Int_t leftIndex = mIndex;
251 while (value > maxValue / 2) {
252 value = this->GetData(leftIndex);
256 return rightIndex - leftIndex;
259Double_t TRestDetectorSignal::GetMaxPeakValue() {
return GetData(GetMaxIndex()); }
261Int_t TRestDetectorSignal::GetMaxIndex(Int_t from, Int_t to) {
262 Double_t max = -1E10;
265 if (from < 0) from = 0;
266 if (to > GetNumberOfPoints()) to = GetNumberOfPoints();
268 if (to == 0) to = GetNumberOfPoints();
270 for (
int i = from; i < to; i++) {
271 if (this->GetData(i) > max) {
283TRestDetectorSignal::GetMaxGauss()
285 Int_t maxRaw = GetMaxIndex();
286 Double_t maxRawTime =
288 Double_t energy = 0, time = 0;
289 Double_t lowerLimit = maxRawTime - 0.2;
290 Double_t upperLimit = maxRawTime + 0.4;
292 TF1* gaus =
new TF1(
"gaus",
"gaus", lowerLimit, upperLimit);
293 TH1F* h1 =
new TH1F(
"h1",
"h1", 1000, 0,
297 for (
int i = 0; i < GetNumberOfPoints(); i++) {
298 h1->Fill(GetTime(i), GetData(i));
307 TFitResultPtr fitResult =
308 h1->Fit(gaus,
"QNRS");
311 if (fitResult->IsValid()) {
312 energy = gaus->GetParameter(0);
313 time = gaus->GetParameter(1);
319 <<
"WARNING: bad fit to signal with ID " << GetID() <<
" with maximum at time = " << maxRawTime
322 <<
"Failed fit parameters = " << gaus->GetParameter(0) <<
" || " << gaus->GetParameter(1)
323 <<
" || " << gaus->GetParameter(2) <<
"\n"
324 <<
"Assigned fit parameters : energy = " << energy <<
", time = " << time << endl;
334 TVector2 fitParam(time, energy);
345TRestDetectorSignal::GetMaxLandau()
347 Int_t maxRaw = GetMaxIndex();
348 Double_t maxRawTime =
350 Double_t energy = 0, time = 0;
351 Double_t lowerLimit = maxRawTime - 0.2;
352 Double_t upperLimit = maxRawTime + 0.4;
354 TF1* landau =
new TF1(
"landau",
"landau", lowerLimit, upperLimit);
355 TH1F* h1 =
new TH1F(
"h1",
"h1", 1000, 0,
359 for (
int i = 0; i < GetNumberOfPoints(); i++) {
360 h1->Fill(GetTime(i), GetData(i));
363 TFitResultPtr fitResult =
364 h1->Fit(landau,
"QNRS");
366 if (fitResult->IsValid()) {
367 energy = landau->GetParameter(0);
368 time = landau->GetParameter(1);
374 <<
"WARNING: bad fit to signal with ID " << GetID() <<
" with maximum at time = " << maxRawTime
377 <<
"Failed fit parameters = " << landau->GetParameter(0) <<
" || " << landau->GetParameter(1)
378 <<
" || " << landau->GetParameter(2) <<
"\n"
379 <<
"Assigned fit parameters : energy = " << energy <<
", time = " << time << endl;
389 TVector2 fitParam(time, energy);
399Double_t agetResponseFunction(Double_t* x, Double_t* par) {
404 (x[0] - par[1] + 1.1664) /
406 Double_t f = par[0] / 0.0440895 * exp(-3 * (arg)) * (arg) * (arg) *
412TRestDetectorSignal::GetMaxAget()
414 Int_t maxRaw = GetMaxIndex();
415 Double_t maxRawTime =
417 Double_t energy = 0, time = 0;
419 Double_t lowerLimit = maxRawTime - 0.2;
420 Double_t upperLimit = maxRawTime + 0.7;
422 TF1* aget =
new TF1(
"aget", agetResponseFunction, lowerLimit, upperLimit, 3);
423 TH1F* h1 =
new TH1F(
"h1",
"h1", 1000, 0,
425 aget->SetParameters(500, maxRawTime, 1.2);
428 for (
int i = 0; i < GetNumberOfPoints(); i++) {
429 h1->Fill(GetTime(i), GetData(i));
432 TFitResultPtr fitResult =
433 h1->Fit(aget,
"QNRS");
436 if (fitResult->IsValid()) {
437 energy = aget->GetParameter(0);
438 time = aget->GetParameter(1);
444 <<
"WARNING: bad fit to signal with ID " << GetID() <<
" with maximum at time = " << maxRawTime
447 <<
"Failed fit parameters = " << aget->GetParameter(0) <<
" || " << aget->GetParameter(1)
448 <<
" || " << aget->GetParameter(2) <<
"\n"
449 <<
"Assigned fit parameters : energy = " << energy <<
", time = " << time << endl;
459 TVector2 fitParam(time, energy);
466Double_t TRestDetectorSignal::GetMaxPeakTime(Int_t from, Int_t to) {
return GetTime(GetMaxIndex(from, to)); }
468Double_t TRestDetectorSignal::GetMinPeakValue() {
return GetData(GetMinIndex()); }
470Int_t TRestDetectorSignal::GetMinIndex() {
474 for (
int i = 0; i < GetNumberOfPoints(); i++) {
475 if (this->GetData(i) < min) {
484Double_t TRestDetectorSignal::GetMinTime() {
485 Double_t minTime = 1E10;
486 for (
int n = 0; n < GetNumberOfPoints(); n++)
487 if (minTime > fSignalTime[n]) minTime = fSignalTime[n];
492Double_t TRestDetectorSignal::GetMaxTime() {
493 Double_t maxTime = -1E10;
494 for (
int n = 0; n < GetNumberOfPoints(); n++)
495 if (maxTime < fSignalTime[n]) maxTime = fSignalTime[n];
500Int_t TRestDetectorSignal::GetTimeIndex(Double_t t) {
503 for (
int n = 0; n < GetNumberOfPoints(); n++)
504 if (time == fSignalTime[n])
return n;
508Bool_t TRestDetectorSignal::isSorted() {
509 for (
int i = 0; i < GetNumberOfPoints() - 1; i++) {
510 if (GetTime(i + 1) < GetTime(i))
return false;
515void TRestDetectorSignal::Sort() {
516 while (!isSorted()) {
517 for (
int i = 0; i < GetNumberOfPoints(); i++) {
518 for (
int j = i; j < GetNumberOfPoints(); j++) {
519 if (GetTime(i) > GetTime(j)) {
520 iter_swap(fSignalTime.begin() + i, fSignalTime.begin() + j);
521 iter_swap(fSignalCharge.begin() + i, fSignalCharge.begin() + j);
528void TRestDetectorSignal::GetDifferentialSignal(
TRestDetectorSignal* diffSgnl, Int_t smearPoints) {
531 for (
int i = 0; i < smearPoints; i++) diffSgnl->
IncreaseAmplitude(GetTime(i), 0);
533 for (
int i = smearPoints; i < this->GetNumberOfPoints() - smearPoints; i++) {
534 Double_t value = (this->GetData(i + smearPoints) - GetData(i - smearPoints)) /
535 (GetTime(i + smearPoints) - GetTime(i - smearPoints));
536 Double_t time = (GetTime(i + smearPoints) + GetTime(i - smearPoints)) / 2.;
541 for (
int i = GetNumberOfPoints() - smearPoints; i < GetNumberOfPoints(); i++)
545void TRestDetectorSignal::GetSignalDelayed(
TRestDetectorSignal* delayedSignal, Int_t delay) {
548 for (
int i = 0; i < delay; i++) delayedSignal->
IncreaseAmplitude(GetTime(i), GetData(i));
550 for (
int i = delay; i < GetNumberOfPoints(); i++)
554void TRestDetectorSignal::GetSignalSmoothed(
TRestDetectorSignal* smthSignal, Int_t averagingPoints) {
557 averagingPoints = (averagingPoints / 2) * 2 + 1;
559 Double_t sum = GetIntegral(0, averagingPoints);
560 for (
int i = 0; i <= averagingPoints / 2; i++)
563 for (
int i = averagingPoints / 2 + 1; i < GetNumberOfPoints() - averagingPoints / 2; i++) {
564 sum -= this->GetData(i - (averagingPoints / 2 + 1));
565 sum += this->GetData(i + averagingPoints / 2);
569 for (
int i = GetNumberOfPoints() - averagingPoints / 2; i < GetNumberOfPoints(); i++)
573Double_t TRestDetectorSignal::GetBaseLine(Int_t startBin, Int_t endBin) {
574 if (endBin - startBin <= 0)
return 0.;
576 Double_t baseLine = 0;
577 for (
int i = startBin; i < endBin; i++) baseLine += fSignalCharge[i];
579 return baseLine / (endBin - startBin);
582Double_t TRestDetectorSignal::GetStandardDeviation(Int_t startBin, Int_t endBin) {
583 Double_t bL = GetBaseLine(startBin, endBin);
584 return GetBaseLineSigma(startBin, endBin, bL);
587Double_t TRestDetectorSignal::GetBaseLineSigma(Int_t startBin, Int_t endBin, Double_t baseline) {
588 Double_t bL = baseline;
589 if (bL == 0) bL = GetBaseLine(startBin, endBin);
591 Double_t baseLineSigma = 0;
592 for (
int i = startBin; i < endBin; i++)
593 baseLineSigma += (bL - fSignalCharge[i]) * (bL - fSignalCharge[i]);
595 return TMath::Sqrt(baseLineSigma / (endBin - startBin));
598Double_t TRestDetectorSignal::SubstractBaseline(Int_t startBin, Int_t endBin) {
599 Double_t bL = GetBaseLine(startBin, endBin);
606void TRestDetectorSignal::AddOffset(Double_t offset) {
607 for (
int i = 0; i < GetNumberOfPoints(); i++) fSignalCharge[i] = fSignalCharge[i] + offset;
610void TRestDetectorSignal::MultiplySignalBy(Double_t factor) {
611 for (
int i = 0; i < GetNumberOfPoints(); i++) fSignalCharge[i] = factor * fSignalCharge[i];
614void TRestDetectorSignal::ExponentialConvolution(Double_t fromTime, Double_t decayTime, Double_t offset) {
615 for (
int i = 0; i < GetNumberOfPoints(); i++) {
616 if (fSignalTime[i] > fromTime)
618 (fSignalCharge[i] - offset) * exp(-(fSignalTime[i] - fromTime) / decayTime) + offset;
623 if (this->GetNumberOfPoints() != inSgnl->GetNumberOfPoints()) {
624 cout <<
"ERROR : I cannot add two signals with different number of points" << endl;
628 Int_t badSignalTimes = 0;
630 for (
int i = 0; i < GetNumberOfPoints(); i++)
631 if (GetTime(i) != inSgnl->GetTime(i)) {
632 cout <<
"Time : " << GetTime(i) <<
" != " << inSgnl->GetTime(i) << endl;
636 if (badSignalTimes) {
637 cout <<
"ERROR : The times of signal addition must be the same" << endl;
641 for (
int i = 0; i < GetNumberOfPoints(); i++) fSignalCharge[i] += inSgnl->GetData(i);
644void TRestDetectorSignal::AddGaussianSignal(Double_t amp, Double_t sigma, Double_t time, Int_t N,
645 Double_t fromTime, Double_t toTime) {
646 for (
int i = 0; i < N; i++) {
647 Double_t tme = fromTime + (double)i / (N - 1) * (toTime - fromTime);
649 Double_t dta = 300 + amp * TMath::Exp(-0.5 * (tme - time) * (tme - time) / sigma / sigma);
651 cout <<
"T : " << tme <<
" D : " << dta << endl;
656void TRestDetectorSignal::GetWhiteNoiseSignal(
TRestDetectorSignal* noiseSgnl, Double_t noiseLevel) {
659 for (
int i = 0; i < GetNumberOfPoints(); i++) {
660 TRandom3* fRandom =
new TRandom3(0);
662 noiseSgnl->
IncreaseAmplitude(GetTime(i), GetData(i) + fRandom->Gaus(0, noiseLevel));
668void TRestDetectorSignal::GetSignalGaussianConvolution(
TRestDetectorSignal* convSgnl, Double_t sigma,
672 Int_t nPoints = GetMaxTime() - GetMinTime();
673 TF1* fGaus =
new TF1(
"fGauss",
"exp(-0.5*((x-[1])/[2])**2)", -nPoints, nPoints);
674 sigma = sigma * 1000.;
675 fGaus->SetParameter(2, sigma);
677 Double_t totChargeInitial = 0.;
678 Double_t totChargeFinal = 0.;
683 for (
int i = 0; i < GetNumberOfPoints(); i++) totChargeInitial += fSignalCharge[i];
686 for (
int i = GetMinTime() - nSigmas * sigma; i < GetMaxTime() + nSigmas * sigma; i++) {
687 for (
int j = 0; j < GetNumberOfPoints(); j++) {
688 if (TMath::Abs(i - GetTime(j)) > nSigmas * sigma)
continue;
689 if (TMath::Abs(i - GetTime(j)) > nSigmas * sigma && i < GetTime(j))
break;
691 fGaus->SetParameter(1, GetTime(j));
692 sum = fSignalCharge[j] / TMath::Sqrt(2. * TMath::Pi()) / sigma * fGaus->Integral(i, i + 1);
695 totChargeFinal += sum;
699 cout <<
"Initial charge of the pulse " << totChargeInitial << endl;
700 cout <<
"Final charge of the pulse " << totChargeFinal << endl;
703void TRestDetectorSignal::WriteSignalToTextFile(TString filename) {
704 FILE* fff = fopen(filename.Data(),
"w");
705 for (
int i = 0; i < GetNumberOfPoints(); i++) fprintf(fff,
"%e\t%e\n", GetTime(i), GetData(i));
709void TRestDetectorSignal::Print() {
710 for (
int i = 0; i < GetNumberOfPoints(); i++)
711 cout <<
"Time : " << GetTime(i) <<
" Charge : " << GetData(i) << endl;
714TGraph* TRestDetectorSignal::GetGraph(Int_t color) {
715 if (fGraph !=
nullptr) {
720 fGraph =
new TGraph();
725 fGraph->SetLineWidth(2);
726 fGraph->SetLineColor(color);
727 fGraph->SetMarkerStyle(7);
730 for (
int n = 0; n < GetNumberOfPoints(); n++) {
731 fGraph->SetPoint(points, GetTime(n), GetData(n));
void IncreaseAmplitude(TVector2 p)
If the point already exists inside the detector signal event, the amplitude value will be added to th...
void SetPoint(TVector2 p)
If the point already exists inside the detector signal event, it will be overwritten....