REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestRawSignalFittingProcess.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 
99 #include "TRestRawSignalFittingProcess.h"
100 
101 using namespace std;
102 
104 
109 
123  Initialize();
124 
125  if (LoadConfigFromFile(configFilename)) LoadDefaultConfig();
126 }
127 
132 
136 void TRestRawSignalFittingProcess::LoadDefaultConfig() { SetTitle("Default config"); }
137 
143  SetSectionName(this->ClassName());
144  SetLibraryVersion(LIBRARY_VERSION);
145 
146  fRawSignalEvent = nullptr;
147 }
148 
161 void TRestRawSignalFittingProcess::LoadConfig(const string& configFilename, const string& name) {
162  if (LoadConfigFromFile(configFilename, name)) LoadDefaultConfig();
163 }
164 
169  // fSignalFittingObservables = TRestEventProcess::ReadObservables();
170 }
171 
176  // no need for verbose copy now
177  fRawSignalEvent = (TRestRawSignalEvent*)inputEvent;
178 
179  RESTDebug << "TRestRawSignalFittingProcess::ProcessEvent. Event ID : " << fRawSignalEvent->GetID()
180  << RESTendl;
181 
182  Double_t SigmaMean = 0;
183  vector<Double_t> Sigma(fRawSignalEvent->GetNumberOfSignals());
184  Double_t RatioSigmaMaxPeakMean = 0;
185  vector<Double_t> RatioSigmaMaxPeak(fRawSignalEvent->GetNumberOfSignals());
186  Double_t ChiSquareMean = 0;
187  vector<Double_t> ChiSquare(fRawSignalEvent->GetNumberOfSignals());
188 
189  map<int, Double_t> baselineFit;
190  map<int, Double_t> amplitudeFit;
191  map<int, Double_t> shapingTimeFit;
192  map<int, Double_t> peakPositionFit;
193 
194  baselineFit.clear();
195  amplitudeFit.clear();
196  shapingTimeFit.clear();
197  peakPositionFit.clear();
198 
199  for (int s = 0; s < fRawSignalEvent->GetNumberOfSignals(); s++) {
200  TRestRawSignal* singleSignal = fRawSignalEvent->GetSignal(s);
201 
202  int MaxPeakBin = singleSignal->GetMaxPeakBin();
203 
204  // ShaperSin function (AGET theoretic curve) times logistic function
205  TF1* f = new TF1("fit",
206  "[0]+[1]*TMath::Exp(-3. * (x-[3])/[2]) * "
207  "(x-[3])/[2] * (x-[3])/[2] * (x-[3])/[2] * "
208  "sin((x-[3])/[2])/(1+TMath::Exp(-10000*(x-[3])))",
209  0, 511);
210  f->SetParameters(0, 2000, 70, 80);
211  // f->SetParameters(0, 0); // Initial values adjusted from Desmos
212  // f->SetParLimits(0, 150, 350);
213  // f->SetParameters(1, 2000);
214  // f->SetParLimits(1, 30, 90000);
215  // f->SetParameters(2, 70);
216  // f->SetParLimits(2, 10, 80);
217  // f->SetParameters(3, 80);
218  // f->SetParLimits(3, 150, 250);
219  f->SetParNames("Baseline", "Amplitude", "ShapingTime", "PeakPosition");
220 
221  // Create histogram from signal
222  Int_t nBins = singleSignal->GetNumberOfPoints();
223  TH1D* h = new TH1D("histo", "Signal to histo", nBins, 0, nBins);
224 
225  for (int i = 0; i < nBins; i++) {
226  h->Fill(i, singleSignal->GetRawData(i));
227  }
228 
229  // Fit histogram with ShaperSin
230  h->Fit(f, "NWW", "", 0, 511); // Options: R->fit in range, N->No draw, Q->Quiet
231 
232  Double_t sigma = 0;
233  for (int j = MaxPeakBin - 145; j < MaxPeakBin + 165; j++) {
234  sigma += (singleSignal->GetRawData(j) - f->Eval(j)) * (singleSignal->GetRawData(j) - f->Eval(j));
235  }
236  Sigma[s] = TMath::Sqrt(sigma / (145 + 165));
237  RatioSigmaMaxPeak[s] = Sigma[s] / singleSignal->GetRawData(MaxPeakBin);
238  RatioSigmaMaxPeakMean += RatioSigmaMaxPeak[s];
239  SigmaMean += Sigma[s];
240  ChiSquare[s] = f->GetChisquare();
241  ChiSquareMean += ChiSquare[s];
242 
243  baselineFit[singleSignal->GetID()] = f->GetParameter(0);
244  amplitudeFit[singleSignal->GetID()] = f->GetParameter(1);
245  shapingTimeFit[singleSignal->GetID()] = f->GetParameter(2);
246  peakPositionFit[singleSignal->GetID()] = f->GetParameter(3);
247 
248  fShaping = f->GetParameter(2);
249  fStartPosition = f->GetParameter(3);
250  fBaseline = f->GetParameter(0);
251  fAmplitude = f->GetParameter(1);
252 
253  h->Delete();
254  }
255 
257  SetObservableValue("FitBaseline_map", baselineFit);
258  SetObservableValue("FitAmplitude_map", amplitudeFit);
259  SetObservableValue("FitShapingTime_map", shapingTimeFit);
260  SetObservableValue("FitPeakPosition_map", peakPositionFit);
261 
263  SigmaMean = SigmaMean / (fRawSignalEvent->GetNumberOfSignals());
264  SetObservableValue("FitSigmaMean", SigmaMean);
265 
267  Double_t sigmaMeanStdDev = 0;
268  for (int k = 0; k < fRawSignalEvent->GetNumberOfSignals(); k++) {
269  sigmaMeanStdDev += (Sigma[k] - SigmaMean) * (Sigma[k] - SigmaMean);
270  }
271  Double_t SigmaMeanStdDev = TMath::Sqrt(sigmaMeanStdDev / fRawSignalEvent->GetNumberOfSignals());
272  SetObservableValue("FitSigmaStdDev", SigmaMeanStdDev);
273 
275  ChiSquareMean = ChiSquareMean / fRawSignalEvent->GetNumberOfSignals();
276  SetObservableValue("FitChiSquareMean", ChiSquareMean);
277 
279  RatioSigmaMaxPeakMean = RatioSigmaMaxPeakMean / fRawSignalEvent->GetNumberOfSignals();
280  SetObservableValue("FitRatioSigmaMaxPeakMean", RatioSigmaMaxPeakMean);
281 
282  RESTDebug << "SigmaMean: " << SigmaMean << RESTendl;
283  RESTDebug << "SigmaMeanStdDev: " << SigmaMeanStdDev << RESTendl;
284  RESTDebug << "ChiSquareMean: " << ChiSquareMean << RESTendl;
285  RESTDebug << "RatioSigmaMaxPeakMean: " << RatioSigmaMaxPeakMean << RESTendl;
286  for (int k = 0; k < fRawSignalEvent->GetNumberOfSignals(); k++) {
287  RESTDebug << "Standard deviation of signal number " << k << ": " << Sigma[k] << RESTendl;
288  RESTDebug << "Chi square of fit signal number " << k << ": " << ChiSquare[k] << RESTendl;
289  RESTDebug << "Sandard deviation divided by amplitude of signal number " << k << ": "
290  << RatioSigmaMaxPeak[k] << RESTendl;
291  }
292 
295  // This will affect the calculation of observables, but not the stored
296  // TRestRawSignal data.
297  // fRawSignalEvent->SetBaseLineRange(fBaseLineRange);
298  // fRawSignalEvent->SetRange(fIntegralRange);
299 
300  /* Perhaps we want to identify the points over threshold where to apply the
301  fitting?
302  * Then, we might need to initialize points over threshold
303  *
304  for (int s = 0; s < fRawSignalEvent->GetNumberOfSignals(); s++) {
305  TRestRawSignal* sgnl = fRawSignalEvent->GetSignal(s);
306 
308  TRestRawSignal
309  sgnl->InitializePointsOverThreshold(TVector2(fPointThreshold,
310  fSignalThreshold),
311  fNPointsOverThreshold);
312 
313  }
314  */
315 
316  // If cut condition matches the event will be not registered.
317  if (ApplyCut()) return nullptr;
318 
319  return fRawSignalEvent;
320 }
321 
327  // Function to be executed once at the end of the process
328  // (after all events have been processed)
329 
330  // Start by calling the EndProcess function of the abstract class.
331  // Comment this if you don't want it.
332  // TRestEventProcess::EndProcess();
333 }
A base class for any REST event.
Definition: TRestEvent.h:38
An event container for time rawdata signals with fixed length.
void InitProcess() override
Process initialization.
void LoadDefaultConfig()
Function to load the default config in absence of RML input.
void LoadConfig(const std::string &configFilename, const std::string &name="")
Function to load the configuration from an external configuration file.
void EndProcess() override
Function to include required actions after all events have been processed. This method will write the...
void Initialize() override
Function to initialize input/output event members and define the section name.
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
The main processing event function.
It defines a Short_t array with a physical parameter that evolves in time using a fixed time bin.
Int_t GetID() const
Returns the value of signal ID.
Double_t GetRawData(Int_t n) const
It returns the original data value of point n without baseline correction.
Int_t GetMaxPeakBin()
It returns the bin at which the maximum peak amplitude happens.
Int_t GetNumberOfPoints() const
Returns the actual number of points, or size of the signal.