REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestRawSignalGeneralFitProcess.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 
61 #include "TRestRawSignalGeneralFitProcess.h"
62 
63 using namespace std;
64 
66 
71 
85  Initialize();
86 
87  if (LoadConfigFromFile(configFilename)) LoadDefaultConfig();
88 }
89 
94 
98 void TRestRawSignalGeneralFitProcess::LoadDefaultConfig() { SetTitle("Default config"); }
99 
105  SetSectionName(this->ClassName());
106  SetLibraryVersion(LIBRARY_VERSION);
107 
108  fRawSignalEvent = nullptr;
109 }
110 
123 void TRestRawSignalGeneralFitProcess::LoadConfig(const string& configFilename, const string& name) {
124  if (LoadConfigFromFile(configFilename, name)) LoadDefaultConfig();
125 }
126 
131  // fSignalFittingObservables = TRestEventProcess::ReadObservables();
132 }
133 
138  // no need for verbose copy now
139  fRawSignalEvent = (TRestRawSignalEvent*)inputEvent;
140 
141  RESTDebug << "TRestRawSignalGeneralFitProcess::ProcessEvent. Event ID : " << fRawSignalEvent->GetID()
142  << RESTendl;
143 
144  Double_t SigmaMean = 0;
145  vector<Double_t> Sigma(fRawSignalEvent->GetNumberOfSignals());
146  Double_t RatioSigmaMaxPeakMean = 0;
147  vector<Double_t> RatioSigmaMaxPeak(fRawSignalEvent->GetNumberOfSignals());
148  Double_t ChiSquareMean = 0;
149  vector<Double_t> ChiSquare(fRawSignalEvent->GetNumberOfSignals());
150 
151  /*map<int, Double_t> baselineFit;
152  map<int, Double_t> amplitudeFit;
153  map<int, Double_t> shapingtimeFit;
154  map<int, Double_t> peakpositionFit;
155 
156  baselineFit.clear();
157  amplitudeFit.clear();
158  shapingtimeFit.clear();
159  peakpositionFit.clear();*/
160 
161  if (fFitFunc) {
162  delete fFitFunc;
163  fFitFunc = nullptr;
164  }
165  fFitFunc = CreateTF1FromString(fFunction, fFunctionRange.X(), fFunctionRange.Y());
166 
167  std::vector<map<int, Double_t>> param(fFitFunc->GetNpar());
168  std::vector<map<int, Double_t>> paramErr(fFitFunc->GetNpar());
169 
170  for (int s = 0; s < fRawSignalEvent->GetNumberOfSignals(); s++) {
171  TRestRawSignal* singleSignal = fRawSignalEvent->GetSignal(s);
172 
173  int MaxPeakBin = singleSignal->GetMaxPeakBin();
174 
175  /*// ShaperSin function (AGET theoretic curve) times logistic function
176  TF1* f = new TF1("fit",
177  "[0]+[1]*TMath::Exp(-3. * (x-[3])/[2]) * "
178  "(x-[3])/[2] * (x-[3])/[2] * (x-[3])/[2] * "
179  "sin((x-[3])/[2])/(1+TMath::Exp(-10000*(x-[3])))",
180  0, 511);
181  f->SetParameters(0, 2000, 70, 80);
182  //f->SetParameters(0, 0); // Initial values adjusted from Desmos
183  //f->SetParLimits(0, 150, 350);
184  //f->SetParameters(1, 2000);
185  //f->SetParLimits(1, 30, 90000);
186  //f->SetParameters(2, 70);
187  //f->SetParLimits(2, 10, 80);
188  //f->SetParameters(3, 80);
189  //f->SetParLimits(3, 150, 250);
190  //f->FixParameter(2, 75);
191  f->SetParNames("Baseline", "Amplitude", "ShapingTime", "PeakPosition");*/
192 
193  // Create histogram from signal
194  Int_t nBins = singleSignal->GetNumberOfPoints();
195  TH1D* h = new TH1D("histo", "Signal to histo", nBins, 0, nBins);
196 
197  for (int i = 0; i < nBins; i++) {
198  h->Fill(i, singleSignal->GetRawData(i));
199  }
200 
201  // Fit histogram with ShaperSin
202  h->Fit(fFitFunc, "NWW", "", 0, 511); // Options: R->fit in range, N->No draw, Q->Quiet
203 
204  Double_t sigma = 0;
205  for (int j = fFunctionRange.X(); j < fFunctionRange.Y(); j++) {
206  sigma += (singleSignal->GetRawData(j) - fFitFunc->Eval(j)) *
207  (singleSignal->GetRawData(j) - fFitFunc->Eval(j));
208  }
209  Sigma[s] = TMath::Sqrt(sigma / (fFunctionRange.Y() - fFunctionRange.X()));
210  RatioSigmaMaxPeak[s] = Sigma[s] / singleSignal->GetRawData(MaxPeakBin);
211  RatioSigmaMaxPeakMean += RatioSigmaMaxPeak[s];
212  SigmaMean += Sigma[s];
213  ChiSquare[s] = fFitFunc->GetChisquare();
214  ChiSquareMean += ChiSquare[s];
215 
216  for (int i = 0; i < fFitFunc->GetNpar(); i++) {
217  param[i][singleSignal->GetID()] = fFitFunc->GetParameter(i);
218  paramErr[i][singleSignal->GetID()] = fFitFunc->GetParError(i);
219  RESTDebug << "Parameter " << i << ": " << param[i][singleSignal->GetID()] << RESTendl;
220  RESTDebug << "Error parameter " << i << ": " << paramErr[i][singleSignal->GetID()] << RESTendl;
221  }
222 
223  /*baselineFit[singleSignal->GetID()] = f->GetParameter(0);
224  amplitudeFit[singleSignal->GetID()] = f->GetParameter(1);
225  shapingtimeFit[singleSignal->GetID()] = f->GetParameter(2);
226  peakpositionFit[singleSignal->GetID()] = f->GetParameter(3);
227 
228  fShaping = f->GetParameter(2);
229  fStartPosition = f->GetParameter(3);
230  fBaseline = f->GetParameter(0);
231  fAmplitude = f->GetParameter(1);*/
232 
233  h->Delete();
234  }
235 
237  /*SetObservableValue("FitBaseline_map", baselineFit);
238  SetObservableValue("FitAmplitude_map", amplitudeFit);
239  SetObservableValue("FitShapingTime_map", shapingtimeFit);
240  SetObservableValue("FitPeakPosition_map", peakpositionFit);*/
241 
243  for (int i = 0; i < fFitFunc->GetNpar(); i++) {
244  SetObservableValue("Param_" + to_string(i) + "_map", param[i]);
245  SetObservableValue("ParamErr_" + to_string(i) + "_map", paramErr[i]);
246  }
247 
249  SigmaMean = SigmaMean / (fRawSignalEvent->GetNumberOfSignals());
250  SetObservableValue("FitSigmaMean", SigmaMean);
251 
253  Double_t sigmaMeanStdDev = 0;
254  for (int k = 0; k < fRawSignalEvent->GetNumberOfSignals(); k++) {
255  sigmaMeanStdDev += (Sigma[k] - SigmaMean) * (Sigma[k] - SigmaMean);
256  }
257  Double_t SigmaMeanStdDev = TMath::Sqrt(sigmaMeanStdDev / fRawSignalEvent->GetNumberOfSignals());
258  SetObservableValue("FitSigmaStdDev", SigmaMeanStdDev);
259 
261  ChiSquareMean = ChiSquareMean / fRawSignalEvent->GetNumberOfSignals();
262  SetObservableValue("FitChiSquareMean", ChiSquareMean);
263 
265  RatioSigmaMaxPeakMean = RatioSigmaMaxPeakMean / fRawSignalEvent->GetNumberOfSignals();
266  SetObservableValue("FitRatioSigmaMaxPeakMean", RatioSigmaMaxPeakMean);
267 
268  RESTDebug << "SigmaMean: " << SigmaMean << RESTendl;
269  RESTDebug << "SigmaMeanStdDev: " << SigmaMeanStdDev << RESTendl;
270  RESTDebug << "ChiSquareMean: " << ChiSquareMean << RESTendl;
271  RESTDebug << "RatioSigmaMaxPeakMean: " << RatioSigmaMaxPeakMean << RESTendl;
272  for (int k = 0; k < fRawSignalEvent->GetNumberOfSignals(); k++) {
273  RESTDebug << "Standard deviation of signal number " << k << ": " << Sigma[k] << RESTendl;
274  RESTDebug << "Chi square of fit signal number " << k << ": " << ChiSquare[k] << RESTendl;
275  RESTDebug << "Sandard deviation divided by amplitude of signal number " << k << ": "
276  << RatioSigmaMaxPeak[k] << RESTendl;
277  }
278 
281  // This will affect the calculation of observables, but not the stored
282  // TRestRawSignal data.
283  // fRawSignalEvent->SetBaseLineRange(fBaseLineRange);
284  // fRawSignalEvent->SetRange(fIntegralRange);
285 
286  /* Perhaps we want to identify the points over threshold where to apply the
287  fitting?
288  * Then, we might need to initialize points over threshold
289  *
290  for (int s = 0; s < fRawSignalEvent->GetNumberOfSignals(); s++) {
291  TRestRawSignal* sgnl = fRawSignalEvent->GetSignal(s);
292 
294  TRestRawSignal
295  sgnl->InitializePointsOverThreshold(TVector2(fPointThreshold,
296  fSignalThreshold),
297  fNPointsOverThreshold);
298 
299  }
300  */
301 
302  // If cut condition matches the event will be not registered.
303  if (ApplyCut()) return nullptr;
304 
305  return fRawSignalEvent;
306 }
307 
313  // Function to be executed once at the end of the process
314  // (after all events have been processed)
315 
316  // Start by calling the EndProcess function of the abstract class.
317  // Comment this if you don't want it.
318  // TRestEventProcess::EndProcess();
319  if (fFitFunc) {
320  delete fFitFunc;
321  fFitFunc = nullptr;
322  }
323 }
A base class for any REST event.
Definition: TRestEvent.h:38
An event container for time rawdata signals with fixed length.
void LoadDefaultConfig()
Function to load the default config in absence of RML input.
TRestEvent * ProcessEvent(TRestEvent *inputEvent) override
The main processing event function.
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.
void InitProcess() override
Process initialization.
void LoadConfig(const std::string &configFilename, const std::string &name="")
Function to load the configuration from an external configuration file.
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.
TF1 * CreateTF1FromString(std::string func, double init, double end)
Reads a function with parameter options from string and returns it as TF1*.