KaliVeda  1.12/06
Heavy-Ion Analysis Toolkit
KVAlphaCalibration.cpp
Go to the documentation of this file.
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 
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 
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 
293  InitializationPeak.push_back(xpos[i]);
294  }
295 
296  std::sort(InitializationPeak.begin(), InitializationPeak.end());
297  std::sort(MeanOfPeak.begin(), MeanOfPeak.end());
298  std::sort(IntensityOfPeak.begin(), IntensityOfPeak.end());
299 
300  if (debug_) std::cerr << "DEBUG IN FitInit : Number of peaks found is " << spec->GetNPeaks() << std::endl;
301  if (debug_) if (spec->GetNPeaks() != NumberOfPeak) std::cerr << "DEBUG IN FitInit : Number of peaks different from the one you asked"
302  << "-> Ignoring histogram" << std::endl
303  << "Please modify your TSpectrum parameters (aka SigmaOfTSpectrum and ThresholdOfTSpectrumOfTSpectrum)" << std::endl;
304  //In mode debug it will also print the result of the linear fit in the terminal
305  if (spec->GetNPeaks() == NumberOfPeak) {
306 
307  for (int i = 0; i < NumberOfPeak; i++) {
308 
309  if (debug_) std::cerr << "DEBUG IN FitInit : Peak position number " << i << " = " << InitializationPeak[i] << std::endl;
311 
312  }
313 
314 
315  if (debug_) std::cerr << "DEBUG IN FitInit : Initializing Parameters" << std::endl;
316 
318  InitializationFit->SetParameter(1, xpos[0] / MeanOfPeak[0]);
319 
320  if (debug_) std::cerr << "DEBUG IN FitInit : Fitting" << std::endl;
322  factorGraph->Fit("calib", "Q");
323  if (debug_) std::cerr << "DEBUG IN FitInit : Fitting done" << std::endl;
324 
325  if (debug_) std::cerr << "DEBUG IN FitInit : Writing fit output in InitializationFitResults array" << std::endl;
327 
329 
330  }
331 
332  if (debug_) std::cerr << "DEBUG IN FitInit : Ending FitInit" << std::endl;
333 }
334 
335 
336 
341 
343 {
344 
345  //This methods will use the model and fit the peaks in the histogram with
346  // a gaussian in order to get a very accurate calibration
347  //It also print the results at the end of the fit
348 
349  std::vector<double> GaussianFitResultsTemp;
350  std::vector<double> GaussianFitResultsErrorTemp;
351 
352  if (debug_) std::cerr << "Entering FitSpectrum method" << std::endl;
353  if (debug_) std::cerr << "Setting Parameters" << std::endl;
354 
355  std::cout << &InitializationFitResults/*[1] << " " << InitializationFitResults[0] */ << std::endl;
357 
358  if (IsOriginAtZero) {
359 
360  GaussianFit->FixParameter(1, 0);
361 
362  }
363  else {
364 
366 
367  }
368 
370  GaussianFit->SetNpx(1000);
371 
372  if (debug_) std::cerr << "Setting Normalization factors" << std::endl;
373  for (int i = 0; i < NumberOfPeak; i++) {
374 
376 
377  }
378 
379  if (debug_) {
380  std::cerr << "Fitting" << std::endl;
381  Histo->Fit("fitPeak");
382  std::cerr << "FitEnded" << std::endl;
383  }
384  else Histo->Fit("fitPeak", "Q");
385 
386 
387  GaussianFitResults.clear();
388  GaussianFitResultsError.clear();
389  GaussianFitResultsTemp.clear();
390  GaussianFitResultsErrorTemp.clear();
391 
392  for (int i = 0; i < NumberOfPeak + 3; i++) {
393 
394  GaussianFitResultsTemp.push_back(GaussianFit->GetParameter(i));
395  GaussianFitResultsErrorTemp.push_back(GaussianFit->GetParError(i));
396  }
397 
398 
399  GaussianFitResults.push_back(1 / GaussianFitResultsTemp[0]);
400  GaussianFitResults.push_back(-GaussianFitResultsTemp[1] / GaussianFitResultsTemp[0]);
401 
402  GaussianFitResults.push_back(GaussianFitResultsTemp[2] / GaussianFitResultsTemp[0]);
403 
404  GaussianFitResultsError.push_back(GaussianFitResultsErrorTemp[0] / GaussianFitResultsTemp[0]);
405  GaussianFitResultsError.push_back(GaussianFitResultsTemp[1] * 0.02);
406  GaussianFitResultsError.push_back(GaussianFitResultsErrorTemp[2] / GaussianFitResultsTemp[0]);
407 
408  for (int i = 3; i < NumberOfPeak + 3; i++) {
409 
410  GaussianFitResults.push_back(GaussianFitResultsTemp[i]);
411  GaussianFitResultsError.push_back(GaussianFitResultsErrorTemp[i]);
412  }
413 
414  if (debug_) std::cerr << "FitSpectrum ended" << std::endl;
415  PrintResult();
416 
417 }
418 
419 
420 
424 
425 double KVAlphaCalibration::FunctionToFit(double* x, double* par)
426 {
427 
428  //Model called by the FitSpectrum method. Can not be called by the user
429  //It consist in a sum of gaussian. The number is the number of peak given by the user
430 
431  double gauss[NumberOfPeak];
432  double factor_ = par[0];
433  double result = 0;
434  double S = par[2];
435  double b = par[1];
436 
437 
438  for (int i = 0; i < NumberOfPeak; i++) {
439 
440  gauss[i] = par[i + 3] / MeanOfPeak[i] * S * TMath::Sqrt(2 * TMath::Pi())
441  * TMath::Exp(-TMath::Power(x[0] - factor_ * MeanOfPeak[i] - b, 2) / (2 * TMath::Power(S, 2)));
442  result += gauss[i];
443 
444  }
445 
446  return result;
447 
448 }
449 
450 
451 
452 // Drawing and printing results
453 
454 
456 
457 void KVAlphaCalibration::DrawResult(bool WhatToDraw)
458 {
459 
460  if (WhatToDraw) {
461 
462  Histo->Draw();
463  GaussianFit->Draw("same");
464 
465  std::cout << "Conversion factor : " << GaussianFitResults[0] << std::endl
466  << " Y at x = 0 : " << GaussianFitResults[1] << std::endl
467  << "Sigma Factor : " << GaussianFitResults[2] << std::endl;
468 
469  for (int i = 3; i < NumberOfPeak + 3; i++) {
470 
471  std::cout << " Normalization factor " << i << " : " << GaussianFitResults[i] << std::endl;
472 
473  }
474 
475  }
476  else
477 
478  factorGraph->Draw();
479 
480 }
481 
482 
483 
484 
486 
488 {
489 
490  std::cout << "Slope : " << GaussianFitResults[0] << std::endl
491  << "Y at x = 0 : " << GaussianFitResults[1] << std::endl
492  << "Peak width factor : " << GaussianFitResults[2] << std::endl;
493 
494 }
495 
496 
ClassImp(KVPartitionList) void KVPartitionList
Initialisation.
#define b(i)
double Double_t
float Float_t
float xmin
float xmax
Set up and run the calibration of siliciums.
void AddPeak(double Energy_, double Intensity_)
void FitInit(bool debug_=false)
void SetHistRange(double xmin, double xmax)
double FunctionToFit(double *x, double *par)
double GetGaussianFitParError(int)
void FitSpectrum(bool debug_=false)
double InitializationFitResults[2]
Array that contain the results of the initialization fit.
~KVAlphaCalibration()
Default destructor.
std::vector< double > GaussianFitResults
Array that contains results of the final fit.
double SigmaOfTSpectrum
Width of the peaks that TSpectrum will search, chosen by user.
TF1 * GaussianFit
function that will fit the peaks
std::vector< double > IntensityOfPeak
array of peaks amlitude. Set by user
double GetGaussianFitParameter(int)
std::vector< double > InitializationPeak
TH1 * Histo
histogram that contains the data to fit. Set by user
void DrawResult(bool WhatToDraw=true)
double GetInitializationFitParameter(int)
TF1 * InitializationFit
function that will do the initial fit
std::vector< double > MeanOfPeak
array peaks energy. Set by user
double ThresholdOfTSpectrum
Lowest peak that the TSpectrum has to search for. It is the ratio of the highest peak that the TSpect...
void FitAll(bool debug_=false)
This function calls the FitInit and FitSpectrum function.
TSpectrum * spec
the method that will search for peaks
std::vector< double > GaussianFitResultsError
Array that contains the error of the results of the final fit.
void SetParameters(double SigmaOfTSpectrum_=1., double SigmaOfGaussian_=1., double ThresholdOfTSpectrum_=0.5, double IsOriginAtZero_=false)
KVAlphaCalibration(int NumberOfPeak_)
int NumberOfPeak
Number of Peak present in the histogram. Chose by user.
double SigmaOfGaussian
Width of the peak that the model will fit chosen by user. It is possible that it has to be different ...
TGraph * factorGraph
Graph where the initial fit is done.
void SetHisto(TH1 *h)
Set the histogram that contains the data.
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)
virtual void Draw(Option_t *option="")
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)
virtual void Draw(Option_t *chopt="")
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)
virtual void Draw(Option_t *option="")
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)
Double_t * GetPositionX() const
Int_t GetNPeaks() const
Double_t x[n]
TH1 * h
void Init()
RooArgSet S(Args_t &&... args)
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()