def DoRooFit(histo, title): can = makeCMSCanvas(str(random.random()),"Fit result ",900,700) #Varible if "ele" in title: x1 = RooRealVar("x1","m_{e^{+}e^{-}}",80,100) if "mu" in title: x1 = RooRealVar("x1","m_{#mu^{+}#mu^{-}}",80,100) #Define CB function m = RooRealVar("mean_{CB}","mean of gaussian",60,120) s = RooRealVar("#sigma_{CB}","width of gaussian",0,3) a = RooRealVar("#alpha_{CB}","mean of gaussian",0,100) n = RooRealVar("n_{CB}","width of gaussian",0,5) CB = RooCBShape("CB","CB PDF",x1, m, s, a, n) m.setConstant(kFALSE) s.setConstant(kFALSE) a.setConstant(kFALSE) n.setConstant(kFALSE) #Define Gaussian function mean1 = RooRealVar("mean_{G}","mean of gaussian",-60,60) sigma1 = RooRealVar("#sigma_{G}","width of gaussian",0,10) gauss1 = RooGaussian("gauss1","gaussian PDF",x1,mean1,sigma1) mean1.setConstant(kFALSE) sigma1.setConstant(kFALSE) #Starting values of the parameters mean1.setVal(1.0) sigma1.setVal(1.0) m.setVal(90.0) s.setVal(1.0) a.setVal(10.0) n.setVal(2.0) # Construct CB (x) gauss x1.setBins(10000, "cache") CBxG = RooFFTConvPdf("CBxG", "CB (X) gauss", x1, CB, gauss1) can.cd() d = RooDataHist("d","d",RooArgList(x1),RooFit.Import(histo)) CBxG.fitTo(d, RooLinkedList()) # Plot PDF and toy data overlaid xframe2 = x1.frame(RooFit.Name("xframe"),RooFit.Title("")) # RooPlot d.plotOn(xframe2, RooLinkedList() ) CBxG.paramOn(xframe2, RooFit.Layout(0.65,0.99,0.9)) xframe2.getAttText().SetTextSize(0.03) CBxG.plotOn(xframe2) xframe2.Draw() can.SaveAs("DataVsMC/FitResults/"+title+"_Roofit.pdf") can.SaveAs("DataVsMC/FitResults/"+title+"_Roofit.png") return;
def buildModel(w): ## Gen level invariant mass variable mass = w.factory('mass[40, 140]') ## Transformed gen level invariant mass variable t = w.factory("t[%f,%f]" % (log(mass.getMin()/91.2), log(mass.getMax()/91.2))) ## m = m(t) tranformation: mass as a function of t massFunc = w.factory("FormulaVar::massFunc('91.2 * exp(t)', {t})") ## inverse transformation t = t(m): t as a function of mass tFunc = w.factory("FormulaVar::tFunc('log(mass/91.2)', {mass})") ## # resf = w.factory("FormulaVar::resf('exp(2*logmu)', {logmu})") t.setBins(10000, "fft") ## PDF for t defined through a transformation of the PDF for m tPdf = w.factory("""BreitWigner::tPdf( massFunc, bwMean[91.19], bwWidth[2.5])""") ## Start a hack to work around a RooFit limitation preventing observable ## transform of the 2nd PDF in the FFT convolution. Use custom PDF ## RooLogCBShape instead of transforming RooCBShape. dt1Pdf = w.factory("""RooLogSqrtGaussian::dt1Pdf( t, #Deltam[1, 0.5, 1.5], #sigma[0.02, 0.001, 0.1])""") dt2Pdf = w.factory("RooLogSqrtGaussian::dt2Pdf(t, #Deltam, #sigma)") TxDT1 = w.factory("FCONV::TxDT1(t,tPdf,dt1Pdf)") TxDT1.setBufferFraction(0.5) w.Print() ## Ideally would like to do: ## model = w.factory("FCONV::model(tFunc, t, TxDT1, dt2Pdf)") ## But that doesn't work for some reason. ## Start a hack to workaround RooWorkspace::factory bug preventing such usage ## of the RooFFTConvPdf constructor with 4 arguments model = RooFFTConvPdf('model', 'model', tFunc, t, TxDT1, dt2Pdf) w.Import(model) model.setBufferFraction(0.25) w.Print() return model
def bwcb(mean_, width_, sigma_, alpha_, n_, fn, tagged_mass, w): ## Breit-Wigner meanBW = RooRealVar ("massBW_%s"%fn , "massBW_%s"%fn , mean_ , 3, 7, "GeV") widthBW = RooRealVar ("widthBW_%s"%fn , "widthBW_%s"%fn , width_ , 0, 10 ) bwshape = RooBreitWigner ("bwshape_%s"%fn , "bwshape_%s"%fn , tagged_mass, meanBW, widthBW) meanCB = RooRealVar ("massBW_%s"%fn , "massBW_%s"%fn , 0.) sigmabwCB = RooRealVar ("#sigma_{bwCB}_%s"%fn , "sigmabwCB_%s"%fn , sigma_ , 0, 1 ) alphabw = RooRealVar ("#alphabw_%s"%fn , "alphabw_%s"%fn , alpha_ , 0, 10 ) # was 0 - 5 nbw = RooRealVar ("nbw_%s"%fn , "nbw_%s"%fn , n_ , 0, 25 ) cbshape = RooCBShape ("cbshapebw_%s"%fn , "cbshapebw_%s"%fn , tagged_mass, meanCB, sigmabwCB, alphabw, nbw) cbbw = RooFFTConvPdf( "cbbw_%s"%fn, "cbbw_%s"%fn, tagged_mass, bwshape, cbshape); _import(w,cbbw)
def broadenspec(ms, E_0): spec = decayspec(ms, E_0) smear = core(E_0_center) newspec = TH1D("", "", spec.GetNbinsX(), -17.5, 17.5) for i in range(1, spec.GetNbinsX() + 1): newspec.SetBinContent(i, spec.GetBinContent(i)) #x = RooRealVar("x","x",-30+E_0_center, 5+E_0_center) x = RooRealVar("x", "x", -17.5, 17.5) data = RooDataHist("", "", RooArgList(x), newspec) specpdf = RooHistPdf("", "", RooArgSet(x), data) #y = RooRealVar("y","y",-30, 5) x.setBins(10000) smearpdf = RooFit.bindPdf(smear, x) fft = RooFFTConvPdf("tt", "tt", x, specpdf, smearpdf) #fft.setShift(0, -18574) #c1 = TCanvas() #frame = x.frame() #fft.plotOn(frame) #frame.Draw() tf = fft.asTF(RooArgList(x)) tf.SetNpx(10000) rtf = tf.Clone() return rtf
def rooFit208(): print ">>> setup component pdfs..." t = RooRealVar("t", "t", -10, 30) ml = RooRealVar("ml", "mean landau", 5., -20, 20) sl = RooRealVar("sl", "sigma landau", 1, 0.1, 10) landau = RooLandau("lx", "lx", t, ml, sl) mg = RooRealVar("mg", "mg", 0) sg = RooRealVar("sg", "sg", 2, 0.1, 10) gauss = RooGaussian("gauss", "gauss", t, mg, sg) print ">>> construct convolution pdf..." # Set #bins to be used for FFT sampling to 10000 t.setBins(10000, "cache") # Construct landau (x) gauss convolution = RooFFTConvPdf("lxg", "landau (X) gauss", t, landau, gauss) print ">>> sample, fit and plot convoluted pdf..." data = convolution.generate(RooArgSet(t), 10000) # RooDataSet convolution.fitTo(data) print "\n>>> plot everything..." frame1 = t.frame(Title("landau #otimes gauss convolution")) # RooPlot data.plotOn(frame1, Binning(50), Name("data")) convolution.plotOn(frame1, Name("lxg")) gauss.plotOn(frame1, LineStyle(kDashed), LineColor(kRed), Name("gauss")) landau.plotOn(frame1, LineStyle(kDashed), LineColor(kGreen), Name("landau")) print "\n>>> draw pfds and fits on canvas..." canvas = TCanvas("canvas", "canvas", 100, 100, 800, 600) legend = TLegend(0.6, 0.8, 0.8, 0.6) legend.SetTextSize(0.032) legend.SetBorderSize(0) legend.SetFillStyle(0) gPad.SetLeftMargin(0.15) gPad.SetRightMargin(0.02) frame1.GetYaxis().SetLabelOffset(0.008) frame1.GetYaxis().SetTitleOffset(1.5) frame1.GetYaxis().SetTitleSize(0.045) frame1.GetXaxis().SetTitleSize(0.045) frame1.Draw() legend.AddEntry("data", "data", 'LEP') legend.AddEntry("lxg", "convolution", 'L') legend.AddEntry("landau", "landau", 'L') legend.AddEntry("gauss", "gauss", 'L') legend.Draw() canvas.SaveAs("rooFit208.png")
RooArgSet(x), hist, 2 # Order of interpolation function ) #p2 = RooGaussian( p2 = RooGaussModel( "comp_2", "", x, mean, sigma ) #pdf = RooNumConvPdf("pdf", 'convolution', x, p1, p2) x.setBins(10000,"fft") ; pdf = RooFFTConvPdf("pdf", 'convolution', x, p2, p1) pdf.setBufferFraction(5.0) #pdf.setBufferFraction(50.0) # Plot PDF canvas = TCanvas("c1","",1200,480); canvas.Divide(3,1); canvas.cd(1) xframe = x.frame() p1.plotOn( xframe ) xframe.Draw() gPad.SetLogy() #canvas.cd(2) #xframe2 = x.frame()
inelascs = 3.4e-18 npx = 5000000 def totalCS(epsilon): #return elas.EngLossPdf(epsilon[0]) * elascs + inelas.EngLossPdf(epsilon[0]) * inelascs return inelas.EngLossPdf(epsilon[0]) * inelascs # Range from 0 to 500 eV to promote precision of FFT and avoid unphysical results. fcn = TF1("pdf", totalCS, 0, 500) fcn.SetNpx(npx) x = RooRealVar("x", "x", 0, 500) x.setBins(npx) f = RooFit.bindPdf(fcn, x) tt = RooFFTConvPdf("tt", "tt", x, f, f) ttt = RooFFTConvPdf("ttt", "ttt", x, tt, f) tf = [] tf.append(fcn) tf.append(tt.asTF(RooArgList(x))) tf.append(ttt.asTF(RooArgList(x))) pdf = [] Times = ["once", "twice", "thrice"] wfile = TFile("../EnergyLoss.root", "RECREATE") for i in range(len(tf)): tf[i].SetNpx(npx) histtmp = tf[i].GetHistogram() histtmp.Scale(1 / histtmp.Integral("width")) # Change energy range to (0, 50)eV.
def RooFitHist(inputhist, title='title', path='.'): # RooFit.gErrorIgnoreLevel = RooFit.kInfo # <6.02 # RooFit.SetSilentMode()# >6.02 # RooMsgService().instance().SetSilentMode(kTRUE) fitbinning = array('d') binwidth = 200 #NBins=(14000/binwidth) - ( (1040/binwidth) + 1 ) NBins = (14000 / binwidth) - ((1040 / binwidth) + 1) for i in range(NBins + 1): fitbinning.append(1050 + i * binwidth) # print(fitbinning) hist = inputhist.Rebin(NBins, "fit parameter", fitbinning) meanstart = hist.GetBinCenter(hist.GetMaximumBin()) sigmastart = hist.GetRMS() print('meanstart:', meanstart, 'sigmastart:', sigmastart) # inputhist.Draw() # hist.Draw() # hold=raw_input('press enter to exit.') gStyle.SetOptFit(1100) gStyle.SetOptTitle(0) RooFit.SumW2Error(kTRUE) mjj = RooRealVar('mjj', 'M_{jj-AK8}', fitbinning[0], fitbinning[len(fitbinning) - 1], 'GeV') mjjral = RooArgList(mjj) dh = RooDataHist('dh', 'dh', mjjral, RooFit.Import(hist)) shapes = {} #Gaussian gaussmean = RooRealVar('#mu_{gauss}', 'mass mean value', meanstart, 0, 2 * meanstart) gausssigma = RooRealVar('#sigma_{gauss}', 'mass resolution', sigmastart, 0, 2 * sigmastart) gauss = RooGaussian('gauss', 'gauss', mjj, gaussmean, gausssigma) shapes.update({'Gauss': gauss}) #CrystalBall mean = RooRealVar('#mu', 'mean', meanstart, 0, 2 * meanstart) sigma = RooRealVar('#sigma', 'sigma', sigmastart, 0, 2 * sigmastart) alpha = RooRealVar('#alpha', 'Gaussian tail', -1000, 0) n = RooRealVar('n', 'Normalization', -1000, 1000) cbshape = RooCBShape('cbshape', 'crystalball PDF', mjj, mean, sigma, alpha, n) shapes.update({'CrystalBall': cbshape}) #Voigt voigtmean = RooRealVar('#mu', 'mass mean value', meanstart, 0, 2 * meanstart) voigtwidth = RooRealVar('#gamma', 'width of voigt', 0, 5000) voigtsigma = RooRealVar('#sigma', 'mass resolution', sigmastart, 0, 2 * sigmastart) voigt = RooVoigtian('voigt', 'voigt', mjj, voigtmean, voigtwidth, voigtsigma) shapes.update({'Voigt': voigt}) #BreitWigner bwmean = RooRealVar('#mu', 'mass mean value', meanstart, 0, 2 * meanstart) bwwidth = RooRealVar('#sigma', 'width of bw', sigmastart, 0, 2 * sigmastart) bw = RooBreitWigner('bw', 'bw', mjj, bwmean, bwwidth) shapes.update({'BreitWigner': bw}) #Landau landaumean = RooRealVar('#mu_{landau}', 'mean landau', meanstart, 0, 2 * meanstart) landausigma = RooRealVar('#sigma_{landau}', 'mass resolution', sigmastart, 0, 2 * sigmastart) landau = RooLandau('landau', 'landau', mjj, landaumean, landausigma) shapes.update({'Landau': landau}) #LandauGauss Convolution landaugauss = RooFFTConvPdf('landaugauss', 'landau x gauss', mjj, landau, gauss) shapes.update({'LandauGauss': landaugauss}) #Logistics # logisticsmean=RooRealVar('#mu_{logistics}','mean logistics',meanstart,0,2*meanstart) # logisticssigma= RooRealVar('#sigma_{logistics}','mass resolution',sigmastart,0,2*sigmastart) # logistics=RooLogistics('logistics','logistics',mjj,logisticsmean,logisticssigma) # shapes.update({'Logistics':logistics}) #ExpAndGauss # expgaussmean=RooRealVar('#mu_{expgauss}','mean expgauss',meanstart,0,2*meanstart) # expgausssigma= RooRealVar('#sigma_{expgauss}','mass resolution',sigmastart,0,2*sigmastart) # expgausstrans= RooRealVar('trans','trans',0,100) # expgauss=RooExpAndGauss('expgauss','expgauss',mjj,expgaussmean,expgausssigma,expgausstrans) # shapes.update({'ExpAndGauss':expgauss}) #BifurGauss BifurGaussmean = RooRealVar('#mu_{BifurGauss}', 'mean BifurGauss', meanstart, 0, 2 * meanstart) BifurGausslsigma = RooRealVar('#sigma_{left}', 'mass resolution', sigmastart, 0, 2 * sigmastart) BifurGaussrsigma = RooRealVar('#sigma_{right}', 'mass resolution', sigmastart, 0, 2 * sigmastart) BifurGauss = RooBifurGauss('BifurGauss', 'BifurGauss', mjj, BifurGaussmean, BifurGausslsigma, BifurGaussrsigma) shapes.update({'BifurGauss': BifurGauss}) #Chebychev Chebychev1 = RooRealVar('c0', 'Chebychev0', -1000, 1000) Chebychev2 = RooRealVar('c1', 'Chebychev1', -1000, 1000) Chebychev3 = RooRealVar('c2', 'Chebychev2', 2, -1000, 1000) Chebychev = RooChebychev('Chebychev', 'Chebychev', mjj, RooArgList(Chebychev1, Chebychev2, Chebychev3)) shapes.update({'Chebychev': Chebychev}) #Polynomial Polynomial1 = RooRealVar('Polynomial1', 'Polynomial1', 100, 0, 1000) Polynomial2 = RooRealVar('Polynomial2', 'Polynomial2', 100, 0, 1000) Polynomial = RooPolynomial('Polynomial', 'Polynomial', mjj, RooArgList(Polynomial1, Polynomial2)) shapes.update({'Polynomial': Polynomial}) # mjj.setRange("FitRange",1050.,14000.) # for fname in ['Gauss','Logistics','BifurGauss']: for fname in ['BifurGauss']: plottitle = '%s Fit of %s' % (fname, title) shape = shapes[fname] # shape.fitTo(dh,RooFit.Range("FitRange"),RooFit.SumW2Error(True)) shape.fitTo(dh, RooFit.SumW2Error(True)) frame = mjj.frame(RooFit.Title(plottitle)) frame.GetYaxis().SetTitleOffset(2) dh.plotOn(frame, RooFit.MarkerStyle(4)) shape.plotOn(frame, RooFit.LineColor(2)) ndof = dh.numEntries() - 3 #chiSquare legend chi2 = frame.chiSquare() probChi2 = TMath.Prob(chi2 * ndof, ndof) chi2 = round(chi2, 2) probChi2 = round(probChi2, 2) leg = TLegend(0.5, 0.5, 0.9, 0.65) leg.SetBorderSize(0) leg.SetFillStyle(0) shape.paramOn(frame, RooFit.Layout(0.5, 0.9, 0.9)) leg.AddEntry(0, '#chi^{2} =' + str(chi2), '') leg.AddEntry(0, 'Prob #chi^{2} = ' + str(probChi2), '') leg.SetTextSize(0.04) frame.addObject(leg) canv = TCanvas(plottitle, plottitle, 700, 700) canv.SetLogy() canv.SetLeftMargin(0.20) canv.cd() frame.SetMinimum(10**(-3)) frame.Draw() canv.Print(path + '/%s__%s.eps' % (title, fname)) return chi2
mPdf = w.factory('KeysPdf::mPdf(mass, mData)') tPdf = w.factory('KeysPdf::tPdf(t, tData)') dt1Pdf = w.factory("""RooLogSqrtGaussian::dt1Pdf( t, #Deltam[1, 0.5, 1.5], #sigma[0.02, 0.001, 0.1]) """) dt2Pdf = w.factory("RooLogSqrtGaussian::dt2Pdf(t, #Deltam, #sigma)") TxDT1 = w.factory("FCONV::TxDT1(t,tPdf,dt1Pdf)") TxDT1.setBufferFraction(0.5) tFunc = w.factory("FormulaVar::tFunc('log(mass/91.2)', {mass})") model = RooFFTConvPdf('model', 'model', tFunc, t, TxDT1, dt2Pdf) w.Import(model) model.setBufferFraction(0.25) w.Print() mPlot = mass.frame(Range(70,110)) tPlot = t.frame(Range(*trange)) mData.plotOn(mPlot) tData.plotOn(tPlot) mPdf.plotOn(mPlot) tPdf.plotOn(tPlot) model.plotOn(mPlot, LineColor(kRed)) TxDT1.plotOn(tPlot, LineColor(kRed))
sig_hist.GetRMS() / 5., #fpar[0], 0., 50., 'fC') lnd = RooLandau('lnd', 'lnd', x, mpv, width) sigma = RooRealVar( 'sigma', '#sigma', #fpar[3], sig_hist.GetRMS() / 5., 0., 50., 'fC') mean = RooConstVar('mean', 'mean', 0.) res = RooGaussian('res', 'res', x, mean, sigma) lxg = RooFFTConvPdf('lxg', 'lxg', x, lnd, res) xf = x.frame(RooFit.Bins(Nbins)) sigDS.plotOn(xf) fmip = RooRealVar('fmip', 'f_{mip}', 0.95, 0., 1.) if havePeds: if opts.sipm: lxgplus = RooAddPdf('lxgplus', 'lxgplus', lxg, ws.pdf('pedPlusOne'), fmip) else: lxgplus = RooAddPdf('lxgplus', 'lxgplus', lxg, ws.pdf('ped'), fmip) ws.pdf('ped').plotOn( xf, RooFit.LineColor(kRed), RooFit.LineStyle(kDashed), RooFit.Normalization(sig_hist.GetEntries() / 3, RooAbsReal.Raw)) fitter = lxgplus
def main(): output = argv[1] rap = argv[2] flavour = argv[3] trackType = argv[4] funct = argv[5] fit_min = int(argv[6]) fit_max = int(argv[7]) rebinFactor = int(argv[8]) i = int(argv[9]) if funct == "CB": DOCRYSTALBALL = True DOCRUIJFF = False DODOUBLECB = False elif funct == "cruijff": DOCRUIJFF = True DOCRYSTALBALL = False DODOUBLECB = False elif funct == "doubleCB": DODOUBLECB = True DOCRYSTALBALL = False DOCRUIJFF = False print("+++++++++++++++++++++++++++++++++++++++++") print("Fitting histogram for %d < pt_{l} <%d" % (ptbins[i], ptbins[i + 1])) print("+++++++++++++++++++++++++++++++++++++++++\n") wsFile = TFile("tmpWorkspace.root") ws = wsFile.Get("tempWS") # fit with a gaussian if DOCRYSTALBALL: funct = TF1("crystal", "crystalball", fit_min, fit_max) funct.SetLineColor(kRed) if ws.data("hist").sum(False) < 1500: nDOF = (fit_max - fit_min) * 2 / (rebinFactor * 4) - 3 else: nDOF = (fit_max - fit_min) * 2 / rebinFactor - 3 ws.factory( "RooCBShape::cb(mass, mean[0.0], sigma[2,0,10], alphaL[3,-25,25], nL[5,-25,25])" ) ws.factory("BreitWigner::bw(mass,meanZ[91.187], width[2.495])") bw = ws.pdf("bw") cb = ws.pdf("cb") ws.var("mass").setBins(2000, "cache") ws.var("mass").setMin("cache", 0) ws.var("mass").setMax("cache", 1000) ## need to be adjusted to be higher than limit setting sigpdf = RooFFTConvPdf("sig", "sig", ws.var("mass"), bw, cb) getattr(ws, 'import')(sigpdf, RooCmdArg()) fitResult = ws.pdf("sig").fitTo(ws.data("hist"), RooFit.Save(), RooFit.SumW2Error(kFALSE), RooFit.Minos(kFALSE)) elif DOCRUIJFF: gSystem.Load("./RooCruijff_cxx.so") ws.factory( "RooCruijff::cb(mass, mean[0.0], sigma[2,0,20], sigma, alphaL[1,0,25], alphaR[1,0,25])" ) if ws.data("hist").sum(False) < 1500: nDOF = (fit_max - fit_min) * 2 / (6) - 3 elif ws.data("hist").sum(False) < 2500: nDOF = (fit_max - fit_min) * 2 / (4) - 3 else: nDOF = (fit_max - fit_min) * 2 / rebinFactor - 3 ws.factory("BreitWigner::bw(mass,meanZ[91.187], width[2.495])") bw = ws.pdf("bw") cb = ws.pdf("cb") ws.var("mass").setBins(2000, "cache") ws.var("mass").setMin("cache", 0) ws.var("mass").setMax("cache", 1000) ## need to be adjusted to be higher than limit setting sigpdf = RooFFTConvPdf("sig", "sig", ws.var("mass"), bw, cb) getattr(ws, 'import')(sigpdf, RooCmdArg()) fitResult = ws.pdf("sig").fitTo(ws.data("hist"), RooFit.Save(), RooFit.SumW2Error(kFALSE), RooFit.Minos(kFALSE)) elif DODOUBLECB: gSystem.Load("./RooDCBShape_cxx.so") ws.factory( "RooDCBShape::cb(mass, mean[0.0,-1.5,1.5], sigma[2,0,20], alphaL[2,0,25] , alphaR[2,0,25], nL[1.5,0,25], nR[1.5,0,25])" ) if i == 0: ws.var("nL").setVal(1) ws.var("nR").setVal(1) ws.factory("BreitWigner::bw(mass,meanZ[91.187], width[2.495])") bw = ws.pdf("bw") cb = ws.pdf("cb") ws.var("mass").setBins(2000, "cache") ws.var("mass").setMin("cache", 0) ws.var("mass").setMax("cache", 1000) ## need to be adjusted to be higher than limit setting sigpdf = RooFFTConvPdf("sig", "sig", ws.var("mass"), bw, cb) getattr(ws, 'import')(sigpdf, RooCmdArg()) fitResult = ws.pdf("sig").fitTo(ws.data("hist"), RooFit.Save(), RooFit.SumW2Error(kFALSE), RooFit.Minos(kFALSE)) chi2 = RooChi2Var("bla", "blubb", ws.pdf("sig"), ws.data("hist")).getVal() if ws.data("hist").sum(False) < 1500: nDOF = (fit_max - fit_min) * 2 / (6) - 5 elif ws.data("hist").sum(False) < 2500: nDOF = (fit_max - fit_min) * 2 / (4) - 5 else: nDOF = (fit_max - fit_min) * 2 / rebinFactor - 5 chi2 = RooChi2Var("bla", "blubb", ws.pdf("sig"), ws.data("hist")).getVal() nDOFforWS = RooRealVar('nDOF', 'nDOF', nDOF) getattr(ws, 'import')(nDOFforWS, RooCmdArg()) chi2forWS = RooRealVar('chi2', 'chi2', chi2) getattr(ws, 'import')(chi2forWS, RooCmdArg()) mean = RooRealVar('Mean', 'Mean', ws.var("meanZ").getVal()) getattr(ws, 'import')(mean, RooCmdArg()) meane = RooRealVar('Meane', 'Meane', ws.var("meanZ").getError()) getattr(ws, 'import')(meane, RooCmdArg()) sig = RooRealVar('Sig', 'Sig', ws.var("sigma").getVal()) getattr(ws, 'import')(sig, RooCmdArg()) sige = RooRealVar('Sige', 'Sige', ws.var("sigma").getError()) getattr(ws, 'import')(sige, RooCmdArg()) c1 = TCanvas("c1", "c1", 700, 700) c1.cd() plotPad = TPad("plotPad", "plotPad", 0, 0, 1, 1) style = setTDRStyle() gStyle.SetOptStat(0) gStyle.SetTitleXOffset(1.45) gStyle.SetPadLeftMargin(0.2) gStyle.SetTitleYOffset(2) plotPad.UseCurrentStyle() plotPad.Draw() plotPad.cd() if DODOUBLECB or DOCRYSTALBALL or DOCRUIJFF: ws.var("mass").setBins(30) frame = ws.var('mass').frame( RooFit.Title('Invariant mass of dimuon pairs')) frame.GetXaxis().SetTitle('m_{#mu#mu} [GeV]') frame.GetYaxis().SetTitle("Events / 2 GeV") RooAbsData.plotOn(ws.data('hist'), frame, RooFit.Name("hist")) ws.pdf('sig').plotOn(frame, RooFit.Name("sig")) frame.Draw() #chi2 = frame.chiSquare("sig","hist",nDOF) else: h.GetXaxis().SetTitle("m_{ll} [GeV]") h.SetLineColor(kBlack) h.GetXaxis().SetRangeUser(fit_min, fit_max) h.SetMarkerStyle(20) h.SetMarkerSize(0.7) h.Draw("E") if DOCRYSTALBALL or DOCRUIJFF or DODOUBLECB: funct.Draw("SAME") else: gaus.Draw("SAME") latex = TLatex() latex.SetTextFont(42) latex.SetTextAlign(31) latex.SetTextSize(0.04) latex.SetNDC(True) latexCMS = TLatex() latexCMS.SetTextFont(61) latexCMS.SetTextSize(0.055) latexCMS.SetNDC(True) latexCMSExtra = TLatex() latexCMSExtra.SetTextFont(52) latexCMSExtra.SetTextSize(0.03) latexCMSExtra.SetNDC(True) latex.DrawLatex(0.95, 0.96, "(13 TeV)") cmsExtra = "Preliminary" latexCMS.DrawLatex(0.78, 0.88, "CMS") yLabelPos = 0.84 latexCMSExtra.DrawLatex(0.78, yLabelPos, "%s" % (cmsExtra)) latexFit1 = TLatex() latexFit1.SetTextFont(42) latexFit1.SetTextSize(0.035) latexFit1.SetNDC(True) latexFit1.DrawLatex(0.25, 0.84, "%d GeV < p_{T} < %d GeV" % (ptbins[i], ptbins[i + 1])) latexFit = TLatex() latexFit.SetTextFont(42) latexFit.SetTextSize(0.030) latexFit.SetNDC(True) latexFit.DrawLatex( 0.25, 0.74, "%s = %5.3g #pm %5.3g GeV" % ("mean bias", ws.var("mean").getVal(), ws.var("mean").getError())) if funct == "CB": latexFit.DrawLatex( 0.25, 0.7, "%s = %5.3g #pm %5.3g GeV" % ("#sigma", ws.var("sigma").getVal(), ws.var("sigma").getError())) latexFit.DrawLatex( 0.25, 0.66, "%s = %5.3g #pm %5.3g" % ("alphaL", ws.var("alphaL").getVal(), ws.var("alphaL").getError())) latexFit.DrawLatex( 0.25, 0.62, "%s = %5.3g #pm %5.3g" % ("nL", ws.var("nL").getVal(), ws.var("nL").getError())) if funct == "cruijff": latexFit.DrawLatex( 0.25, 0.7, "%s = %5.3g #pm %5.3g GeV" % ("#sigma", ws.var("sigma").getVal(), ws.var("sigma").getError())) latexFit.DrawLatex( 0.25, 0.66, "%s = %5.3g #pm %5.3g" % ("alphaL", ws.var("alphaL").getVal(), ws.var("alphaL").getError())) latexFit.DrawLatex( 0.25, 0.62, "%s = %5.3g #pm %5.3g" % ("alphaR", ws.var("alphaR").getVal(), ws.var("alphaR").getError())) if funct == "doubleCB": latexFit.DrawLatex( 0.25, 0.7, "%s = %5.3g #pm %5.3g GeV" % ("#sigma", ws.var("sigma").getVal(), ws.var("sigma").getError())) latexFit.DrawLatex( 0.25, 0.66, "%s = %5.3g #pm %5.3g" % ("alphaL", ws.var("alphaL").getVal(), ws.var("alphaL").getError())) latexFit.DrawLatex( 0.25, 0.62, "%s = %5.3g #pm %5.3g" % ("alphaR", ws.var("alphaR").getVal(), ws.var("alphaR").getError())) latexFit.DrawLatex( 0.25, 0.58, "%s = %5.3g #pm %5.3g" % ("nL", ws.var("nL").getVal(), ws.var("nL").getError())) latexFit.DrawLatex( 0.25, 0.54, "%s = %5.3g #pm %5.3g" % ("nR", ws.var("nR").getVal(), ws.var("nR").getError())) latexFit.DrawLatex( 0.25, 0.5, "#chi^{2}/ndf = %5.1f / %2.0f = %4.2f" % (chi2, nDOF, chi2 / nDOF)) saveas = "/MassRes_%s_%s_Pt%d_%d_%s" % (trackType, flavour, ptbins[i], ptbins[i + 1], rap) c1.SaveAs(output + saveas + ".root") c1.SaveAs(output + saveas + ".C") c1.SaveAs(output + saveas + ".png") c1.SaveAs(output + saveas + ".pdf") print("DONE Fitting...") ws.writeToFile("tmpWorkspaceReturn.root")
def bw_fit(ecm, infile, outdir, reconstruction): """Breit-Wigner fit of the Mw distribution""" file_ = TFile(infile, "r") file_.cd() mass_ = 'h_mW2' h_mass = gDirectory.Get(mass_) scale = h_mass.GetXaxis().GetBinWidth(1) / (h_mass.Integral("width")) h_mass.Scale(scale) mass_min = 40 mass_max = 120 mass = RooRealVar("Dijet mass", "Dijet mass", mass_min, mass_max, "GeV") # parameters for gaussian function gaus_sig = RooRealVar("#sigma_{G}", "Core Width", 1., 0.5, 10., "GeV") # gaus_sig.setConstant() # parameters for Crystall Ball distribution m_ = RooRealVar("#Delta m", "Bias", 0., -3., 3., "GeV") sigma = RooRealVar("#sigma", "Width", 1.7, 0., 10., "GeV") alpha = RooRealVar("#alpha", "Cut", -0.15, -5., 0.) n = RooRealVar("n", "Power", 2.4, 0.5, 10.) alpha.setConstant() n.setConstant() # Parameters for Breit-Wigner distribution m_res = RooRealVar("M_{W}", "W boson mass", 80.385, 80.0, 81.0, "GeV") width = RooRealVar("#Gamma", "W width", 2.085, 1.5, 2.5, "GeV") m_res.setConstant() width.setConstant() # Cristall-Ball lineshape resG = RooGaussian("resG", "Gaussian distribution", mass, m_, gaus_sig) resCB = RooCBShape("resCB", "Crystal Ball distribution", mass, m_, sigma, alpha, n) fracG = RooRealVar("f_{G}", "Gaussian Fraction", 0., 0., 1.) res = RooAddPdf("res", "Resolution Model", resG, resCB, fracG) # Breit-wigner lineshape bw = RooBreitWigner("bw", "Breit-Wigner distribution", mass, m_res, width) # Convolution bw_CB_conv = RooFFTConvPdf("bw_CB_conv", "Convolution", mass, bw, res) # Background p.d.f bgtau = RooRealVar("a_{BG}", "Backgroung Shape", -0.15, -1.0, 0.0, "1/GeV/c^{2}") bg = RooExponential("bg", "Background distribution", mass, bgtau) # Fit model nentries = h_mass.GetEntries() nsigmin = 0.5 * nentries nsigmean = 1.0 * nentries nsigmax = 1.05 * nentries nbkgmean = 0.01 * nentries nbkgmax = 0.1 * nentries nsig = RooRealVar("N_S", "#signal events", nsigmean, nsigmin, nsigmax) nbkg = RooRealVar("N_B", "#background events", nbkgmean, 0, nbkgmax) model = RooAddPdf("model", "W mass fit", RooArgList(bw_CB_conv, bg), RooArgList(nsig, nbkg)) ###### FIT c_name = "c_ " + mass_ + "_" + str(ecm) + "_" + reconstruction + "_fit" c_mass_fit = TCanvas( c_name, 'Fit of the reconstructed mass distribution with a convolution of Breit-Wigner and Crystal-Ball', 700, 500) c_mass_fit.cd() data = RooDataHist("data", "data", RooArgList(mass), h_mass) frame = mass.frame() data.plotOn(frame) model.fitTo(data, RooFit.Optimize(0)) model.plotOn(frame) model.paramOn(frame, RooFit.Layout(0.6, 0.90, 0.85)) frame.Draw() # norm = h_mass.Integral()/bw_CB_conv.createIntegral(RooArgSet(mass)).getValV() # m = m_.getValV()*norm # s = sigma.getValV()*norm m = m_.getVal() s = sigma.getVal() print("\n\n----------------------------------------------") print(" Fit results :") print(" Bias to apply on mW : {} GeV".format(m)) print(" Mw = {} +/- {} GeV".format((m + 80.385), s)) print("--------------------------------------------------") raw_input("") c_mass_fit.Print("{}fit/fit_{}_{}_{}.pdf".format(outdir, mass_, ecm, reconstruction)) # write into an output file and close the file outfilename = "{}fit/fit_{}_{}.root".format(outdir, mass_, ecm) outfile = TFile(outfilename, "UPDATE") c_mass_fit.Write("", TObject.kOverwrite) outfile.Write() outfile.Close()
def RooFitHist(inputhist,title='title',path='.'): # RooFit.gErrorIgnoreLevel = RooFit.kInfo # <6.02 # RooFit.SetSilentMode()# >6.02 # RooMsgService().instance().SetSilentMode(kTRUE) fitbinning=array('d') binwidth=200 #NBins=(14000/binwidth) - ( (1040/binwidth) + 1 ) Mjj NBins=(8000/binwidth) - ( (200/binwidth)+1 )#pT for i in range(NBins+1): fitbinning.append(210+i*binwidth)# Mjj 1050 # print(fitbinning) #import numpy as np #fitbinning=np.linspace(0,8000,81) hist=inputhist.Rebin(NBins,"fit parameter",fitbinning) #hist=inputhist.Rebin(80,"fit parameter", fitbinning) #meanstart=hist.GetBinCenter(2000) meanstart=hist.GetBinCenter(hist.GetMaximumBin())#maximum sigmastart=hist.GetRMS() #sigmastart=3000 print('meanstart:',meanstart,'sigmastart:',sigmastart) # inputhist.Draw() # hist.Draw() # hold=raw_input('press enter to exit.') gStyle.SetOptFit(1111) gStyle.SetOptTitle(0) RooFit.SumW2Error(kTRUE) RooFit.Extended(kTRUE) # RooDataHist::adjustBinning(dh): fit range of variable mjj expanded to nearest bin boundaries: [1050,13850] --> [1050,13850] mjj=RooRealVar('mjj','P_{T-AK8}',fitbinning[0],fitbinning[len(fitbinning)-1],'GeV') mjjral=RooArgList(mjj) dh=RooDataHist('dh','dh',mjjral,RooFit.Import(hist)) #shape.fitTo(dh,RooFit.Range("FitRange"),RooFit.Extended(True),RooFit.SumW2Error(False)) shapes={} #Gaussian not really # 3rd, 4th and 5th arguments are: (starting value, minimum possible value, maximum possible value) -- not goot gaussmean = RooRealVar('#mu_{gauss}','mass mean value',meanstart,0,2*meanstart) gausssigma= RooRealVar('#sigma_{gauss}','mass resolution',sigmastart,0,2*meanstart) gauss=RooGaussian('gauss','gauss',mjj,gaussmean,gausssigma) shapes.update({'Gauss':gauss}) #poisson poissonmean = RooRealVar('#mu_{poisson}', 'pT mean value', meanstart,0,2*meanstart) poissonsigma = RooRealVar('#sigma_{poisson]', 'pT resolution', sigmastart, 0, 2*sigmastart) poisson = RooPoisson('poisson', 'poisson', mjj, poissonmean, False) shapes.update({'Poisson': poisson}) #Landau -- not good landaumean=RooRealVar('#mu_{landau}','mean landau',meanstart,0,2*meanstart) landausigma= RooRealVar('#sigma_{landau}','mass resolution',sigmastart,0,2*sigmastart)#bzw8 landau=RooLandau('landau','landau',mjj,landaumean,landausigma) shapes.update({'Landau':landau}) #CrystalBall -> this is close to be good but matrix error :( mean = RooRealVar('#mu','mean',meanstart,0,2*meanstart) sigma= RooRealVar('#sigma','sigma',sigmastart,0,2*sigmastart) alpha=RooRealVar('#alpha','Gaussian tail',-1000,0) n=RooRealVar('n','Normalization',-1000,1000) cbshape=RooCBShape('cbshape','crystalball PDF',mjj,mean,sigma,alpha,n) shapes.update({'CrystalBall':cbshape}) #Voigt ---pff voigtmean = RooRealVar('#mu','mass mean value',meanstart,0,2*meanstart) voigtwidth = RooRealVar('#gamma','width of voigt',0,100) voigtsigma= RooRealVar('#sigma','mass resolution',sigmastart,0,150) voigt=RooVoigtian('voigt','voigt',mjj,voigtmean,voigtwidth,voigtsigma) shapes.update({'Voigt':voigt}) #BreitWigner--worst bwmean = RooRealVar('#mu','mass mean value',meanstart,0,2*meanstart) bwwidth = RooRealVar('#sigma','width of bw',sigmastart,100, 150) bw=RooBreitWigner('bw','bw',mjj,bwmean,bwwidth) shapes.update({'BreitWigner':bw}) #Logistics #logisticsmean=RooRealVar('#mu_{logistics}','mean logistics',meanstart,0,2*meanstart) #logisticssigma= RooRealVar('#sigma_{logistics}','mass resolution',sigmastart,0,2*sigmastart) #logistics=RooLogistics('logistics','logistics',mjj,logisticsmean,logisticssigma) #shapes.update({'Logistics':logistics}) #ExpAndGauss expgaussmean=RooRealVar('#mu_{expgauss}','mean expgauss',meanstart,490,900) expgausssigma= RooRealVar('#sigma_{expgauss}','mass resolution',sigmastart,20,3*sigmastart) expgausstrans= RooRealVar('trans','trans',0,1000) ExpAndGauss=RooExpAndGauss('expgauss','expgauss',mjj,expgaussmean,expgausssigma,expgausstrans) shapes.update({'ExpAndGauss':ExpAndGauss}) #Exp #expmean=RooRealVar('') #BifurGauss -bad BifurGaussmean=RooRealVar('#mu_{BifurGauss}','mean BifurGauss',meanstart,0,2*meanstart) BifurGausslsigma= RooRealVar('#sigma_{left}','mass resolution',sigmastart,200,2*sigmastart)#2*sigmastart BifurGaussrsigma= RooRealVar('#sigma_{right}','mass resolution',sigmastart,200,2*sigmastart) BifurGauss=RooBifurGauss('BifurGauss','BifurGauss',mjj,BifurGaussmean,BifurGausslsigma,BifurGaussrsigma) shapes.update({'BifurGauss':BifurGauss}) #Chebychev -nope Chebychev1=RooRealVar('c0','Chebychev0',-1000,1000) Chebychev2= RooRealVar('c1','Chebychev1',-1000,1000) Chebychev3= RooRealVar('c2','Chebychev2',2,-1000,1000) Chebychev=RooChebychev('Chebychev','Chebychev',mjj,RooArgList(Chebychev1,Chebychev2,Chebychev3)) shapes.update({'Chebychev':Chebychev}) #Polynomial -nope Polynomial1=RooRealVar('Polynomial1','Polynomial1',100,0,1000) Polynomial2= RooRealVar('Polynomial2','Polynomial2',100,0,1000) Polynomial=RooPolynomial('Polynomial','Polynomial',mjj,RooArgList(Polynomial1,Polynomial2)) shapes.update({'Polynomial':Polynomial}) #pareto #___________________________________________________________We will see #Convolutions #-> use bin > 1000 for better accuracy -----cyclic trouble #-> Convolution depends on order!!! RooFFTConvPdf the first p.d.f. is the theory model and that the second p.d.f. is the resolution model # #LandauGauss Convolution - really bad landaugauss=RooFFTConvPdf('landaugauss','landau x gauss',mjj,landau, gauss) #landaugauss.setBufferFraction(126) shapes.update({'LandauGauss':landaugauss}) #GaussLandau Convolution -> Better but NOT posdef. ...but for 100 it is gausslandau=RooFFTConvPdf('gausslandau','gauss x landau ',mjj,gauss,landau) #gausslandau.setBufferFraction(126) shapes.update({'GaussLandau':gausslandau}) #CrystalBallLandau Convolution cbshape x landau looks better -> status failed crystlandau=RooFFTConvPdf('crystallandau','cbshape x landau', mjj, landau, cbshape) crystlandau.setBufferFraction(39) shapes.update({'CrystLandau': crystlandau}) #BifurGaussLandau Convolution -> Better in look, NO matrix error for Binwidth 200 BifurGaussLandau=RooFFTConvPdf('bifurgausslandau','landau x bifurgauss',mjj,landau, BifurGauss) BifurGaussLandau.setBufferFraction(39) #against over cycling shapes.update({'BifurGaussLandau':BifurGaussLandau}) #CrystalGauss Convolution looks better -> status failed crystgauss=RooFFTConvPdf('crystalgauss','cbshape x gauss', mjj, cbshape, gauss) #crystgauss.setBufferFraction(39) shapes.update({'CrystGauss': crystgauss}) #BreitWignerLandau Convolution (Breitwigner = Lorentz)-> status OK.... BreitWignerLandau=RooFFTConvPdf('breitwignerlandau','breitwigner x landau',mjj,landau,bw,3) #BreitWignerLandau.setBufferFraction(48) #setBufferFraction(fraction of the sampling array size) ->cyclic behaviour fix #crystgauss.setShift(0,0) #s1 and s2 are the amounts by which the sampling ranges for pdf's are shifted respectively #(0,-(xmin+xmax)/2) replicates the default behavior #(0,0) disables the shifting feature altogether shapes.update({'BreitWignerLandau':BreitWignerLandau}) for fname in ['ExpAndGauss']: plottitle='%s Fit of %s'%(fname,title) shape=shapes[fname] # shape.fitTo(dh,RooFit.Range("FitRange"),RooFit.SumW2Error(True)) #shape.fitTo(dh,RooFit.Extended(True),RooFit.SumW2Error(True)) mjj.setRange("FitRange",500,4000)#tried shape.fitTo(dh,RooFit.Range("FitRange"),RooFit.Extended(False),RooFit.SumW2Error(True)) frame=mjj.frame(RooFit.Title(plottitle)) #frame.GetYaxis().SetTitleOffset(2) dh.plotOn(frame,RooFit.MarkerStyle(4)) shape.plotOn(frame,RooFit.LineColor(2)) ndof=dh.numEntries()-3 print ('ndof', ndof) #chiSquare legend chi2 = frame.chiSquare()#there are 2 chiSquare. the 2cond returns chi2/ndf /// \return \f$ \chi^2 / \mathrm{ndf} \f$ print ('chi2', chi2) probChi2 = TMath.Prob(chi2*ndof, ndof)# why chi2*ndof ?! makes no sense to me #Double_t Prob(Double_t chi2, Int_t ndf) #Computation of the probability for a certain Chi-squared (chi2) #and number of degrees of freedom (ndf). #P(a,x) represents the probability that the observed Chi-squared #for a correct model should be less than the value chi2. #The returned probability corresponds to 1-P(a,x), !!!! #which denotes the probability that an observed Chi-squared exceeds #the value chi2 by chance, even for a correct model. #--- NvE 14-nov-1998 UU-SAP Utrecht #probChi2=TMath.Prob(chi2, ndof) chi2 = round(chi2,2) #probChi2 = round(probChi2,2) leg = TLegend(0.5,0.5,0.5,0.65)#0.9 leg.SetBorderSize(0) leg.SetFillStyle(0) shape.paramOn(frame, RooFit.Layout(0.5,0.9,0.9)) leg.AddEntry(0,'#chi^{2} ='+str(chi2),'') leg.AddEntry(0,'Prob #chi^{2} = '+str(probChi2),'') leg.SetTextSize(0.04) frame.addObject(leg) canv=TCanvas(plottitle,plottitle,700,700) canv.SetLogy() canv.SetLeftMargin(0.20) canv.cd() frame.SetMaximum(10**(1)) frame.SetMinimum(10**(-11))#from -3 -> -6 frame.Draw() #canv.Print(path+'/%s__%sS2MoreLessY.pdf'%(title,fname)) raw_input('press enter to continue') return chi2
rrv_mean_sigma_X1 = RooRealVar("rrv_sigma_shift_lep_scale_CB"+options.channel+"_"+options.category,"rrv_sigma_shift_scale_CB"+options.channel+"_"+options.category,float(0.005)); rrv_mean_sigma_X2 = RooRealVar("rrv_sigma_shift_jes_CB"+options.channel+"_"+options.category,"rrv_sigma_shift_scale_CB"+options.channel+"_"+options.category,float(0.033)); rrv_mean_sigma_X3 = RooRealVar("rrv_sigma_shift_res_CB"+options.channel+"_"+options.category,"rrv_sigma_shift_res_CB"+options.channel+"_"+options.category,float(0.030)); rrv_mean_sigma_X1.setConstant(kTRUE); rrv_mean_sigma_X2.setConstant(kTRUE); rrv_mean_sigma_X3.setConstant(kTRUE); rrv_total_sigma_CB = RooFormulaVar("rrv_total_sigma_CB"+options.channel+"_"+options.category,"@0*(1+@1*@2)*(1+@3*@4)*(1+@5*@6)", RooArgList(rrv_sigma_CB,rrv_sigma_scale_p1,rrv_mean_sigma_X1,rrv_sigma_scale_p2,rrv_mean_sigma_X2,rrv_sigma_scale_p3,rrv_mean_sigma_X3)); new_signal = ROOT.RooDoubleCrystalBall("DoubleCB_BulkG_WW_"+options.channel+"_"+options.category+"_mlvj","DoubleCB_BulkG_WW_"+options.channel+"_"+options.category+"_mlvj",old_workspace.var("rrv_mass_lvj"),rrv_mean_CB,rrv_total_sigma_CB,rrv_alpha1_CB,rrv_n1_CB,rrv_alpha2_CB,rrv_n2_CB); ### FFT ConvPdf original_binnning = old_workspace.var("rrv_mass_lvj").getBin(); old_workspace.var("rrv_mass_lvj").setBins(1000,"cache"); model_pdf = RooFFTConvPdf("BulkWW_xww_%s_%s"%(options.channel,options.category),"BulkWW_xww_%s_%s"%(options.channel,options.category),old_workspace.var("rrv_mass_lvj"),bw,new_signal); model_pdf.setBufferFraction(1.0); old_workspace.var("rrv_mass_lvj").setBins(int(original_binnning)); model_pdf.SetName("BulkWW_xww_%s_%s"%(options.channel,options.category)); getattr(new_workspace,"import")(model_pdf); ### iterate on the workspace element parameters print "----------- Parameter Workspace -------------"; parameters_workspace = new_workspace.allVars(); par = parameters_workspace.createIterator(); par.Reset(); param = par.Next() while (param): param.Print(); param=par.Next()
def PeakFit_likelihood(Likelihood_cut: pd.DataFrame, mass_energy: pd.DataFrame, cutval, plots=True, constant_mean=True, constant_width=True, classifier_name='Likelihood', CB=True, Gauss=False, bkg_comb=True, bkg_exp=False, bkg_cheb=False): print('Starting fit...') matplotlib.use('Agg') # Check if we have mass in MeV or GeV if np.mean(mass_energy) > 1000: normalization_mass = 1000 else: normalization_mass = 1 sns.set_style("whitegrid") # White background on plot prediction = Likelihood_cut # rename to prediction # Set range mZmin = 60.0 mZmax = 130.0 # Number of bins NbinsZmass = 100 #Initiate the mass variable m_ee = ROOT.RooRealVar("m_ee", "Invariant mass (GeV/c^{2})", mZmin, mZmax) m_ee.setRange("MC_mZfit_range", mZmin, mZmax) # ============================================================================= # fit signal # ============================================================================= # Make a mask in the signal range. Prediction is 0 or 1, so above 0.5 is signal mask_mass = (mass_energy / normalization_mass > mZmin) & ( mass_energy / normalization_mass < mZmax) & (prediction > 0.5) Z_mass_signal = np.array(mass_energy[mask_mass] / normalization_mass) #Make np.array # Initiate 1D histogram h_mZ_all = ROOT.TH1D("h_mZ_all", "Histogram of Z mass", NbinsZmass, mZmin, mZmax) for isample in range(Z_mass_signal.shape[0]): score = Z_mass_signal[isample] h_mZ_all.Fill(score) # Constructs histogram with m_ee as argument from the 1d histogram h_mZ_all mc_Zee_mZ = ROOT.RooDataHist("mc_Zee_mZ", "Dataset with Zee m_ee", RooArgList(m_ee), h_mZ_all) # Define variables for the fits. # BW: Breit-Wigner. CB: Crystal-Ball meanBW = ROOT.RooRealVar("meanBW", "meanBW", 91.1876, 60.0, 120.0) #91.1876 meanBW.setConstant(True) # this is a theoretical constant sigmaBW = ROOT.RooRealVar("sigmaBW", "sigmaBW", 2.4952, 2.0, 20.0) #2.4952 sigmaBW.setConstant(True) # this is a theoretical constant # if constant_mean: func_BW = ROOT.RooBreitWigner("func_BW", "Breit-Wigner", m_ee, meanBW, sigmaBW) # Make the function from the constants # Crystal ball if CB: meanCB = RooRealVar("meanCB", "meanCB", -0.0716, -10.0, 10.0) # meanCB.setConstant(True) #if commented out, it can float between the minimum and maximum sigmaCB = RooRealVar("sigmaCB", "sigmaCB", 0.193, 0, 15) # sigmaCB.setConstant(True) alphaCB = RooRealVar("alphaCB", "alphaCB", 1.58, 0.0, 10.0) # alphaCB.setConstant(True) nCB = RooRealVar("nCB", "nCB", 0.886, -10, 50.0) # nCB.setConstant(True) func_sig_CB = RooCBShape("func_CB", "Crystal Ball", m_ee, meanCB, sigmaCB, alphaCB, nCB) # Define Crystal-Ball function # Gaussian elif Gauss: # Use Gaussian if True in function call meanGA = RooRealVar("meanGA", "meanGA", 10.0, -10.0, 10.0) sigmaGA = RooRealVar("sigmaGA", "sigmaGA", 3.0, 0.01, 10.0) if constant_width: sigmaGA.setConstant(True) nGA = RooRealVar("nGA", "nGA", 1.5, 0.0, 20.0) func_GA = RooGaussian("func_GA", "Gaussian", m_ee, meanGA, sigmaGA) #, nGA); if CB: # Convolute Breit-Wigner and Crystal-Ball print("Convoluting a Crystal-Ball and Breit-Wigner for signal") func_BWxCB_unextended = RooFFTConvPdf("func_BWxCB_unextended", "Breit-Wigner (X) Crystal Ball", m_ee, func_BW, func_sig_CB) elif Gauss: # Convolute Breit-Wigner and Gauss print("Convoluting a Gauss and Breit-Wigner for signal") func_BWxCB_unextended = RooFFTConvPdf("func_BWxCB_unextended", "Breit-Wigner (X) Gaussian", m_ee, func_BW, func_GA) else: # only Breit-Wigner fit on the signal print("Fitting only with Breit-Wigner for signal") func_BWxCB_unextended = func_BW m_ee.setRange("MC_mZfit_range", 85, 97) # Set the fit range for the signal nsig = RooRealVar("ntotal", "ntotal", 1000, 0, 10e6) # Define the variable for the number of signal func_BWxCB = ROOT.RooExtendPdf("signal_func_Zee", "signal_func_Zee", func_BWxCB_unextended, nsig) # Adding the nsig term to the pdf func_BWxCB.fitTo(mc_Zee_mZ, RooFit.Range("MC_mZfit_range")) # Fit the signal if plots: # Plots the signal using the function "root_plot" defined above mc_Zee_signal = root_plot(m_ee=m_ee, distribution=mc_Zee_mZ, fit=func_BWxCB, mZmin=mZmin, mZmax=mZmax, title=f'signal for cut {cutval}') #cut {cutval} # ============================================================================= # background # ============================================================================= nbkg = RooRealVar("nbkg", "nbkg", 1000, 0, 10e6) # Define the variable for the number of background #if True: m_ee.setRange("MC_mZfit_range", mZmin, mZmax) # Set range for fit as defined in the beginning c_bkg_mZ = ROOT.TCanvas("c_bkg_mZ", "", 0, 0, 1000, 500) # Make the canvas for plotting Z_mass_background = np.array(mass_energy[mask_mass] / normalization_mass) # Mask for background h_mZWenu_all = ROOT.TH1D("h_mZ_all", "Histogram of Z mass", NbinsZmass, mZmin, mZmax) # Initiate 1D histogram for isample in range(Z_mass_background.shape[0]): score = Z_mass_background[isample] h_mZWenu_all.Fill(score) # Create the lin + exponential fit lam = RooRealVar("lambda", "Exponent", -0.04, -5.0, 0.0) func_expo = ROOT.RooExponential("func_expo", "Exponential PDF", m_ee, lam) #coef_pol1 = RooRealVar("coef_pol1", "Slope of background", 0.0, -10.0, 10.0); #func_pol1 = ROOT.RooPolynomial("func_pol1", "Linear PDF", m_ee, RooArgList(coef_pol1)); # Create Chebychev polymonial a0 = RooRealVar("a0", "a0", -0.4, -5.0, 5.0) a1 = RooRealVar("a1", "a1", -0.03, -5.0, 5.0) a2 = RooRealVar("a2", "a2", 0.02, -5.0, 5.0) a3 = RooRealVar("a3", "a3", 0.02, -5.0, 5.0) # Polynomials with different order func_Cpol1 = RooChebychev("func_Cpol1", "Chebychev polynomial of 1st order", m_ee, RooArgList(a0, a1)) func_Cpol2 = RooChebychev("func_Cpol2", "Chebychev polynomial of 2nd order", m_ee, RooArgList(a0, a1, a2)) func_Cpol3 = RooChebychev("func_Cpol3", "Chebychev polynomial of 3rd order", m_ee, RooArgList(a0, a1, a2, a3)) f_exp_mZ = RooRealVar("N_lin_mZ", "CLinear fraction", 0.50, 0, 1) m_ee.setRange("low", 60, 70) m_ee.setRange("high", 110, 130) # Adding exponential and Chebychev if comb: if bkg_comb: func_ExpLin_mZ_unextended = ROOT.RooAddPdf( "func_ExpLin_mZ_unextended", "Exponential and Linear PDF", RooArgList(func_Cpol3, func_expo), RooArgList(f_exp_mZ)) elif bkg_exp: func_ExpLin_mZ_unextended = func_expo elif bkg_cheb: func_ExpLin_mZ_unextended = func_Cpol3 else: print("No background fit called. Exiting") return None func_ExpLin_mZ = ROOT.RooExtendPdf("func_ExpLin_mZ", "func_ExpLin_mZ", func_ExpLin_mZ_unextended, nbkg) # Adding the nbkg term to the pdf # Constructs histogram with m_ee as argument from the 1d histogram h_mZ_all mc_Wenu_mZ = ROOT.RooDataHist("mc_Zee_mZ", "Dataset with Zee m_ee", RooArgList(m_ee), h_mZWenu_all) func_ExpLin_mZ.fitTo(mc_Wenu_mZ, RooFit.Range("MC_mZfit_range")) #ROOT.RooFit.Range("low,high")); # Fits background #Plotting background residue = root_plot(m_ee=m_ee, distribution=mc_Wenu_mZ, fit=func_ExpLin_mZ, mZmin=mZmin, mZmax=mZmax, title=f'Background for cut {cutval}') # # ============================================================================= # Combining signal and background # ============================================================================= m_ee.setRange("MC_mZfit_range", mZmin, mZmax) Z_mass = np.array(mass_energy[mask_mass] / normalization_mass) h_mZWenu = ROOT.TH1D("h_mZ_all", "Histogram of Z mass", NbinsZmass, mZmin, mZmax) for isample in range(Z_mass.shape[0]): score = Z_mass[isample] h_mZWenu.Fill(score) # Constructs histogram with m_ee as argument from the 1d hist ogram h_mZ_all mc_ZeeWenu_mZ = ROOT.RooDataHist("mc_Zee_mZ", "Dataset with Zee m_ee", RooArgList(m_ee), h_mZWenu) ## Fits the data and returns the fraction of background f_bkg_mZ = RooRealVar("f_bkg_mZ", "Signal fraction", nbkg.getVal() / nsig.getVal(), 0.0, 1) ## Combining the signal and background fits func_SigBkg_mZ_unextended = ROOT.RooAddPdf( "func_SigBkg_mZ", "Signal and Background PDF", RooArgList(func_ExpLin_mZ_unextended, func_BWxCB_unextended), RooArgList(f_bkg_mZ)) # func_SigBkg_mZ_unextended = func_BWxCB_unextended;#ROOT.RooAddPdf("func_SigBkg_mZ", "Signal and Background PDF", RooArgList(func_BWxCB_unextended, func_BWxCB_unextended), RooArgList(f_bkg_mZ)); ntotal = RooRealVar("ntotal", "ntotal", 10000, 0, 10e6) func_SigBkg_mZ = ROOT.RooExtendPdf("func_ExpLin_mZ", "func_ExpLin_mZ", func_SigBkg_mZ_unextended, ntotal) func_SigBkg_mZ.fitTo(mc_ZeeWenu_mZ) # Fits the full data set if plots: mc_ZeeWenu_mZ_resid = root_plot(m_ee=m_ee, distribution=mc_ZeeWenu_mZ, fit=func_SigBkg_mZ, mZmin=mZmin, mZmax=mZmax, title=f'Bkg+Sig for cut {cutval}') # Baseline ntotal = 41231 (Data) # fraction 0.9333 # Baseline ntotal = 74747 (MC) # fraction 0.4427 # Malte script len(Z_mass) bkg = len(Z_mass) * f_bkg_mZ.getVal() sig = len(Z_mass) * (1 - f_bkg_mZ.getVal()) print(f_bkg_mZ.getVal()) #DATA #BL_sig = 41231*(1-0.9333) # BL = baseline, the number is the fraction of bkg in baseline #BL_bkg = 41231*0.9333 # BL = baseline # DATA OS # BL_sig = 22276 * (1-0.853) # BL = baseline, the number is the fraction of bkg in baseline # BL_bkg = 22276 * 0.853 # BL = baseline # DATA SS # BL_sig = 18925 * (1-0.993552)#74747 * (1-0.4427)#41054 # BL_bkg = 18925 - BL_sig #MC OS # exp BL_sig = 46547 * (1 - 0.0350) #74747 * (1-0.4427)#41054 BL_bkg = 46547 * 0.0350 #comb #BL_sig = 74747*(1-0.4427) # BL = baseline, the number is the fraction of bkg in baseline #BL_bkg = 74747*0.4427 # BL = baseline bkg_ratio = bkg / BL_bkg sig_ratio = sig / BL_sig max_residue = max(abs(mc_ZeeWenu_mZ_resid.getYAxisMax()), abs(mc_ZeeWenu_mZ_resid.getYAxisMin())) print(max_residue) print(bkg_ratio) print(sig_ratio) if (bkg_ratio < 1.009) & (sig_ratio < 1.009) & (abs( mc_ZeeWenu_mZ_resid.getYAxisMin()) < 4) & (abs( mc_ZeeWenu_mZ_resid.getYAxisMax()) < 4): # input('....') return BL_sig, BL_bkg, sig_ratio, bkg_ratio #max_residue, ntotal.getVal(), nsig.getVal(), nbkg.getVal()return sigmaCB if CB else sigmaGA #sig_ratio, sigma_sig, bkg_ratio, sigma_bkg else: return 0, 0, 0, 0
def fitLandauGaus(hist, full = False): ## c1 = ROOT.TCanvas() ## c1.Divide(2) ## c1.cd(1) ## hist.Draw() neg_landau = False if hist.GetMean() < 0.: neg_landau = True if neg_landau: hist = turnHisto(hist) hist.Rebin(2) hist.SetTitle('') hist.SetName('hSignal') ## c1.cd(2) ## hist.Draw('hist') ## c1.SaveAs('foobar.pdf') ### #if neg_landau: ### # func = ROOT.TF1('my_landau','[0] * TMath::Landau(-x,[1],[2])', hist.GetXaxis().GetXmin(), hist.GetXaxis().GetXmax()) ### # func.SetParameters(1, hist.GetMean(), hist.GetRMS() ) ### #else: ### func = ROOT.TF1('my_landau','[0] * TMath::Landau(x,[1],[2])', hist.GetXaxis().GetXmin(), hist.GetXaxis().GetXmax()) ### func.SetParameters(1, hist.GetMean(), hist.GetRMS() ) ### hist.Fit('my_landau','q') ### fit_res = [] ### fit_res.append(func.GetParameter(0) if not neg_landau else func.GetParameter(0)) ### fit_res.append(func.GetParameter(1) if not neg_landau else -1.*func.GetParameter(1)) ### fit_res.append(func.GetParameter(2) if not neg_landau else func.GetParameter(2)) ### return hist, fit_res ## ROOFIT VERSION xmin = hist.GetXaxis().GetXmin() xmax = hist.GetXaxis().GetXmax() mean = hist.GetMean() mp = hist.GetXaxis().GetBinCenter(hist.GetMaximumBin()) rms = hist.GetRMS() flandau = ROOT.TF1('flandau','landau',mp-20,mp+40) flandau.SetLineWidth(1) flandau.SetLineColor(ROOT.kBlue) hist2 = hist.Clone(hist.GetName()+'_2') hist2.Scale(1./hist2.GetBinContent(hist2.GetMaximumBin())) hist2.Fit(flandau,'Q','',mp-20,mp+40) flandau2 = flandau.Clone('flandau2') flandau2.SetRange(0,500) flandau2.SetLineStyle(2) for i in range(flandau.GetNpar()): flandau2.SetParLimits(i,flandau.GetParameter(i),flandau.GetParameter(i)) hist2.Fit(flandau2,'Q+')#,'same',mp-20,mp+40) for i in range(flandau.GetNpar()): hist2.GetFunction('flandau2').SetParameter(i,flandau.GetParameter(i)) for i in range(flandau.GetNpar()): print flandau.GetParameter(i),flandau2.GetParameter(i) x = RooRealVar('x', 'signal / adc', 0,500) x.setRange("signal",mp - 40, mp+90) x.setRange("draw",0,500) ral = RooArgList(x) dh = RooDataHist('dh', 'dh', ral, RooFit.Import(hist)) if full: ml = RooRealVar('ml', 'mean landau' , mp, mp-20., mp+30) sl = RooRealVar('sl', 'sigma landau', 10, 1., 25.) else: ml = RooRealVar('ml', 'mean landau' , mean, mean-40., mean) sl = RooRealVar('sl', 'sigma landau', 10., 6., 14.) landau = RooLandau ('lx', 'lx', x, ml, sl) mean = 0 if full: mg = RooRealVar ('mg', 'mean gaus' , 0,0,0) sg = RooRealVar ('sg', 'sigma gaus', flandau.GetParameter(2), 0.1, 30.) else: mg = RooRealVar ('mg', 'mean gaus' , 0,0,0) #mean, mean-30., mean+30.) sg = RooRealVar ('sg', 'sigma gaus', 2., 0.1, 20.) gaus = RooGaussian('gx', 'gx', x, mg, sg) x.setBins(1000,'cache') ## Construct landau (x) gauss lxg = RooFFTConvPdf('lxg','landau (x) gaus', x, landau, gaus) lxg.fitTo(dh,RooFit.Range("signal")) #,RooFit.Normalization(ROOT.RooAbsReal.NumEvent,1)) a = lxg.getParameters(dh) print 'fit par0 %+6.1f'%flandau.GetParameter(0) print 'fit par1 %+6.1f'%flandau.GetParameter(1) print 'fit par2 %+6.1f'%flandau.GetParameter(2) print 'mp %+6.1f'%mp print 'rms %+6.1f'%rms print 'lxg.getParameters(dh).getRealValue(\'ml\'): %+6.1f'% a.getRealValue('ml') print 'lxg.getParameters(dh).getRealValue(\'sl\'): %+6.1f'% a.getRealValue('sl') print 'lxg.getParameters(dh).getRealValue(\'sg\'): %+6.1f'% a.getRealValue('sg') frame = x.frame(RooFit.Title('landau (x) gauss convolution'),RooFit.Range("draw")) #,RooFit.Normalization(ROOT.RooAbsReal.NumEvent,1)) dh.plotOn(frame,RooFit.Range("draw")) #,RooFit.Normalization(1./dh.numEntries(),ROOT.RooAbsReal.Raw)) lxg.plotOn(frame,RooFit.LineColor(ROOT.kRed),RooFit.Range("draw")) #,RooFit.Normalization(1,ROOT.RooAbsReal.Raw)) #lxg.plotOn(frame,RooFit.LineColor(ROOT.kBlue),RooFit.Range("signal"),RooFit.Components('lx,gx')) # c = ROOT.TCanvas('lg_convolution','landau (x) gaus', 600, 600) # c.Divide(2) # c.cd(1) # hist.Draw() # c.cd(2) # ROOT.gPad.SetLeftMargin(0.15) # frame.GetYaxis().SetTitleOffset(1.4) # frame.Draw() # c.SaveAs('histograms/outputhisto'+hist.GetName().split('pz')[1]+'.pdf') return dh, copy.deepcopy(a), copy.deepcopy(frame),copy.deepcopy(hist2)