Advertisement
Guest User

Untitled

a guest
Mar 25th, 2019
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.58 KB | None | 0 0
  1. #include "Riostream.h"
  2.  
  3. // Custom exponential PDF
  4. class ExpPdf : public RooAbsPdf {
  5. public:
  6. ExpPdf() {};
  7. ExpPdf(const char *name, const char *title, RooAbsReal& _t, RooAbsReal& _tau);
  8. ExpPdf(const ExpPdf& other, const char* name = 0);
  9. virtual TObject* clone(const char* newname) const { return new ExpPdf(*this, newname); }
  10. inline virtual ~ExpPdf() { }
  11.  
  12. Int_t getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* rangeName=0) const ;
  13. Double_t analyticalIntegral(Int_t code, const char* rangeName=0) const ;
  14. Double_t indefiniteIntegral(Double_t y) const;
  15.  
  16. protected:
  17. RooRealProxy t;
  18. RooRealProxy tau;
  19. Double_t evaluate() const;
  20. };
  21.  
  22. ExpPdf::ExpPdf(const char *name, const char *title, RooAbsReal& _t, RooAbsReal& _tau) :
  23. RooAbsPdf(name, title), t("t", "t", this, _t), tau("tau", "tau", this, _tau) {
  24. }
  25.  
  26. ExpPdf::ExpPdf(const ExpPdf& other, const char* name) : RooAbsPdf(other, name), t("t", this, other.t), tau("tau", this, other.tau){
  27. }
  28.  
  29. Double_t ExpPdf::evaluate() const {
  30. if (t < 0) return 0.;
  31. return exp(-t/tau);
  32. }
  33.  
  34. Double_t ExpPdf::indefiniteIntegral(Double_t y) const {
  35. return -exp(-y/tau)*tau;
  36. }
  37.  
  38. Int_t ExpPdf::getAnalyticalIntegral(RooArgSet& allVars, RooArgSet& analVars, const char* rangeName) const {
  39. if (matchArgs(allVars,analVars,t)) return 1;
  40. return 0;
  41. }
  42.  
  43. Double_t ExpPdf::analyticalIntegral(Int_t code, const char* rangeName) const {
  44. if (code == 1){
  45. Double_t t1 = t.min(rangeName);
  46. Double_t t2 = t.max(rangeName);
  47. if (t2 <= 0) return 0;
  48. t1 = TMath::Max(0.,t1);
  49. return indefiniteIntegral(t2) - indefiniteIntegral(t1);
  50. }
  51. return 0;
  52. }
  53.  
  54. // Main macro
  55. void conv_linearity_test() {
  56.  
  57. // Create observable
  58. RooRealVar* t = new RooRealVar("t", "time axis", 0, 10, "ns");
  59. t->setBins(100);
  60.  
  61. // Coefficient to convert fwhm to dispersion
  62. RooConstVar fwhm2dispersion = RooFit::RooConst(0.424661);
  63.  
  64. // FIRST TEST: RooAddPdf(ExpPdf + ExpPdf) x gauss
  65. // Resolution function is RooGaussian
  66. RooRealVar* mean1 = new RooRealVar("mean1", "gauss1 mean", 3, 0, 10, "ns");
  67. RooRealVar* fwhm1 = new RooRealVar("fwhm1", "gauss1 fwhm", 0.5, 0, 2, "ns");
  68. RooFormulaVar* sigma1 = new RooFormulaVar("sigma1", "gauss1 dispersion", "@0*@1", RooArgList(*fwhm1, fwhm2dispersion));
  69. RooGaussian* gauss1 = new RooGaussian("gauss1", "gauss pdf", *t, *mean1, *sigma1);
  70.  
  71. // Model is sum of two custom ExpPdf's. Their sum is convoluted via RooFFTConvPdf.
  72. RooRealVar* tauA1 = new RooRealVar("tauA1", "lifetime A1", 0.2, "ns");
  73. RooRealVar* tauB1 = new RooRealVar("tauB1", "lifetime B1", 1, "ns");
  74. RooRealVar* I_B1 = new RooRealVar("I_B1", "intensity of B1", 0.13, 0.0, 1.0);
  75. ExpPdf* pdfA1 = new ExpPdf("pdfA1", "PDF A1", *t, *tauA1);
  76. ExpPdf* pdfB1 = new ExpPdf("pdfB1", "PDF B1", *t, *tauB1);
  77. RooAddPdf* pdfA1B1 = new RooAddPdf("pdfAB", "sum pdfA1 and pdf B1", RooArgList(*pdfB1, *pdfA1), *I_B1); // first sum
  78. // Uncomment this line to get the correct result.
  79. // pdfA1B1->fixAddCoefNormalization(RooArgSet(*t));
  80. RooFFTConvPdf* pdf1 = new RooFFTConvPdf("pdf1", "RooAddPdf(ExpPdf + ExpPdf) x gauss", *t, *pdfA1B1, *gauss1); // then convolute
  81.  
  82. // SECOND TEST: RooAddPdf((ExpPdf x gauss) + (ExpPdf x gauss))
  83. // Resolution function is RooGaussian with same parameter starting values
  84. RooRealVar* mean2 = new RooRealVar("mean2", "gauss2 mean", 3, 0, 10, "ns");
  85. RooRealVar* fwhm2 = new RooRealVar("fwhm2", "gauss2 fwhm", 0.5, 0, 2, "ns");
  86. RooFormulaVar* sigma2 = new RooFormulaVar("sigma2", "gauss2 dispersion", "@0*@1", RooArgList(*fwhm2, fwhm2dispersion));
  87. RooGaussian* gauss2 = new RooGaussian("gauss2", "gauss pdf", *t, *mean2, *sigma2);
  88.  
  89. // Model is sum of two custom ExpPdf's independently convoluted via RooFFTConvPdf
  90. RooRealVar* tauA2 = new RooRealVar("tauA2", "lifetime A2", 0.2, "ns");
  91. RooRealVar* tauB2 = new RooRealVar("tauB2", "lifetime B2", 1, "ns");
  92. RooRealVar* I_B2 = new RooRealVar("I_B2", "intensity of B2", 0.13, 0.0, 1.0);
  93. ExpPdf* pdfA2 = new ExpPdf("pdfA2", "PDF A2", *t, *tauA2);
  94. RooFFTConvPdf* convA2 = new RooFFTConvPdf("convA2", "convoluted A2", *t, *pdfA2, *gauss2);
  95. ExpPdf* pdfB2 = new ExpPdf("pdfB2", "PDF B2", *t, *tauB2);
  96. RooFFTConvPdf* convB2 = new RooFFTConvPdf("convB2", "convoluted B2", *t, *pdfB2, *gauss2);
  97. RooAddPdf* pdf2 = new RooAddPdf("pdf2", "RooAddPdf((ExpPdf x gauss) + (ExpPdf x gauss))", RooArgList(*convB2, *convA2), *I_B2);
  98.  
  99. // Create dataset from second model (that gives correct intensities)
  100. RooDataHist* data = pdf2->generateBinned(*t, 10000);
  101.  
  102. // FIT DATA (to the identical dataset)
  103. pdf1->fitTo(*data);
  104. pdf2->fitTo(*data);
  105.  
  106. // PLOT FITS AND REVEAL THE PROBLEM:
  107. TCanvas* canvas = new TCanvas("canvas", "canvas", 1280, 800);
  108. canvas->Divide(1, 2);
  109.  
  110. // Top plot: convolution of two RooDecay's and RooGaussModel
  111. canvas->cd(1)->SetLogy();
  112. RooPlot* frame1 = t->frame(RooFit::Title("RooAddPdf(ExpPdf + ExpPdf) x gauss, gives incorrect I_B1 = 0.03 unless I call fixAddCoefNormalization()"));
  113. data->plotOn(frame1, RooFit::MarkerSize(0.2));
  114. pdf1->plotOn(frame1);
  115. gauss1->plotOn(frame1, RooFit::LineStyle(kDashed));
  116. pdf1->paramOn(frame1, RooFit::Layout(0.58, 0.9, 0.9), RooFit::Format("NEU", RooFit::AutoPrecision(1)));
  117. frame1->Draw();
  118.  
  119. // Middle plot: convolution of custom ExpPdf's with RooGaussian by means of RooFFTConvPdf
  120. canvas->cd(2)->SetLogy();
  121. RooPlot* frame2 = t->frame(RooFit::Title("RooAddPdf((ExpPdf x gauss) + (ExpPdf x gauss)), gives correct I_B2 = 0.136"));
  122. data->plotOn(frame2, RooFit::MarkerSize(0.2));
  123. pdf2->plotOn(frame2);
  124. gauss2->plotOn(frame2, RooFit::LineStyle(kDashed));
  125. pdf2->paramOn(frame2, RooFit::Layout(0.58, 0.9, 0.9), RooFit::Format("NEU", RooFit::AutoPrecision(1)));
  126. frame2->Draw();
  127. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement