KaliVeda  1.13/01
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  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;
309  }
310 
311  if (debug_) std::cerr << "DEBUG IN FitInit : Initializing Parameters" << std::endl;
312 
314  InitializationFit->SetParameter(1, xpos[0] / MeanOfPeak[0]);
315 
316  if (debug_) std::cerr << "DEBUG IN FitInit : Fitting" << std::endl;
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;
323 
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;
353 
354  if (IsOriginAtZero) {
355 
356  GaussianFit->FixParameter(1, 0);
357 
358  }
359  else {
360 
362 
363  }
364 
366  GaussianFit->SetNpx(1000);
367 
368  if (debug_) std::cerr << "Setting Normalization factors" << std::endl;
369  for (int i = 0; i < NumberOfPeak; i++) {
370 
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 
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 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.
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)
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()