KaliVeda
Toolkit for HIC analysis
KVAlphaCalibration.cpp
1 /*
2  $Id: KVAlphaCalibration.h, v 1.0 2019/05/14 17:00:00 lemarie Exp $
3  $Revision: 1.0 $
4  $Date: 2019/05/14 17:00:00 $
5  $Author: lemarie $
6 */
7 
8 #include "KVAlphaCalibration.h"
9 
11 
12 
13 
16 {
17 
18  Init(NumberOfPeak_);
19 
20 }
21 
22 
23 
25 
27 {
28 
29  Init(NumberOfPeak_);
30  HistoInit(h);
31 
32 }
33 
34 
35 
38 
40 {
41  //Default destructor
42 }
43 
44 
45 
47 
48 void KVAlphaCalibration::HistoInit(TH1* h)
49 {
50 
51  Histo = h;
52  double min = Histo->GetBinCenter(h->GetMinimumBin());
53  double max = Histo->GetBinCenter(h->GetMaximumBin());
54  GaussianFit = new TF1("fitPeak", this, &KVAlphaCalibration::FunctionToFit, min, max, NumberOfPeak + 3, "KVAlphaCalibration", "FonctionToFit");
55 
56 }
57 
58 
59 
60 
62 
63 void KVAlphaCalibration::Init(int NumberOfPeak_)
64 {
65 
66  spec = new TSpectrum();
67 
68  factorGraph = new TGraph();
69  InitializationFit = new TF1("calib", "pol1", 0, 100);
70  SigmaOfTSpectrum = 1.;
71  ThresholdOfTSpectrum = 0.05;
72  NumberOfPeak = 0;
73 
74  if (NumberOfPeak_ <= 0) {
75  std::cerr << "ERROR in KVAlphaCalibration Constructor : The number of peak you want to fit has to be positive" << std::endl;
76  std::exit(1);
77  }
78  NumberOfPeak = NumberOfPeak_;
79 }
80 
81 
82 
86 
87 void KVAlphaCalibration::AddPeak(double Energy_, double Intensity_)
88 {
89 
90  //Set the energy and the normalization factor the peaks you want to fit.
91  //The normalization factor is only here to constrain the model
92 
93  if (Intensity_ <= 0) {
94  std::cerr << "ERROR in KVAlphaCalibration::SetPeak : Normalization factor can not be equal nor inferior to 0" << std::endl;
95  std::exit(1);
96  }
97 
98  MeanOfPeak.push_back(Energy_);
99  IntensityOfPeak.push_back(Intensity_);
100 
101 }
102 
103 
104 
107 
109 {
110 
111  //Set the histogram that contains the data
112  HistoInit(h);
113 
114 }
115 
116 
117 
119 
120 void KVAlphaCalibration::SetHistRange(double xmin, double xmax)
121 {
122 
123  Histo->GetXaxis()->SetRangeUser(xmin, xmax);
124 
125 }
126 
127 
128 
130 
131 void KVAlphaCalibration::SetParameters(double SigmaOfTSpectrum_, double SigmaOfGaussian_, double ThresholdOfTSpectrum_, double IsOriginAtZero_)
132 {
133 
134  if (SigmaOfTSpectrum_ <= 0) {
135  std::cerr << "ERROR in KVAlphaCalibration::SetParameters : SigmaOfTSpectrum can not be equal nor inferior to 0" << std::endl;
136  std::exit(1);
137  }
138 
139  SigmaOfTSpectrum = SigmaOfTSpectrum_;
140 
141  if (SigmaOfGaussian_ <= 0) {
142  std::cerr << "ERROR in KVAlphaCalibration::SetParameters : SigmaOfGaussian can not be equal nor inferior to 0" << std::endl;
143  std::exit(1);
144  }
145 
146  SigmaOfGaussian = SigmaOfGaussian_;
147 
148  if (ThresholdOfTSpectrum_ <= 0) {
149  std::cerr << "ERROR in KVAlphaCalibration::SetParameters : ThresholdOfTSpectrumOfTSpectrum can not be equal nor inferior to 0" << std::endl;
150  std::exit(1);
151  }
152 
153  IsOriginAtZero = IsOriginAtZero_;
154 
155  ThresholdOfTSpectrum = ThresholdOfTSpectrum_;
156 
157 }
158 
159 
160 
161 
162 
167 
169 {
170 
171  //Get the initialization parameter of the model.
172  //0 for the slope
173  //1 for the ordinate at the origin
174  if (j != 0 && j != 1) {
175  std::cerr << "ERROR in KVAlphaCalibration::GetLinerFitParameter : You asked for a wrong parameter value, it needs to be 1 or 0"
176  << std::endl
177  << "-> Ignoring command" << std::endl;
178  return 0.;
179 
180  }
181 
182  return InitializationFitResults[j];
183 
184 }
185 
186 
187 
194 
196 {
197  //Get the final parameter found by the model
198  //0 for the slope
199  //1 for the ordinate at the origin
200  //2 for the width factor. This factor needs to be multiplied by the energy of one peak in order to get his width
201  //3 - NumberOfPeak + 3 for the normalization factor
202 
203  if (j < 0 || j > NumberOfPeak + 2) {
204  std::cerr << "ERROR in KVAlphaCalibration::GetGaussianFitParameter : You asked for a wrong parameter value, it needs to be between 0 or "
205  << NumberOfPeak + 3
206  << std::endl
207  << "-> Ignoring command" << std::endl;
208  return 0.;
209 
210  }
211 
212  return GaussianFitResults[j];
213 
214 }
215 
216 
217 
224 
226 {
227  //Get the error of final parameter found by the model
228  //0 for the error of the slope
229  //1 for the error of the ordinate at the origin
230  //2 for the error of the width factor. This factor needs to be multiplied by the energy of one peak in order to get his width
231  //3 - NumberOfPeak + 3 for the error of the normalization factor
232 
233  if (j < 0 || j > NumberOfPeak + 2) {
234  std::cerr << "ERROR in KVAlphaCalibration::GetGaussianFitParameter : You asked for a wrong parameter value, it needs to be between 0 or "
235  << NumberOfPeak + 3
236  << std::endl
237  << "-> Ignoring command" << std::endl;
238  return 0.;
239 
240  }
241 
242  return GaussianFitResultsError[j];
243 
244 }
245 
246 
247 
248 // Fitting methods
249 
250 
253 
254 void KVAlphaCalibration::FitAll(bool debug_)
255 {
256 
257  //This function calls the FitInit and FitSpectrum function
258  FitInit(debug_);
259  FitSpectrum(debug_);
260 
261 }
262 
263 
264 
271 
273 {
274 
275  //This method find the peaks with a TSpectrum and fit their position to
276  //initialize the model
277  //The boolean is false by default, but it is advised to set it true in order to
278  //check if the TSpectrum find the right peaks. If not, change the parameter SigmaOfTSpectrum
279  //and ThresholdOfTSpectrum
280 
281  if (debug_) std::cerr << "DEBUG IN FitInit : Searching for peaks in histogram" << std::endl;
282  unsigned int npeaks = spec->Search(Histo, SigmaOfTSpectrum, "", ThresholdOfTSpectrum);
283 
284 #if ROOT_VERSION_CODE > ROOT_VERSION(5,99,01)
285  Double_t* xpos = spec->GetPositionX();
286 #else
287  Float_t* xpos = spec->GetPositionX();
288 #endif
289 
290  InitializationPeak.clear();
291  for (unsigned int i = 0; i < npeaks; i++) {
292  InitializationPeak.push_back(xpos[i]);
293  }
294 
295  std::sort(InitializationPeak.begin(), InitializationPeak.end());
296  std::sort(MeanOfPeak.begin(), MeanOfPeak.end());
297  std::sort(IntensityOfPeak.begin(), IntensityOfPeak.end());
298 
299  if (debug_) std::cerr << "DEBUG IN FitInit : Number of peaks found is " << spec->GetNPeaks() << std::endl;
300  // if (debug_) if (spec->GetNPeaks() != NumberOfPeak) std::cerr << "DEBUG IN FitInit : Number of peaks different from the one you asked"
301  // << "-> Ignoring histogram" << std::endl
302  // << "Please modify your TSpectrum parameters (aka SigmaOfTSpectrum and ThresholdOfTSpectrumOfTSpectrum)" << std::endl;
303  //In mode debug it will also print the result of the linear fit in the terminal
304  if (spec->GetNPeaks() == NumberOfPeak) {
305 
306  for (int i = 0; i < NumberOfPeak; i++) {
307  if (debug_) std::cerr << "DEBUG IN FitInit : Peak position number " << i << " = " << InitializationPeak[i] << std::endl;
308  factorGraph->SetPoint(i, MeanOfPeak[i], InitializationPeak[i]);
309  }
310 
311  if (debug_) std::cerr << "DEBUG IN FitInit : Initializing Parameters" << std::endl;
312 
313  InitializationFit->SetParameter(0, 1);
314  InitializationFit->SetParameter(1, xpos[0] / MeanOfPeak[0]);
315 
316  if (debug_) std::cerr << "DEBUG IN FitInit : Fitting" << std::endl;
317  factorGraph->SetMarkerStyle(5);
318  factorGraph->Fit("calib", "Q");
319  if (debug_) std::cerr << "DEBUG IN FitInit : Fitting done" << std::endl;
320 
321  if (debug_) std::cerr << "DEBUG IN FitInit : Writing fit output in InitializationFitResults array" << std::endl;
322  InitializationFitResults[0] = InitializationFit->GetParameter(0);
323 
324  InitializationFitResults[1] = InitializationFit->GetParameter(1);
325  }
326 
327  if (debug_) std::cerr << "DEBUG IN FitInit : Ending FitInit" << std::endl;
328  return factorGraph;
329 }
330 
331 
332 
337 
339 {
340 
341  //This methods will use the model and fit the peaks in the histogram with
342  // a gaussian in order to get a very accurate calibration
343  //It also print the results at the end of the fit
344 
345  std::vector<double> GaussianFitResultsTemp;
346  std::vector<double> GaussianFitResultsErrorTemp;
347 
348  if (debug_) std::cerr << "Entering FitSpectrum method" << std::endl;
349  if (debug_) std::cerr << "Setting Parameters" << std::endl;
350 
351  std::cout << &InitializationFitResults/*[1] << " " << InitializationFitResults[0] */ << std::endl;
352  GaussianFit->SetParameter(0, InitializationFitResults[1]);
353 
354  if (IsOriginAtZero) {
355 
356  GaussianFit->FixParameter(1, 0);
357 
358  }
359  else {
360 
361  GaussianFit->SetParameter(1, InitializationFitResults[0]);
362 
363  }
364 
365  GaussianFit->SetParameter(2, SigmaOfGaussian);
366  GaussianFit->SetNpx(1000);
367 
368  if (debug_) std::cerr << "Setting Normalization factors" << std::endl;
369  for (int i = 0; i < NumberOfPeak; i++) {
370 
371  GaussianFit->SetParameter(i + 3, IntensityOfPeak[i]);
372 
373  }
374 
375  if (debug_) {
376  std::cerr << "Fitting" << std::endl;
377  Histo->Fit("fitPeak");
378  std::cerr << "FitEnded" << std::endl;
379  }
380  else Histo->Fit("fitPeak", "Q");
381 
382 
383  GaussianFitResults.clear();
384  GaussianFitResultsError.clear();
385  GaussianFitResultsTemp.clear();
386  GaussianFitResultsErrorTemp.clear();
387 
388  for (int i = 0; i < NumberOfPeak + 3; i++) {
389 
390  GaussianFitResultsTemp.push_back(GaussianFit->GetParameter(i));
391  GaussianFitResultsErrorTemp.push_back(GaussianFit->GetParError(i));
392  }
393 
394 
395  GaussianFitResults.push_back(1 / GaussianFitResultsTemp[0]);
396  GaussianFitResults.push_back(-GaussianFitResultsTemp[1] / GaussianFitResultsTemp[0]);
397 
398  GaussianFitResults.push_back(GaussianFitResultsTemp[2] / GaussianFitResultsTemp[0]);
399 
400  GaussianFitResultsError.push_back(GaussianFitResultsErrorTemp[0] / GaussianFitResultsTemp[0]);
401  GaussianFitResultsError.push_back(GaussianFitResultsTemp[1] * 0.02);
402  GaussianFitResultsError.push_back(GaussianFitResultsErrorTemp[2] / GaussianFitResultsTemp[0]);
403 
404  for (int i = 3; i < NumberOfPeak + 3; i++) {
405 
406  GaussianFitResults.push_back(GaussianFitResultsTemp[i]);
407  GaussianFitResultsError.push_back(GaussianFitResultsErrorTemp[i]);
408  }
409 
410  if (debug_) std::cerr << "FitSpectrum ended" << std::endl;
411  PrintResult();
412 
413 }
414 
415 
416 
420 
421 double KVAlphaCalibration::FunctionToFit(double* x, double* par)
422 {
423 
424  //Model called by the FitSpectrum method. Can not be called by the user
425  //It consist in a sum of gaussian. The number is the number of peak given by the user
426 
427  double gauss[NumberOfPeak];
428  double factor_ = par[0];
429  double result = 0;
430  double S = par[2];
431  double b = par[1];
432 
433 
434  for (int i = 0; i < NumberOfPeak; i++) {
435 
436  gauss[i] = par[i + 3] / MeanOfPeak[i] * S * TMath::Sqrt(2 * TMath::Pi())
437  * TMath::Exp(-TMath::Power(x[0] - factor_ * MeanOfPeak[i] - b, 2) / (2 * TMath::Power(S, 2)));
438  result += gauss[i];
439 
440  }
441 
442  return result;
443 
444 }
445 
446 
447 
448 // Drawing and printing results
449 
450 
452 
453 void KVAlphaCalibration::DrawResult(bool WhatToDraw)
454 {
455 
456  if (WhatToDraw) {
457 
458  Histo->Draw();
459  GaussianFit->Draw("same");
460 
461  std::cout << "Conversion factor : " << GaussianFitResults[0] << std::endl
462  << " Y at x = 0 : " << GaussianFitResults[1] << std::endl
463  << "Sigma Factor : " << GaussianFitResults[2] << std::endl;
464 
465  for (int i = 3; i < NumberOfPeak + 3; i++) {
466 
467  std::cout << " Normalization factor " << i << " : " << GaussianFitResults[i] << std::endl;
468 
469  }
470 
471  }
472  else
473 
474  factorGraph->Draw();
475 
476 }
477 
478 
479 
480 
482 
484 {
485 
486  std::cout << "Slope : " << GaussianFitResults[0] << std::endl
487  << "Y at x = 0 : " << GaussianFitResults[1] << std::endl
488  << "Peak width factor : " << GaussianFitResults[2] << std::endl;
489 
490 }
491 
492 
float Float_t
double Double_t
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t b
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t result
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void xpos
float xmin
float xmax
Set up and run the calibration of siliciums.
void AddPeak(double Energy_, double Intensity_)
void SetHistRange(double xmin, double xmax)
double GetGaussianFitParError(int)
void FitSpectrum(bool debug_=false)
~KVAlphaCalibration()
Default destructor.
double GetGaussianFitParameter(int)
void DrawResult(bool WhatToDraw=true)
double GetInitializationFitParameter(int)
void FitAll(bool debug_=false)
This function calls the FitInit and FitSpectrum function.
void SetParameters(double SigmaOfTSpectrum_=1., double SigmaOfGaussian_=1., double ThresholdOfTSpectrum_=0.5, double IsOriginAtZero_=false)
KVAlphaCalibration(int NumberOfPeak_)
void SetHisto(TH1 *h)
Set the histogram that contains the data.
TGraph * FitInit(bool debug_=false)
virtual void SetMarkerStyle(Style_t mstyle=1)
virtual void SetRangeUser(Double_t ufirst, Double_t ulast)
virtual Double_t GetParameter(const TString &name) const
virtual Double_t GetParError(Int_t ipar) const
virtual void SetNpx(Int_t npx=100)
void Draw(Option_t *option="") override
virtual void SetParameter(const TString &name, Double_t value)
virtual void FixParameter(Int_t ipar, Double_t value)
virtual void SetPoint(Int_t i, Double_t x, Double_t y)
virtual TFitResultPtr Fit(const char *formula, Option_t *option="", Option_t *goption="", Axis_t xmin=0, Axis_t xmax=0)
void Draw(Option_t *chopt="") override
virtual Double_t GetBinCenter(Int_t bin) const
TAxis * GetXaxis()
virtual TFitResultPtr Fit(const char *formula, Option_t *option="", Option_t *goption="", Double_t xmin=0, Double_t xmax=0)
void Draw(Option_t *option="") override
virtual Int_t GetMaximumBin() const
virtual Int_t GetMinimumBin() const
virtual Int_t Search(const TH1 *hist, Double_t sigma=2, Option_t *option="", Double_t threshold=0.05)
Int_t GetNPeaks() const
Double_t * GetPositionX() const
TH1 * h
void Init()
RooArgSet S(Args_t &&... args)
double min(double x, double y)
double max(double x, double y)
Double_t Exp(Double_t x)
Double_t Power(Double_t x, Double_t y)
Double_t Sqrt(Double_t x)
constexpr Double_t Pi()
ClassImp(TPyArg)