CMS 3D CMS Logo

FitWithRooFit.cc
Go to the documentation of this file.
1 #ifndef FitWithRooFit_cc
2 #define FitWithRooFit_cc
3 
4 #ifndef __CINT__
5 #include "RooGlobalFunc.h"
6 #endif
7 #include "TCanvas.h"
8 #include "TTree.h"
9 #include "TH1D.h"
10 #include "TRandom.h"
11 #include "RooRealVar.h"
12 #include "RooDataSet.h"
13 #include "RooGaussian.h"
14 #include "RooVoigtian.h"
15 #include "RooExponential.h"
16 #include "RooPlot.h"
17 #include "RooDataHist.h"
18 #include "RooAddPdf.h"
19 #include "RooChebychev.h"
20 #include "RooGenericPdf.h"
21 #include "RooGaussModel.h"
22 #include "RooAddModel.h"
23 #include "RooPolynomial.h"
24 #include "RooCBShape.h"
25 #include "RooMinimizer.h"
26 #include "RooBreitWigner.h"
27 #include "RooFFTConvPdf.h"
28 
47 namespace {
48  typedef std::pair<RooRealVar, RooDataHist*> rooPair;
49 }
50 
52 public:
54  : useChi2_(false),
55  mean_(nullptr),
56  mean2_(nullptr),
57  mean3_(nullptr),
58  sigma_(nullptr),
59  sigma2_(nullptr),
60  sigma3_(nullptr),
61  gamma_(nullptr),
62  gaussFrac_(nullptr),
63  gaussFrac2_(nullptr),
64  expCoeffa0_(nullptr),
65  expCoeffa1_(nullptr),
66  expCoeffa2_(nullptr),
67  fsig_(nullptr),
68  a0_(nullptr),
69  a1_(nullptr),
70  a2_(nullptr),
71  a3_(nullptr),
72  a4_(nullptr),
73  a5_(nullptr),
74  a6_(nullptr),
75  alpha_(nullptr),
76  n_(nullptr),
77  fGCB_(nullptr) {}
78 
79  // Import TH1 histogram into a RooDataHist
80  rooPair importTH1(TH1* histo, const double& inputXmin, const double& inputXmax) {
81  double xMin = inputXmin;
82  double xMax = inputXmax;
83  if ((xMin == xMax) && xMin == 0) {
84  xMin = histo->GetXaxis()->GetXmin();
85  xMax = histo->GetXaxis()->GetXmax();
86  }
87  // Declare observable x
88  RooRealVar x("x", "x", xMin, xMax);
89  // Create a binned dataset that imports contents of TH1 and associates its contents to observable 'x'
90  return (std::make_pair(x, new RooDataHist("dh", "dh", x, RooFit::Import(*histo))));
91  }
92 
93  // Plot and fit a RooDataHist fitting signal and background
94  void fit(TH1* histo,
95  const TString signalType,
96  const TString backgroundType,
97  const double& xMin = 0.,
98  const double& xMax = 0.,
99  bool sumW2Error = false) {
101 
102  rooPair imported = importTH1(histo, xMin, xMax);
103  RooRealVar x(imported.first);
104  RooDataHist* dh = imported.second;
105 
106  // Make plot of binned dataset showing Poisson error bars (RooFit default)
107  RooPlot* frame = x.frame(RooFit::Title("Imported TH1 with Poisson error bars"));
108  frame->SetName(TString(histo->GetName()) + "_frame");
109  dh->plotOn(frame);
110 
111  // Build the composite model
112  RooAbsPdf* model = buildModel(&x, signalType, backgroundType);
113 
114  std::unique_ptr<RooAbsReal> chi2{model->createChi2(*dh, RooFit::DataError(RooAbsData::SumW2))};
115 
116  // Fit the composite model
117  // -----------------------
118  // Fit with likelihood
119  if (!useChi2_) {
120  if (sumW2Error)
121  model->fitTo(*dh, RooFit::Save(), RooFit::SumW2Error(kTRUE));
122  else
123  model->fitTo(*dh);
124  }
125  // Fit with chi^2
126  else {
127  std::cout << "FITTING WITH CHI^2" << std::endl;
128  RooMinimizer m(*chi2);
129  m.migrad();
130  m.hesse();
131  // RooFitResult* r_chi2_wgt = m.save();
132  }
133  model->plotOn(frame);
134  model->plotOn(frame, RooFit::Components(backgroundType), RooFit::LineStyle(kDotted), RooFit::LineColor(kRed));
135  model->paramOn(frame, RooFit::Label("fit result"), RooFit::Format("NEU", RooFit::AutoPrecision(2)));
136 
137  // TODO: fix next lines to get the prob(chi2) (ndof should be dynamically set according to the choosen pdf)
138  // double chi2 = xframe.chiSquare("model","data",ndof);
139  // double ndoff = xframeGetNbinsX();
140  // double chi2prob = TMath::Prob(chi2,ndoff);
141 
142  // P l o t a n d f i t a R o o D a t a H i s t w i t h i n t e r n a l e r r o r s
143  // ---------------------------------------------------------------------------------------------
144 
145  // If histogram has custom error (i.e. its contents is does not originate from a Poisson process
146  // but e.g. is a sum of weighted events) you can data with symmetric 'sum-of-weights' error instead
147  // (same error bars as shown by ROOT)
148  RooPlot* frame2 = x.frame(RooFit::Title("Imported TH1 with internal errors"));
149  dh->plotOn(frame2, RooFit::DataError(RooAbsData::SumW2));
150  model->plotOn(frame2);
151  model->plotOn(frame2, RooFit::Components(backgroundType), RooFit::LineColor(kRed));
152  model->paramOn(frame2, RooFit::Label("fit result"), RooFit::Format("NEU", RooFit::AutoPrecision(2)));
153 
154  // Please note that error bars shown (Poisson or SumW2) are for visualization only, the are NOT used
155  // in a maximum likelihood fit
156  //
157  // A (binned) ML fit will ALWAYS assume the Poisson error interpretation of data (the mathematical definition
158  // of likelihood does not take any external definition of errors). Data with non-unit weights can only be correctly
159  // fitted with a chi^2 fit (see rf602_chi2fit.C)
160 
161  // Draw all frames on a canvas
162  // if( canvas == 0 ) {
163  // canvas = new TCanvas("rf102_dataimport","rf102_dataimport",800,800);
164  // canvas->cd(1);
165  // }
166  // canvas->Divide(2,1);
167  // canvas->cd(1) ; frame->Draw();
168  // canvas->cd(2) ; frame2->Draw();
169 
170  frame2->Draw();
171  }
172 
173  // Initialization methods for all the parameters
174  void initMean(const double& value,
175  const double& min,
176  const double& max,
177  const TString& name = "mean",
178  const TString& title = "mean") {
179  if (mean_ != nullptr)
180  delete mean_;
181  mean_ = new RooRealVar(name, title, value, min, max);
183  }
184  void initMean2(const double& value,
185  const double& min,
186  const double& max,
187  const TString& name = "mean2",
188  const TString& title = "mean2") {
189  if (mean2_ != nullptr)
190  delete mean2_;
191  mean2_ = new RooRealVar(name, title, value, min, max);
193  }
194  void initMean3(const double& value,
195  const double& min,
196  const double& max,
197  const TString& name = "mean3",
198  const TString& title = "mean3") {
199  if (mean3_ != nullptr)
200  delete mean3_;
201  mean3_ = new RooRealVar(name, title, value, min, max);
203  }
204  void initSigma(const double& value,
205  const double& min,
206  const double& max,
207  const TString& name = "sigma",
208  const TString& title = "sigma") {
209  if (sigma_ != nullptr)
210  delete sigma_;
211  sigma_ = new RooRealVar(name, title, value, min, max);
213  }
214  void initSigma2(const double& value,
215  const double& min,
216  const double& max,
217  const TString& name = "sigma2",
218  const TString& title = "sigma2") {
219  if (sigma2_ != nullptr)
220  delete sigma2_;
221  sigma2_ = new RooRealVar(name, title, value, min, max);
223  }
224  void initSigma3(const double& value,
225  const double& min,
226  const double& max,
227  const TString& name = "sigma3",
228  const TString& title = "sigma3") {
229  if (sigma3_ != nullptr)
230  delete sigma3_;
231  sigma3_ = new RooRealVar(name, title, value, min, max);
233  }
234  void initGamma(const double& value,
235  const double& min,
236  const double& max,
237  const TString& name = "gamma",
238  const TString& title = "gamma") {
239  if (gamma_ != nullptr)
240  delete gamma_;
241  gamma_ = new RooRealVar(name, title, value, min, max);
243  }
244  void initGaussFrac(const double& value,
245  const double& min,
246  const double& max,
247  const TString& name = "GaussFrac",
248  const TString& title = "GaussFrac") {
249  if (gaussFrac_ != nullptr)
250  delete gaussFrac_;
251  gaussFrac_ = new RooRealVar(name, title, value, min, max);
253  }
254  void initGaussFrac2(const double& value,
255  const double& min,
256  const double& max,
257  const TString& name = "GaussFrac2",
258  const TString& title = "GaussFrac2") {
259  if (gaussFrac2_ != nullptr)
260  delete gaussFrac2_;
261  gaussFrac2_ = new RooRealVar(name, title, value, min, max);
263  }
264  void initExpCoeffA0(const double& value,
265  const double& min,
266  const double& max,
267  const TString& name = "expCoeffa0",
268  const TString& title = "expCoeffa0") {
269  if (expCoeffa0_ != nullptr)
270  delete expCoeffa0_;
271  expCoeffa0_ = new RooRealVar(name, title, value, min, max);
273  }
274  void initExpCoeffA1(const double& value,
275  const double& min,
276  const double& max,
277  const TString& name = "expCoeffa1",
278  const TString& title = "expCoeffa1") {
279  if (expCoeffa1_ != nullptr)
280  delete expCoeffa1_;
281  expCoeffa1_ = new RooRealVar(name, title, value, min, max);
283  }
284  void initExpCoeffA2(const double& value,
285  const double& min,
286  const double& max,
287  const TString& name = "expCoeffa2",
288  const TString& title = "expCoeffa2") {
289  if (expCoeffa2_ != nullptr)
290  delete expCoeffa2_;
291  expCoeffa2_ = new RooRealVar(name, title, value, min, max);
293  }
294  void initFsig(const double& value,
295  const double& min,
296  const double& max,
297  const TString& name = "fsig",
298  const TString& title = "signal fraction") {
299  if (fsig_ != nullptr)
300  delete fsig_;
301  fsig_ = new RooRealVar(name, title, value, min, max);
303  }
304  void initA0(const double& value,
305  const double& min,
306  const double& max,
307  const TString& name = "a0",
308  const TString& title = "a0") {
309  if (a0_ != nullptr)
310  delete a0_;
311  a0_ = new RooRealVar(name, title, value, min, max);
312  initVal_a0 = value;
313  }
314  void initA1(const double& value,
315  const double& min,
316  const double& max,
317  const TString& name = "a1",
318  const TString& title = "a1") {
319  if (a1_ != nullptr)
320  delete a1_;
321  a1_ = new RooRealVar(name, title, value, min, max);
322  initVal_a1 = value;
323  }
324  void initA2(const double& value,
325  const double& min,
326  const double& max,
327  const TString& name = "a2",
328  const TString& title = "a2") {
329  if (a2_ != nullptr)
330  delete a2_;
331  a2_ = new RooRealVar(name, title, value, min, max);
332  initVal_a2 = value;
333  }
334  void initA3(const double& value,
335  const double& min,
336  const double& max,
337  const TString& name = "a3",
338  const TString& title = "a3") {
339  if (a3_ != nullptr)
340  delete a3_;
341  a3_ = new RooRealVar(name, title, value, min, max);
342  initVal_a3 = value;
343  }
344  void initA4(const double& value,
345  const double& min,
346  const double& max,
347  const TString& name = "a4",
348  const TString& title = "a4") {
349  if (a4_ != nullptr)
350  delete a4_;
351  a4_ = new RooRealVar(name, title, value, min, max);
352  initVal_a4 = value;
353  }
354  void initA5(const double& value,
355  const double& min,
356  const double& max,
357  const TString& name = "a5",
358  const TString& title = "a5") {
359  if (a5_ != nullptr)
360  delete a5_;
361  a5_ = new RooRealVar(name, title, value, min, max);
362  initVal_a5 = value;
363  }
364  void initA6(const double& value,
365  const double& min,
366  const double& max,
367  const TString& name = "a6",
368  const TString& title = "a6") {
369  if (a6_ != nullptr)
370  delete a6_;
371  a6_ = new RooRealVar(name, title, value, min, max);
372  initVal_a6 = value;
373  }
374  void initAlpha(const double& value,
375  const double& min,
376  const double& max,
377  const TString& name = "alpha",
378  const TString& title = "alpha") {
379  if (alpha_ != nullptr)
380  delete alpha_;
381  alpha_ = new RooRealVar(name, title, value, min, max);
383  }
384  void initN(const double& value,
385  const double& min,
386  const double& max,
387  const TString& name = "n",
388  const TString& title = "n") {
389  if (n_ != nullptr)
390  delete n_;
391  n_ = new RooRealVar(name, title, value, min, max);
392  initVal_n = value;
393  }
394  void initFGCB(const double& value,
395  const double& min,
396  const double& max,
397  const TString& name = "fGCB",
398  const TString& title = "fGCB") {
399  if (fGCB_ != nullptr)
400  delete fGCB_;
401  fGCB_ = new RooRealVar(name, title, value, min, max);
403  }
404 
406  if (mean_ != nullptr)
407  mean_->setVal(initVal_mean);
408  if (mean2_ != nullptr)
409  mean2_->setVal(initVal_mean2);
410  if (mean3_ != nullptr)
411  mean3_->setVal(initVal_mean3);
412  if (sigma_ != nullptr)
413  sigma_->setVal(initVal_sigma);
414  if (sigma2_ != nullptr)
415  sigma2_->setVal(initVal_sigma2);
416  if (sigma3_ != nullptr)
417  sigma3_->setVal(initVal_sigma3);
418  if (gamma_ != nullptr)
419  gamma_->setVal(initVal_gamma);
420  if (gaussFrac_ != nullptr)
421  gaussFrac_->setVal(initVal_gaussFrac);
422  if (gaussFrac2_ != nullptr)
424  if (expCoeffa0_ != nullptr)
426  if (expCoeffa1_ != nullptr)
428  if (expCoeffa2_ != nullptr)
430  if (fsig_ != nullptr)
431  fsig_->setVal(initVal_fsig);
432  if (a0_ != nullptr)
433  a0_->setVal(initVal_a0);
434  if (a1_ != nullptr)
435  a1_->setVal(initVal_a1);
436  if (a2_ != nullptr)
437  a2_->setVal(initVal_a2);
438  if (a3_ != nullptr)
439  a3_->setVal(initVal_a3);
440  if (a4_ != nullptr)
441  a4_->setVal(initVal_a4);
442  if (a5_ != nullptr)
443  a5_->setVal(initVal_a5);
444  if (a6_ != nullptr)
445  a6_->setVal(initVal_a6);
446  if (alpha_ != nullptr)
447  alpha_->setVal(initVal_alpha);
448  if (n_ != nullptr)
449  n_->setVal(initVal_n);
450  if (fGCB_ != nullptr)
451  fGCB_->setVal(initVal_fGCB);
452  }
453 
454  inline RooRealVar* mean() { return mean_; }
455  inline RooRealVar* mean2() { return mean2_; }
456  inline RooRealVar* mean3() { return mean3_; }
457  inline RooRealVar* sigma() { return sigma_; }
458  inline RooRealVar* sigma2() { return sigma2_; }
459  inline RooRealVar* sigma3() { return sigma3_; }
460  inline RooRealVar* gamma() { return gamma_; }
461  inline RooRealVar* gaussFrac() { return gaussFrac_; }
462  inline RooRealVar* gaussFrac2() { return gaussFrac2_; }
463  inline RooRealVar* expCoeffa0() { return expCoeffa0_; }
464  inline RooRealVar* expCoeffa1() { return expCoeffa1_; }
465  inline RooRealVar* expCoeffa2() { return expCoeffa2_; }
466  inline RooRealVar* fsig() { return fsig_; }
467  inline RooRealVar* a0() { return a0_; }
468  inline RooRealVar* a1() { return a1_; }
469  inline RooRealVar* a2() { return a2_; }
470  inline RooRealVar* a3() { return a3_; }
471  inline RooRealVar* a4() { return a4_; }
472  inline RooRealVar* a5() { return a5_; }
473  inline RooRealVar* a6() { return a6_; }
474  inline RooRealVar* alpha() { return alpha_; }
475  inline RooRealVar* n() { return n_; }
476  inline RooRealVar* fGCB() { return fGCB_; }
477 
479  RooAbsPdf* buildSignalModel(RooRealVar* x, const TString& signalType) {
480  RooAbsPdf* signal = nullptr;
481  if (signalType == "gaussian") {
482  // Fit a Gaussian p.d.f to the data
483  if ((mean_ == nullptr) || (sigma_ == nullptr)) {
484  std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize mean and sigma"
485  << std::endl;
486  exit(1);
487  }
488  signal = new RooGaussian("gauss", "gauss", *x, *mean_, *sigma_);
489  } else if (signalType == "doubleGaussian") {
490  // Fit with double gaussian
491  if ((mean_ == nullptr) || (sigma_ == nullptr) || (sigma2_ == nullptr)) {
492  std::cout
493  << "Error: one or more parameters are not initialized. Please be sure to initialize mean, sigma and sigma2"
494  << std::endl;
495  exit(1);
496  }
497  RooGaussModel* gaussModel = new RooGaussModel("gaussModel", "gaussModel", *x, *mean_, *sigma_);
498  RooGaussModel* gaussModel2 = new RooGaussModel("gaussModel2", "gaussModel2", *x, *mean_, *sigma2_);
499  signal = new RooAddModel("doubleGaussian", "double gaussian", RooArgList(*gaussModel, *gaussModel2), *gaussFrac_);
500  } else if (signalType == "tripleGaussian") {
501  // Fit with triple gaussian
502  if ((mean_ == nullptr) || (mean2_ == nullptr) || (mean3_ == nullptr) || (sigma_ == nullptr) ||
503  (sigma2_ == nullptr) || (sigma3_ == nullptr)) {
504  std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize mean, mean2, "
505  "mean3, sigma, sigma2, sigma3"
506  << std::endl;
507  exit(1);
508  }
509  RooGaussModel* gaussModel = new RooGaussModel("gaussModel", "gaussModel", *x, *mean_, *sigma_);
510  RooGaussModel* gaussModel2 = new RooGaussModel("gaussModel2", "gaussModel2", *x, *mean2_, *sigma2_);
511  RooGaussModel* gaussModel3 = new RooGaussModel("gaussModel3", "gaussModel3", *x, *mean3_, *sigma3_);
512  signal = new RooAddModel("tripleGaussian",
513  "triple gaussian",
514  RooArgList(*gaussModel, *gaussModel2, *gaussModel3),
515  RooArgList(*gaussFrac_, *gaussFrac2_));
516  } else if (signalType == "breitWigner") {
517  // Fit a Breit-Wigner
518  if ((mean_ == nullptr) || (gamma_ == nullptr)) {
519  std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize mean and gamma"
520  << std::endl;
521  exit(1);
522  }
523  signal = new RooBreitWigner("breiWign", "breitWign", *x, *mean_, *gamma_);
524  } else if (signalType == "relBreitWigner") {
525  // Fit a relativistic Breit-Wigner
526  if ((mean_ == nullptr) || (gamma_ == nullptr)) {
527  std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize mean and gamma"
528  << std::endl;
529  exit(1);
530  }
531  signal = new RooGenericPdf("Relativistic Breit-Wigner",
532  "RBW",
533  "@0/(pow(@0*@0 - @1*@1,2) + @2*@2*@0*@0*@0*@0/(@1*@1))",
534  RooArgList(*x, *mean_, *gamma_));
535  } else if (signalType == "voigtian") {
536  // Fit a Voigtian
537  if ((mean_ == nullptr) || (sigma_ == nullptr) || (gamma_ == nullptr)) {
538  std::cout
539  << "Error: one or more parameters are not initialized. Please be sure to initialize mean, sigma and gamma"
540  << std::endl;
541  exit(1);
542  }
543  signal = new RooVoigtian("voigt", "voigt", *x, *mean_, *gamma_, *sigma_);
544  } else if (signalType == "crystalBall") {
545  // Fit a CrystalBall
546  if ((mean_ == nullptr) || (sigma_ == nullptr) || (alpha_ == nullptr) || (n_ == nullptr)) {
547  std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize mean, sigma, "
548  "alpha and n"
549  << std::endl;
550  exit(1);
551  }
552  signal = new RooCBShape("crystalBall", "crystalBall", *x, *mean_, *sigma_, *alpha_, *n_);
553  } else if (signalType == "breitWignerTimesCB") {
554  // Fit a Breit Wigner convoluted with a CrystalBall
555  if ((mean_ == nullptr) || (mean2_ == nullptr) || (sigma_ == nullptr) || (gamma_ == nullptr) ||
556  (alpha_ == nullptr) || (n_ == nullptr)) {
557  std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize mean, mean2, "
558  "sigma, gamma, alpha and n"
559  << std::endl;
560  exit(1);
561  }
562  RooAbsPdf* bw = new RooBreitWigner("breiWigner", "breitWigner", *x, *mean_, *gamma_);
563  RooAbsPdf* cb = new RooCBShape("crystalBall", "crystalBall", *x, *mean2_, *sigma_, *alpha_, *n_);
564  signal = new RooFFTConvPdf("breitWignerTimesCB", "breitWignerTimesCB", *x, *bw, *cb);
565  } else if (signalType == "relBreitWignerTimesCB") {
566  // Fit a relativistic Breit Wigner convoluted with a CrystalBall
567  if ((mean_ == nullptr) || (mean2_ == nullptr) || (sigma_ == nullptr) || (gamma_ == nullptr) ||
568  (alpha_ == nullptr) || (n_ == nullptr)) {
569  std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize mean, mean2, "
570  "sigma, gamma, alpha and n"
571  << std::endl;
572  exit(1);
573  }
574  RooGenericPdf* bw = new RooGenericPdf("Relativistic Breit-Wigner",
575  "RBW",
576  "@0/(pow(@0*@0 - @1*@1,2) + @2*@2*@0*@0*@0*@0/(@1*@1))",
577  RooArgList(*x, *mean_, *gamma_));
578  RooAbsPdf* cb = new RooCBShape("crystalBall", "crystalBall", *x, *mean2_, *sigma_, *alpha_, *n_);
579  signal = new RooFFTConvPdf("relBreitWignerTimesCB", "relBreitWignerTimesCB", *x, *bw, *cb);
580  } else if (signalType == "gaussianPlusCrystalBall") {
581  // Fit a Gaussian + CrystalBall with the same mean
582  if ((mean_ == nullptr) || (sigma_ == nullptr) || (alpha_ == nullptr) || (n_ == nullptr) || (sigma2_ == nullptr) ||
583  (fGCB_ == nullptr)) {
584  std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize mean, sigma, "
585  "sigma2, alpha, n and fGCB"
586  << std::endl;
587  exit(1);
588  }
589  RooAbsPdf* tempCB = new RooCBShape("crystalBall", "crystalBall", *x, *mean_, *sigma_, *alpha_, *n_);
590  RooAbsPdf* tempGaussian = new RooGaussian("gauss", "gauss", *x, *mean_, *sigma2_);
591 
592  signal = new RooAddPdf(
593  "gaussianPlusCrystalBall", "gaussianPlusCrystalBall", RooArgList(*tempCB, *tempGaussian), *fGCB_);
594  } else if (signalType == "voigtianPlusCrystalBall") {
595  // Fit a Voigtian + CrystalBall with the same mean
596  if ((mean_ == nullptr) || (sigma_ == nullptr) || (gamma_ == nullptr) || (alpha_ == nullptr) || (n_ == nullptr) ||
597  (sigma2_ == nullptr) || (fGCB_ == nullptr)) {
598  std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize mean, gamma, "
599  "sigma, sigma2, alpha, n and fGCB"
600  << std::endl;
601  exit(1);
602  }
603  RooAbsPdf* tempVoigt = new RooVoigtian("voigt", "voigt", *x, *mean_, *gamma_, *sigma_);
604  RooAbsPdf* tempCB = new RooCBShape("crystalBall", "crystalBall", *x, *mean_, *sigma2_, *alpha_, *n_);
605 
606  signal =
607  new RooAddPdf("voigtianPlusCrystalBall", "voigtianPlusCrystalBall", RooArgList(*tempCB, *tempVoigt), *fGCB_);
608  } else if (signalType == "breitWignerPlusCrystalBall") {
609  // Fit a Breit-Wigner + CrystalBall with the same mean
610  if ((mean_ == nullptr) || (gamma_ == nullptr) || (alpha_ == nullptr) || (n_ == nullptr) || (sigma2_ == nullptr) ||
611  (fGCB_ == nullptr)) {
612  std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize mean, gamma, "
613  "sigma, alpha, n and fGCB"
614  << std::endl;
615  exit(1);
616  }
617  RooAbsPdf* tempBW = new RooBreitWigner("breitWign", "breitWign", *x, *mean_, *gamma_);
618  RooAbsPdf* tempCB = new RooCBShape("crystalBall", "crystalBall", *x, *mean_, *sigma2_, *alpha_, *n_);
619 
620  signal = new RooAddPdf(
621  "breitWignerPlusCrystalBall", "breitWignerPlusCrystalBall", RooArgList(*tempCB, *tempBW), *fGCB_);
622  }
623 
624  else if (signalType != "") {
625  std::cout << "Unknown signal function: " << signalType << ". Signal will not be in the model" << std::endl;
626  }
627  return signal;
628  }
629 
631  RooAbsPdf* buildBackgroundModel(RooRealVar* x, const TString& backgroundType) {
632  RooAbsPdf* background = nullptr;
633  if (backgroundType == "exponential") {
634  // Add an exponential for the background
635  if ((expCoeffa1_ == nullptr) || (fsig_ == nullptr)) {
636  std::cout
637  << "Error: one or more parameters are not initialized. Please be sure to initialize expCoeffa1 and fsig"
638  << std::endl;
639  exit(1);
640  }
641  background = new RooExponential("exponential", "exponential", *x, *expCoeffa1_);
642  }
643 
644  if (backgroundType == "exponentialpol") {
645  // Add an exponential for the background
646  if ((expCoeffa0_ == nullptr) || (expCoeffa1_ == nullptr) || (expCoeffa2_ == nullptr) || (fsig_ == nullptr)) {
647  std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize expCoeff and fsig"
648  << std::endl;
649  exit(1);
650  }
651  background = new RooGenericPdf("exponential",
652  "exponential",
653  "TMath::Exp(@1+@2*@0+@3*@0*@0)",
654  RooArgList(*x, *expCoeffa0_, *expCoeffa1_, *expCoeffa2_));
655  }
656 
657  else if (backgroundType == "chebychev0") {
658  // Add a linear background
659  if (a0_ == nullptr) {
660  std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize a0" << std::endl;
661  exit(1);
662  }
663  background = new RooChebychev("chebychev0", "chebychev0", *x, *a0_);
664  } else if (backgroundType == "chebychev1") {
665  // Add a 2nd order chebychev polynomial background
666  if ((a0_ == nullptr) || (a1_ == nullptr)) {
667  std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize a0 and a1"
668  << std::endl;
669  exit(1);
670  }
671  background = new RooChebychev("chebychev1", "chebychev1", *x, RooArgList(*a0_, *a1_));
672  } else if (backgroundType == "chebychev3") {
673  // Add a 3rd order chebychev polynomial background
674  if ((a0_ == nullptr) || (a1_ == nullptr) || (a2_ == nullptr) || (a3_ == nullptr)) {
675  std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize a0, a1, a2 and a3"
676  << std::endl;
677  exit(1);
678  }
679  background = new RooChebychev("3rdOrderPol", "3rdOrderPol", *x, RooArgList(*a0_, *a1_, *a2_, *a3_));
680  }
681 
682  else if (backgroundType == "chebychev6") {
683  // Add a 6th order chebychev polynomial background
684  if ((a0_ == nullptr) || (a1_ == nullptr) || (a2_ == nullptr) || (a3_ == nullptr) || (a4_ == nullptr) ||
685  (a5_ == nullptr) || (a6_ == nullptr)) {
686  std::cout << "Error: one or more parameters are not initialized. Please be sure to initialize a0, a1, a2, a3, "
687  "a4, a5 and a6"
688  << std::endl;
689  exit(1);
690  }
691  background =
692  new RooChebychev("6thOrderPol", "6thOrderPol", *x, RooArgList(*a0_, *a1_, *a2_, *a3_, *a4_, *a5_, *a6_));
693  }
694 
695  return background;
696  }
697 
699  RooAbsPdf* buildModel(RooRealVar* x, const TString& signalType, const TString& backgroundType) {
700  RooAbsPdf* model = nullptr;
701 
702  RooAbsPdf* signal = buildSignalModel(x, signalType);
703  RooAbsPdf* background = buildBackgroundModel(x, backgroundType);
704 
705  if ((signal != nullptr) && (background != nullptr)) {
706  // Combine signal and background pdfs
707  std::cout << "Building model with signal and backgound" << std::endl;
708  model = new RooAddPdf("model", "model", RooArgList(*signal, *background), *fsig_);
709  } else if (signal != nullptr) {
710  std::cout << "Building model with signal" << std::endl;
711  model = signal;
712  } else if (background != nullptr) {
713  std::cout << "Building model with backgound" << std::endl;
714  model = background;
715  } else {
716  std::cout << "Nothing to fit" << std::endl;
717  exit(0);
718  }
719  return model;
720  }
721 
722  bool useChi2_;
723 
724 protected:
725  // Declare all variables
726  RooRealVar* mean_;
727  RooRealVar* mean2_;
728  RooRealVar* mean3_;
729  RooRealVar* sigma_;
730  RooRealVar* sigma2_;
731  RooRealVar* sigma3_;
732  RooRealVar* gamma_;
733  RooRealVar* gaussFrac_;
734  RooRealVar* gaussFrac2_;
735  RooRealVar* expCoeffa0_;
736  RooRealVar* expCoeffa1_;
737  RooRealVar* expCoeffa2_;
738  RooRealVar* fsig_;
739  RooRealVar* a0_;
740  RooRealVar* a1_;
741  RooRealVar* a2_;
742  RooRealVar* a3_;
743  RooRealVar* a4_;
744  RooRealVar* a5_;
745  RooRealVar* a6_;
746  RooRealVar* alpha_;
747  RooRealVar* n_;
748  RooRealVar* fGCB_;
749 
750  // Initial values
751  double initVal_mean;
763  double initVal_fsig;
764  double initVal_a0;
765  double initVal_a1;
766  double initVal_a2;
767  double initVal_a3;
768  double initVal_a4;
769  double initVal_a5;
770  double initVal_a6;
772  double initVal_n;
773  double initVal_fGCB;
774 };
775 
776 #endif
void initGaussFrac2(const double &value, const double &min, const double &max, const TString &name="GaussFrac2", const TString &title="GaussFrac2")
void initGaussFrac(const double &value, const double &min, const double &max, const TString &name="GaussFrac", const TString &title="GaussFrac")
void initA6(const double &value, const double &min, const double &max, const TString &name="a6", const TString &title="a6")
RooRealVar * mean3()
RooRealVar * n_
RooRealVar * mean_
double initVal_expCoeffa0
RooRealVar * gaussFrac2_
RooRealVar * a0_
RooRealVar * sigma()
RooRealVar * sigma2_
double initVal_mean2
void initA1(const double &value, const double &min, const double &max, const TString &name="a1", const TString &title="a1")
RooRealVar * a4_
RooRealVar * sigma_
void initFsig(const double &value, const double &min, const double &max, const TString &name="fsig", const TString &title="signal fraction")
RooRealVar * expCoeffa0()
RooRealVar * fGCB_
void fit(TH1 *histo, const TString signalType, const TString backgroundType, const double &xMin=0., const double &xMax=0., bool sumW2Error=false)
RooAbsPdf * buildSignalModel(RooRealVar *x, const TString &signalType)
Build the model for the specified signal type.
void initGamma(const double &value, const double &min, const double &max, const TString &name="gamma", const TString &title="gamma")
RooRealVar * mean2_
RooRealVar * a6()
RooRealVar * sigma3_
RooRealVar * a6_
RooRealVar * a3()
RooRealVar * expCoeffa2_
RooRealVar * fsig()
void initA3(const double &value, const double &min, const double &max, const TString &name="a3", const TString &title="a3")
double initVal_expCoeffa1
double initVal_gamma
double initVal_alpha
double initVal_gaussFrac2
RooRealVar * mean3_
void reinitializeParameters()
double initVal_sigma3
RooRealVar * gaussFrac()
RooRealVar * sigma3()
RooRealVar * sigma2()
RooRealVar * mean()
RooRealVar * gaussFrac2()
void initMean3(const double &value, const double &min, const double &max, const TString &name="mean3", const TString &title="mean3")
RooRealVar * a0()
RooRealVar * n()
double initVal_sigma2
RooRealVar * mean2()
void initA4(const double &value, const double &min, const double &max, const TString &name="a4", const TString &title="a4")
Definition: value.py:1
RooRealVar * expCoeffa1()
RooRealVar * gamma()
void initMean(const double &value, const double &min, const double &max, const TString &name="mean", const TString &title="mean")
void initN(const double &value, const double &min, const double &max, const TString &name="n", const TString &title="n")
double initVal_expCoeffa2
RooRealVar * a1_
RooRealVar * alpha_
rooPair importTH1(TH1 *histo, const double &inputXmin, const double &inputXmax)
void initA0(const double &value, const double &min, const double &max, const TString &name="a0", const TString &title="a0")
void initAlpha(const double &value, const double &min, const double &max, const TString &name="alpha", const TString &title="alpha")
RooRealVar * fsig_
void initSigma3(const double &value, const double &min, const double &max, const TString &name="sigma3", const TString &title="sigma3")
RooRealVar * fGCB()
void initA5(const double &value, const double &min, const double &max, const TString &name="a5", const TString &title="a5")
RooRealVar * expCoeffa2()
void initExpCoeffA0(const double &value, const double &min, const double &max, const TString &name="expCoeffa0", const TString &title="expCoeffa0")
RooRealVar * a2_
RooAbsPdf * buildModel(RooRealVar *x, const TString &signalType, const TString &backgroundType)
Build the model to fit.
RooAbsPdf * buildBackgroundModel(RooRealVar *x, const TString &backgroundType)
Build the model for the specified background type.
RooRealVar * expCoeffa1_
void initExpCoeffA1(const double &value, const double &min, const double &max, const TString &name="expCoeffa1", const TString &title="expCoeffa1")
RooRealVar * a4()
RooRealVar * a3_
void initA2(const double &value, const double &min, const double &max, const TString &name="a2", const TString &title="a2")
void initSigma2(const double &value, const double &min, const double &max, const TString &name="sigma2", const TString &title="sigma2")
void initFGCB(const double &value, const double &min, const double &max, const TString &name="fGCB", const TString &title="fGCB")
RooRealVar * alpha()
RooRealVar * a5_
RooRealVar * a1()
RooRealVar * a2()
void initExpCoeffA2(const double &value, const double &min, const double &max, const TString &name="expCoeffa2", const TString &title="expCoeffa2")
double initVal_gaussFrac
void initSigma(const double &value, const double &min, const double &max, const TString &name="sigma", const TString &title="sigma")
dh
Definition: cuy.py:354
RooRealVar * a5()
void initMean2(const double &value, const double &min, const double &max, const TString &name="mean2", const TString &title="mean2")
double initVal_mean3
RooRealVar * gamma_
RooRealVar * expCoeffa0_
RooRealVar * gaussFrac_
double initVal_sigma
def exit(msg="")