def draw(ws, res, eff, var, cat, xtitle, trig, nfitparams, xlow=0, xup=400, ymax=1.1, oldres=[]): # Set variable-width binning tmpbins = [x * 0.05 for x in range(0, 20)]+[1,10,20,30,40,50,60,70,80,90,100,110,120,140,160,180,200,220,240,280,320,360,400,480,600,750,1000] if kTrig == "PFMET100HT400" or kTrig == "PFMET80HT400" or kTrig == "PFMET80CJ30x2CSV07" or kTrig == "PFMET100CJ80CSV07": # low stat tmpbins = [0,10,20,30,40,50,60,70,80,90,100,110,120,140,160,200,240,320,400,480,600,750,1000] tmpbins2 = [xlow] + [x for x in tmpbins if (x > xlow and x < xup)] + [xup] bins = RooBinning(len(tmpbins2)-1, numpy.array(tmpbins2, dtype=float)) kColor = 4 # kBlue kColorErr = 432 # kCyan new = len(oldres)>0 if new: kColorOld = kColor kColorErrOld = kColorErr kColor = 618 # kMagenta+2 kColorErr = 609 # kMagenta-7 frame1 = ws.var(var).frame(RooFit.Bins(40), RooFit.Title("Data (all, accepted)")) ds.plotOn(frame1) ds.plotOn(frame1, RooFit.Cut("%s==%s::accept" % (cat,cat)), RooFit.MarkerColor(kColor), RooFit.LineColor(kColor)) frame2 = ws.var(var).frame(RooFit.Title("; %s; HLT efficiency" % xtitle)) if new: ws.saveSnapshot("2015alpha", "fit0,fit1,fit2") ws.loadSnapshot("2012D") ws.function(eff).plotOn(frame2, RooFit.VisualizeError(oldres[0]), RooFit.FillColor(kColorErrOld)) ws.function(eff).plotOn(frame2, RooFit.LineColor(kColorOld)) ws.loadSnapshot("2015alpha") ws.function(eff).plotOn(frame2, RooFit.VisualizeError(res), RooFit.FillColor(kColorErr)) ws.function(eff).plotOn(frame2, RooFit.LineColor(kColor)) ds.plotOn(frame2, RooFit.Binning(bins), RooFit.Efficiency(ws.cat(cat))) nchisq = frame2.chiSquare(nfitparams) ndof = bins.numBins()-nfitparams chisq = nchisq * ndof gPad.SetLeftMargin(0.15); frame2.GetYaxis().SetTitleOffset(1.25); frame2.GetYaxis().SetRangeUser(0,ymax) #frame1.Draw() frame2.Draw() CMS_label() latex.SetTextSize(0.044) latex.DrawLatex(0.60, 0.30, "#chi^{2}/ndof = %4.2f/%.0f" % (chisq,ndof)) text = ["** "+trig+" **"] text.append("chi2/ndof %6.2f = %4.2f/%.0f" % (nchisq, chisq, ndof)) print "chi2/ndof %6.2f = %4.2f/%.0f" % (nchisq, chisq, ndof) latex.SetTextSize(0.026) latex.DrawLatex(0.60, 0.26, trig) for i in xrange(3): v = ws.var("fit%i" % i) if v.getVal() > 1: text.append("p_%i %6.2f +/- %3.2f" % (i, v.getVal(), v.getError())) latex.DrawLatex(0.60, 0.26-(i+1)*0.03, "p_{%i} %6.2f +/- %3.2f" % (i, v.getVal(), v.getError())) else: text.append("p_%i %6.3f +/- %4.3f" % (i, v.getVal(), v.getError())) latex.DrawLatex(0.60, 0.26-(i+1)*0.03, "p_{%i} %6.3f +/- %4.3f" % (i, v.getVal(), v.getError())) line.DrawLine(xlow, 1, xup, 1) text.append("") return text
class Binned_MassPdf( MassPdf ) : def __init__( self, Name, Mass, **kwargs ) : self._name = Name self._mass = Mass # get binning self._bins = kwargs.pop( 'Binning', None ) if not self._bins : # create binning from array import array binBounds = kwargs.pop( 'BinBoundaries', [ self._mass.getMin(), self._mass.getMax() ] ) self._binBounds = array( 'd', binBounds ) self._numBins = len(binBounds) - 1 from ROOT import RooBinning self._bins = RooBinning( self._numBins, self._binBounds, self._name + '_binning' ) self._mass.setBinning( self._bins, self._name + '_binning' ) self._numBins = self._bins.numBins() # determine number of events in each bin self._data = kwargs.pop( 'Data', None ) if self._data : assert self._mass._var in self._data.get(0),\ 'Binned_MassPdf.__init__(): %s is not and observable in the provided data set' % self._mass.GetName() self._numEvents = self._data.sumEntries() self._numEventsBins = self._numBins * [ 0. ] for obsSet in self._data : bin = self._bins.binNumber( obsSet.getRealValue( self._mass.GetName() ) ) self._numEventsBins[bin] += self._data.weight() # create bin coefficients self._coefs = [ ] for bin in range( 1, self._numBins ) : self._parseArg( '%s_coef%d' % ( self._name, bin ), kwargs , Title = '%s bin coefficient %d' % ( self._name, bin ) , Value = self._numEventsBins[bin] / self._numEvents if self._data else 1. / self._numBins , MinMax = ( 0., 1. ) , ContainerList = self._coefs ) # create a BinnedPdf from P2VV.RooFitWrappers import BinnedPdf pdf = BinnedPdf( Name = self._name , Observable = self._mass , Binning = self._bins , Coefficients = self._coefs , BinIntegralCoefs = True ) # initialize MassPdf.__init__( self, pdf = pdf ) self._check_extraneous_kw( kwargs )
def __init__ (self, pars): self.pars = pars self.ws = RooWorkspace('wjj2dfitter') self.utils = Wjj2DFitterUtils(self.pars) self.useImportPars = False self.rangeString = None obs = [] for v in self.pars.var: try: vName = self.pars.varNames[v] except AttributeError: vName = v obs.append(vName) var1 = self.ws.factory('%s[%f,%f]' % (vName, self.pars.varRanges[v][1], self.pars.varRanges[v][2]) ) var1.setUnit('GeV') try: var1.SetTitle(self.pars.varTitles[v]) except AttributeError: var1.SetTitle('m_{jj}') var1.setPlotLabel(var1.GetTitle()) if len(self.pars.varRanges[v][3]) > 1: vbinning = RooBinning(len(self.pars.varRanges[v][3]) - 1, array('d', self.pars.varRanges[v][3]), '%sBinning' % vName) var1.setBinning(vbinning) else: var1.setBins(self.pars.varRanges[v][0]) var1.Print() if v in self.pars.exclude: var1.setRange('signalRegion', self.pars.exclude[v][0], self.pars.exclude[v][1]) var1.setRange('lowSideband', var1.getMin(), self.pars.exclude[v][0]) var1.setRange('highSideband', self.pars.exclude[v][1], var1.getMax()) self.rangeString = 'lowSideband,highSideband' self.ws.defineSet('obsSet', ','.join(obs))
def signal(channel, stype): if 'VBF' in channel: stype = 'XZHVBF' else: stype = 'XZH' # HVT model if stype.startswith('X'): signalType = 'HVT' genPoints = [800, 1000, 1200, 1400, 1600, 1800, 2000, 2500, 3000, 3500, 4000, 4500, 5000] massPoints = [x for x in range(800, 5000+1, 100)] interPar = True else: print "Signal type", stype, "not recognized" return n = len(genPoints) category = channel cColor = color[category] if category in color else 1 nElec = channel.count('e') nMuon = channel.count('m') nLept = nElec + nMuon nBtag = channel.count('b') if '0b' in channel: nBtag = 0 X_name = "VH_mass" if not os.path.exists(PLOTDIR+stype+category): os.makedirs(PLOTDIR+stype+category) #*******************************************************# # # # Variables and selections # # # #*******************************************************# X_mass = RooRealVar( "X_mass", "m_{ZH}", XBINMIN, XBINMAX, "GeV") J_mass = RooRealVar( "H_mass", "jet mass", LOWMIN, HIGMAX, "GeV") V_mass = RooRealVar( "V_mass", "V jet mass", -9., 1.e6, "GeV") CSV1 = RooRealVar( "H_csv1", "", -999., 2. ) CSV2 = RooRealVar( "H_csv2", "", -999., 2. ) DeepCSV1= RooRealVar( "H_deepcsv1", "", -999., 2. ) DeepCSV2= RooRealVar( "H_deepcsv2", "", -999., 2. ) H_ntag = RooRealVar( "H_ntag", "", -9., 9. ) H_dbt = RooRealVar( "H_dbt", "", -2., 2. ) H_tau21 = RooRealVar( "H_tau21", "", -9., 2. ) H_eta = RooRealVar( "H_eta", "", -9., 9. ) H_tau21_ddt = RooRealVar( "H_ddt", "", -9., 2. ) MaxBTag = RooRealVar( "MaxBTag", "", -10., 2. ) H_chf = RooRealVar( "H_chf", "", -1., 2. ) MinDPhi = RooRealVar( "MinDPhi", "", -1., 99. ) DPhi = RooRealVar( "DPhi", "", -1., 99. ) DEta = RooRealVar( "DEta", "", -1., 99. ) Mu1_relIso = RooRealVar( "Mu1_relIso", "", -1., 99. ) Mu2_relIso = RooRealVar( "Mu2_relIso", "", -1., 99. ) nTaus = RooRealVar( "nTaus", "", -1., 99. ) Vpt = RooRealVar( "V.Pt()", "", -1., 1.e6 ) V_pt = RooRealVar( "V_pt", "", -1., 1.e6 ) H_pt = RooRealVar( "H_pt", "", -1., 1.e6 ) VH_deltaR=RooRealVar( "VH_deltaR", "", -1., 99. ) isZtoNN = RooRealVar( "isZtoNN", "", 0., 2. ) isZtoEE = RooRealVar( "isZtoEE", "", 0., 2. ) isZtoMM = RooRealVar( "isZtoMM", "", 0., 2. ) isHtobb = RooRealVar( "isHtobb", "", 0., 2. ) isVBF = RooRealVar( "isVBF", "", 0., 2. ) isMaxBTag_loose = RooRealVar( "isMaxBTag_loose", "", 0., 2. ) weight = RooRealVar( "eventWeightLumi", "", -1.e9, 1.e9 ) Xmin = XBINMIN Xmax = XBINMAX # Define the RooArgSet which will include all the variables defined before # there is a maximum of 9 variables in the declaration, so the others need to be added with 'add' variables = RooArgSet(X_mass, J_mass, V_mass, CSV1, CSV2, H_ntag, H_dbt, H_tau21) variables.add(RooArgSet(DEta, DPhi, MaxBTag, MinDPhi, nTaus, Vpt)) variables.add(RooArgSet(DeepCSV1, DeepCSV2,VH_deltaR, H_tau21_ddt)) variables.add(RooArgSet(isZtoNN, isZtoEE, isZtoMM, isHtobb, isMaxBTag_loose, weight)) variables.add(RooArgSet(isVBF, Mu1_relIso, Mu2_relIso, H_chf, H_pt, V_pt,H_eta)) #X_mass.setRange("X_extended_range", X_mass.getMin(), X_mass.getMax()) X_mass.setRange("X_reasonable_range", X_mass.getMin(), X_mass.getMax()) X_mass.setRange("X_integration_range", Xmin, Xmax) X_mass.setBins(int((X_mass.getMax() - X_mass.getMin())/100)) binsXmass = RooBinning(int((X_mass.getMax() - X_mass.getMin())/100), X_mass.getMin(), X_mass.getMax()) X_mass.setBinning(binsXmass, "PLOT") massArg = RooArgSet(X_mass) # Cuts SRcut = selection[category]+selection['SR'] print " Cut:\t", SRcut #*******************************************************# # # # Signal fits # # # #*******************************************************# treeSign = {} setSignal = {} vmean = {} vsigma = {} valpha1 = {} vslope1 = {} smean = {} ssigma = {} salpha1 = {} sslope1 = {} salpha2 = {} sslope2 = {} a1 = {} a2 = {} sbrwig = {} signal = {} signalExt = {} signalYield = {} signalIntegral = {} signalNorm = {} signalXS = {} frSignal = {} frSignal1 = {} frSignal2 = {} frSignal3 = {} # Signal shape uncertainties (common amongst all mass points) xmean_fit = RooRealVar("sig_p1_fit", "Variation of the resonance position with the fit uncertainty", 0.005, -1., 1.) smean_fit = RooRealVar("CMSRunII_sig_p1_fit", "Change of the resonance position with the fit uncertainty", 0., -10, 10) xmean_jes = RooRealVar("sig_p1_scale_jes", "Variation of the resonance position with the jet energy scale", 0.010, -1., 1.) #0.001 smean_jes = RooRealVar("CMSRunII_sig_p1_jes", "Change of the resonance position with the jet energy scale", 0., -10, 10) xmean_e = RooRealVar("sig_p1_scale_e", "Variation of the resonance position with the electron energy scale", 0.001, -1., 1.) smean_e = RooRealVar("CMSRunII_sig_p1_scale_e", "Change of the resonance position with the electron energy scale", 0., -10, 10) xmean_m = RooRealVar("sig_p1_scale_m", "Variation of the resonance position with the muon energy scale", 0.001, -1., 1.) smean_m = RooRealVar("CMSRunII_sig_p1_scale_m", "Change of the resonance position with the muon energy scale", 0., -10, 10) xsigma_fit = RooRealVar("sig_p2_fit", "Variation of the resonance width with the fit uncertainty", 0.02, -1., 1.) ssigma_fit = RooRealVar("CMSRunII_sig_p2_fit", "Change of the resonance width with the fit uncertainty", 0., -10, 10) xsigma_jes = RooRealVar("sig_p2_scale_jes", "Variation of the resonance width with the jet energy scale", 0.010, -1., 1.) #0.001 ssigma_jes = RooRealVar("CMSRunII_sig_p2_jes", "Change of the resonance width with the jet energy scale", 0., -10, 10) xsigma_jer = RooRealVar("sig_p2_scale_jer", "Variation of the resonance width with the jet energy resolution", 0.020, -1., 1.) ssigma_jer = RooRealVar("CMSRunII_sig_p2_jer", "Change of the resonance width with the jet energy resolution", 0., -10, 10) xsigma_e = RooRealVar("sig_p2_scale_e", "Variation of the resonance width with the electron energy scale", 0.001, -1., 1.) ssigma_e = RooRealVar("CMSRunII_sig_p2_scale_e", "Change of the resonance width with the electron energy scale", 0., -10, 10) xsigma_m = RooRealVar("sig_p2_scale_m", "Variation of the resonance width with the muon energy scale", 0.040, -1., 1.) ssigma_m = RooRealVar("CMSRunII_sig_p2_scale_m", "Change of the resonance width with the muon energy scale", 0., -10, 10) xalpha1_fit = RooRealVar("sig_p3_fit", "Variation of the resonance alpha with the fit uncertainty", 0.03, -1., 1.) salpha1_fit = RooRealVar("CMSRunII_sig_p3_fit", "Change of the resonance alpha with the fit uncertainty", 0., -10, 10) xslope1_fit = RooRealVar("sig_p4_fit", "Variation of the resonance slope with the fit uncertainty", 0.10, -1., 1.) sslope1_fit = RooRealVar("CMSRunII_sig_p4_fit", "Change of the resonance slope with the fit uncertainty", 0., -10, 10) xmean_fit.setConstant(True) smean_fit.setConstant(True) xmean_jes.setConstant(True) smean_jes.setConstant(True) xmean_e.setConstant(True) smean_e.setConstant(True) xmean_m.setConstant(True) smean_m.setConstant(True) xsigma_fit.setConstant(True) ssigma_fit.setConstant(True) xsigma_jes.setConstant(True) ssigma_jes.setConstant(True) xsigma_jer.setConstant(True) ssigma_jer.setConstant(True) xsigma_e.setConstant(True) ssigma_e.setConstant(True) xsigma_m.setConstant(True) ssigma_m.setConstant(True) xalpha1_fit.setConstant(True) salpha1_fit.setConstant(True) xslope1_fit.setConstant(True) sslope1_fit.setConstant(True) # the alpha method is now done. for m in massPoints: signalString = "M%d" % m signalMass = "%s_M%d" % (stype, m) signalName = "%s%s_M%d" % (stype, category, m) signalColor = sample[signalMass]['linecolor'] if signalName in sample else 1 # define the signal PDF vmean[m] = RooRealVar(signalName + "_vmean", "Crystal Ball mean", m, m*0.5, m*1.25) smean[m] = RooFormulaVar(signalName + "_mean", "@0*(1+@1*@2)*(1+@3*@4)*(1+@5*@6)*(1+@7*@8)", RooArgList(vmean[m], xmean_e, smean_e, xmean_m, smean_m, xmean_jes, smean_jes, xmean_fit, smean_fit)) vsigma[m] = RooRealVar(signalName + "_vsigma", "Crystal Ball sigma", m*0.035, m*0.01, m*0.4) sigmaList = RooArgList(vsigma[m], xsigma_e, ssigma_e, xsigma_m, ssigma_m, xsigma_jes, ssigma_jes, xsigma_jer, ssigma_jer) sigmaList.add(RooArgList(xsigma_fit, ssigma_fit)) ssigma[m] = RooFormulaVar(signalName + "_sigma", "@0*(1+@1*@2)*(1+@3*@4)*(1+@5*@6)*(1+@7*@8)*(1+@9*@10)", sigmaList) valpha1[m] = RooRealVar(signalName + "_valpha1", "Crystal Ball alpha", 1., 0., 5.) # number of sigmas where the exp is attached to the gaussian core. >0 left, <0 right salpha1[m] = RooFormulaVar(signalName + "_alpha1", "@0*(1+@1*@2)", RooArgList(valpha1[m], xalpha1_fit, salpha1_fit)) vslope1[m] = RooRealVar(signalName + "_vslope1", "Crystal Ball slope", 10., 1., 60.) # slope of the power tail #10 1 60 sslope1[m] = RooFormulaVar(signalName + "_slope1", "@0*(1+@1*@2)", RooArgList(vslope1[m], xslope1_fit, sslope1_fit)) salpha2[m] = RooRealVar(signalName + "_alpha2", "Crystal Ball alpha", 2, 1., 5.) # number of sigmas where the exp is attached to the gaussian core. >0 left, <0 right sslope2[m] = RooRealVar(signalName + "_slope2", "Crystal Ball slope", 10, 1.e-1, 115.) # slope of the power tail #define polynomial #a1[m] = RooRealVar(signalName + "_a1", "par 1 for polynomial", m, 0.5*m, 2*m) a1[m] = RooRealVar(signalName + "_a1", "par 1 for polynomial", 0.001*m, 0.0005*m, 0.01*m) a2[m] = RooRealVar(signalName + "_a2", "par 2 for polynomial", 0.05, -1.,1.) #if channel=='nnbbVBF' or channel=='nn0bVBF': # signal[m] = RooPolynomial(signalName,"m_{%s'} = %d GeV" % (stype[1], m) , X_mass, RooArgList(a1[m],a2[m])) #else: # signal[m] = RooCBShape(signalName, "m_{%s'} = %d GeV" % (stype[1], m), X_mass, smean[m], ssigma[m], salpha1[m], sslope1[m]) # Signal name does not have the channel signal[m] = RooCBShape(signalName, "m_{%s'} = %d GeV" % (stype[1], m), X_mass, smean[m], ssigma[m], salpha1[m], sslope1[m]) # Signal name does not have the channel # extend the PDF with the yield to perform an extended likelihood fit signalYield[m] = RooRealVar(signalName+"_yield", "signalYield", 100, 0., 1.e6) signalNorm[m] = RooRealVar(signalName+"_norm", "signalNorm", 1., 0., 1.e6) signalXS[m] = RooRealVar(signalName+"_xs", "signalXS", 1., 0., 1.e6) signalExt[m] = RooExtendPdf(signalName+"_ext", "extended p.d.f", signal[m], signalYield[m]) vslope1[m].setMax(50.) vslope1[m].setVal(20.) #valpha1[m].setVal(1.0) #valpha1[m].setConstant(True) if 'bb' in channel and 'VBF' not in channel: if 'nn' in channel: valpha1[m].setVal(0.5) elif '0b' in channel and 'VBF' not in channel: if 'nn' in channel: if m==800: valpha1[m].setVal(2.) vsigma[m].setVal(m*0.04) elif 'ee' in channel: valpha1[m].setVal(0.8) if m==800: #valpha1[m].setVal(1.2) valpha1[m].setVal(2.5) vslope1[m].setVal(50.) elif 'mm' in channel: if m==800: valpha1[m].setVal(2.) vsigma[m].setVal(m*0.03) else: vmean[m].setVal(m*0.9) vsigma[m].setVal(m*0.08) elif 'bb' in channel and 'VBF' in channel: if 'nn' in channel: if m!=1800: vmean[m].setVal(m*0.8) vsigma[m].setVal(m*0.08) valpha1[m].setMin(1.) elif 'ee' in channel: valpha1[m].setVal(0.7) elif 'mm' in channel: if m==800: vslope1[m].setVal(50.) valpha1[m].setVal(0.7) elif '0b' in channel and 'VBF' in channel: if 'nn' in channel: valpha1[m].setVal(3.) vmean[m].setVal(m*0.8) vsigma[m].setVal(m*0.08) valpha1[m].setMin(1.) elif 'ee' in channel: if m<2500: valpha1[m].setVal(2.) if m==800: vsigma[m].setVal(m*0.05) elif m==1000: vsigma[m].setVal(m*0.03) elif m>1000 and m<1800: vsigma[m].setVal(m*0.04) elif 'mm' in channel: if m<2000: valpha1[m].setVal(2.) if m==1000 or m==1800: vsigma[m].setVal(m*0.03) elif m==1200 or m==1600: vsigma[m].setVal(m*0.04) #if m < 1000: vsigma[m].setVal(m*0.06) # If it's not the proper channel, make it a gaussian #if nLept==0 and 'VBF' in channel: # valpha1[m].setVal(5) # valpha1[m].setConstant(True) # vslope1[m].setConstant(True) # salpha2[m].setConstant(True) # sslope2[m].setConstant(True) # ---------- if there is no simulated signal, skip this mass point ---------- if m in genPoints: if VERBOSE: print " - Mass point", m # define the dataset for the signal applying the SR cuts treeSign[m] = TChain("tree") for j, ss in enumerate(sample[signalMass]['files']): treeSign[m].Add(NTUPLEDIR + ss + ".root") if treeSign[m].GetEntries() <= 0.: if VERBOSE: print " - 0 events available for mass", m, "skipping mass point..." signalNorm[m].setVal(-1) vmean[m].setConstant(True) vsigma[m].setConstant(True) salpha1[m].setConstant(True) sslope1[m].setConstant(True) salpha2[m].setConstant(True) sslope2[m].setConstant(True) signalNorm[m].setConstant(True) signalXS[m].setConstant(True) continue setSignal[m] = RooDataSet("setSignal_"+signalName, "setSignal", variables, RooFit.Cut(SRcut), RooFit.WeightVar(weight), RooFit.Import(treeSign[m])) if VERBOSE: print " - Dataset with", setSignal[m].sumEntries(), "events loaded" # FIT signalYield[m].setVal(setSignal[m].sumEntries()) if treeSign[m].GetEntries(SRcut) > 5: if VERBOSE: print " - Running fit" frSignal[m] = signalExt[m].fitTo(setSignal[m], RooFit.Save(1), RooFit.Extended(True), RooFit.SumW2Error(True), RooFit.PrintLevel(-1)) if VERBOSE: print "********** Fit result [", m, "] **", category, "*"*40, "\n", frSignal[m].Print(), "\n", "*"*80 if VERBOSE: frSignal[m].correlationMatrix().Print() drawPlot(signalMass, stype+channel, X_mass, signal[m], setSignal[m], frSignal[m]) else: print " WARNING: signal", stype, "and mass point", m, "in channel", channel, "has 0 entries or does not exist" # Remove HVT cross section (which is the same for Zlep and Zinv) if stype == "XZHVBF": sample_name = 'Zprime_VBF_Zh_Zlephinc_narrow_M-%d' % m else: sample_name = 'ZprimeToZHToZlepHinc_narrow_M%d' % m xs = xsection[sample_name]['xsec'] signalXS[m].setVal(xs * 1000.) signalIntegral[m] = signalExt[m].createIntegral(massArg, RooFit.NormSet(massArg), RooFit.Range("X_integration_range")) boundaryFactor = signalIntegral[m].getVal() if VERBOSE: print " - Fit normalization vs integral:", signalYield[m].getVal(), "/", boundaryFactor, "events" if channel=='nnbb' and m==5000: signalNorm[m].setVal(2.5) elif channel=='nn0b' and m==5000: signalNorm[m].setVal(6.7) else: signalNorm[m].setVal( boundaryFactor * signalYield[m].getVal() / signalXS[m].getVal()) # here normalize to sigma(X) x Br(X->VH) = 1 [fb] a1[m].setConstant(True) a2[m].setConstant(True) vmean[m].setConstant(True) vsigma[m].setConstant(True) valpha1[m].setConstant(True) vslope1[m].setConstant(True) salpha2[m].setConstant(True) sslope2[m].setConstant(True) signalNorm[m].setConstant(True) signalXS[m].setConstant(True) #*******************************************************# # # # Signal interpolation # # # #*******************************************************# # ====== CONTROL PLOT ====== c_signal = TCanvas("c_signal", "c_signal", 800, 600) c_signal.cd() frame_signal = X_mass.frame() for m in genPoints[:-2]: if m in signalExt.keys(): signal[m].plotOn(frame_signal, RooFit.LineColor(sample["%s_M%d" % (stype, m)]['linecolor']), RooFit.Normalization(signalNorm[m].getVal(), RooAbsReal.NumEvent), RooFit.Range("X_reasonable_range")) frame_signal.GetXaxis().SetRangeUser(0, 6500) frame_signal.Draw() drawCMS(-1, YEAR, "Simulation") drawAnalysis(channel) drawRegion(channel) c_signal.SaveAs(PLOTDIR+"/"+stype+category+"/"+stype+"_Signal.pdf") c_signal.SaveAs(PLOTDIR+"/"+stype+category+"/"+stype+"_Signal.png") #if VERBOSE: raw_input("Press Enter to continue...") # ====== CONTROL PLOT ====== # Normalization gnorm = TGraphErrors() gnorm.SetTitle(";m_{X} (GeV);integral (GeV)") gnorm.SetMarkerStyle(20) gnorm.SetMarkerColor(1) gnorm.SetMaximum(0) inorm = TGraphErrors() inorm.SetMarkerStyle(24) fnorm = TF1("fnorm", "pol9", 800, 5000) #"pol5" if not channel=="XZHnnbb" else "pol6" #pol5*TMath::Floor(x-1800) + ([5]*x + [6]*x*x)*(1-TMath::Floor(x-1800)) fnorm.SetLineColor(920) fnorm.SetLineStyle(7) fnorm.SetFillColor(2) fnorm.SetLineColor(cColor) # Mean gmean = TGraphErrors() gmean.SetTitle(";m_{X} (GeV);gaussian mean (GeV)") gmean.SetMarkerStyle(20) gmean.SetMarkerColor(cColor) gmean.SetLineColor(cColor) imean = TGraphErrors() imean.SetMarkerStyle(24) fmean = TF1("fmean", "pol1", 0, 5000) fmean.SetLineColor(2) fmean.SetFillColor(2) # Width gsigma = TGraphErrors() gsigma.SetTitle(";m_{X} (GeV);gaussian width (GeV)") gsigma.SetMarkerStyle(20) gsigma.SetMarkerColor(cColor) gsigma.SetLineColor(cColor) isigma = TGraphErrors() isigma.SetMarkerStyle(24) fsigma = TF1("fsigma", "pol1", 0, 5000) fsigma.SetLineColor(2) fsigma.SetFillColor(2) # Alpha1 galpha1 = TGraphErrors() galpha1.SetTitle(";m_{X} (GeV);crystal ball lower alpha") galpha1.SetMarkerStyle(20) galpha1.SetMarkerColor(cColor) galpha1.SetLineColor(cColor) ialpha1 = TGraphErrors() ialpha1.SetMarkerStyle(24) falpha1 = TF1("falpha", "pol0", 0, 5000) falpha1.SetLineColor(2) falpha1.SetFillColor(2) # Slope1 gslope1 = TGraphErrors() gslope1.SetTitle(";m_{X} (GeV);exponential lower slope (1/Gev)") gslope1.SetMarkerStyle(20) gslope1.SetMarkerColor(cColor) gslope1.SetLineColor(cColor) islope1 = TGraphErrors() islope1.SetMarkerStyle(24) fslope1 = TF1("fslope", "pol0", 0, 5000) fslope1.SetLineColor(2) fslope1.SetFillColor(2) # Alpha2 galpha2 = TGraphErrors() galpha2.SetTitle(";m_{X} (GeV);crystal ball upper alpha") galpha2.SetMarkerStyle(20) galpha2.SetMarkerColor(cColor) galpha2.SetLineColor(cColor) ialpha2 = TGraphErrors() ialpha2.SetMarkerStyle(24) falpha2 = TF1("falpha", "pol0", 0, 5000) falpha2.SetLineColor(2) falpha2.SetFillColor(2) # Slope2 gslope2 = TGraphErrors() gslope2.SetTitle(";m_{X} (GeV);exponential upper slope (1/Gev)") gslope2.SetMarkerStyle(20) gslope2.SetMarkerColor(cColor) gslope2.SetLineColor(cColor) islope2 = TGraphErrors() islope2.SetMarkerStyle(24) fslope2 = TF1("fslope", "pol0", 0, 5000) fslope2.SetLineColor(2) fslope2.SetFillColor(2) n = 0 for i, m in enumerate(genPoints): if not m in signalNorm.keys(): continue if signalNorm[m].getVal() < 1.e-6: continue signalString = "M%d" % m signalName = "%s_M%d" % (stype, m) if gnorm.GetMaximum() < signalNorm[m].getVal(): gnorm.SetMaximum(signalNorm[m].getVal()) gnorm.SetPoint(n, m, signalNorm[m].getVal()) gmean.SetPoint(n, m, vmean[m].getVal()) gmean.SetPointError(n, 0, min(vmean[m].getError(), vmean[m].getVal()*0.02)) gsigma.SetPoint(n, m, vsigma[m].getVal()) gsigma.SetPointError(n, 0, min(vsigma[m].getError(), vsigma[m].getVal()*0.05)) galpha1.SetPoint(n, m, valpha1[m].getVal()) galpha1.SetPointError(n, 0, min(valpha1[m].getError(), valpha1[m].getVal()*0.10)) gslope1.SetPoint(n, m, vslope1[m].getVal()) gslope1.SetPointError(n, 0, min(vslope1[m].getError(), vslope1[m].getVal()*0.10)) galpha2.SetPoint(n, m, salpha2[m].getVal()) galpha2.SetPointError(n, 0, min(salpha2[m].getError(), salpha2[m].getVal()*0.10)) gslope2.SetPoint(n, m, sslope2[m].getVal()) gslope2.SetPointError(n, 0, min(sslope2[m].getError(), sslope2[m].getVal()*0.10)) n = n + 1 print "fit on gmean:" gmean.Fit(fmean, "Q0", "SAME") print "fit on gsigma:" gsigma.Fit(fsigma, "Q0", "SAME") print "fit on galpha:" galpha1.Fit(falpha1, "Q0", "SAME") print "fit on gslope:" gslope1.Fit(fslope1, "Q0", "SAME") galpha2.Fit(falpha2, "Q0", "SAME") gslope2.Fit(fslope2, "Q0", "SAME") #for m in [5000, 5500]: gnorm.SetPoint(gnorm.GetN(), m, gnorm.Eval(m, 0, "S")) gnorm.Fit(fnorm, "Q", "SAME", 700, 5000) for m in massPoints: signalName = "%s_M%d" % (stype, m) if vsigma[m].getVal() < 10.: vsigma[m].setVal(10.) # Interpolation method syield = gnorm.Eval(m) spline = gnorm.Eval(m, 0, "S") sfunct = fnorm.Eval(m) #delta = min(abs(1.-spline/sfunct), abs(1.-spline/syield)) delta = abs(1.-spline/sfunct) if sfunct > 0 else 0 syield = spline if interPar: jmean = gmean.Eval(m) jsigma = gsigma.Eval(m) jalpha1 = galpha1.Eval(m) jslope1 = gslope1.Eval(m) else: jmean = fmean.GetParameter(0) + fmean.GetParameter(1)*m + fmean.GetParameter(2)*m*m jsigma = fsigma.GetParameter(0) + fsigma.GetParameter(1)*m + fsigma.GetParameter(2)*m*m jalpha1 = falpha1.GetParameter(0) + falpha1.GetParameter(1)*m + falpha1.GetParameter(2)*m*m jslope1 = fslope1.GetParameter(0) + fslope1.GetParameter(1)*m + fslope1.GetParameter(2)*m*m inorm.SetPoint(inorm.GetN(), m, syield) signalNorm[m].setVal(syield) imean.SetPoint(imean.GetN(), m, jmean) if jmean > 0: vmean[m].setVal(jmean) isigma.SetPoint(isigma.GetN(), m, jsigma) if jsigma > 0: vsigma[m].setVal(jsigma) ialpha1.SetPoint(ialpha1.GetN(), m, jalpha1) if not jalpha1==0: valpha1[m].setVal(jalpha1) islope1.SetPoint(islope1.GetN(), m, jslope1) if jslope1 > 0: vslope1[m].setVal(jslope1) c1 = TCanvas("c1", "Crystal Ball", 1200, 800) c1.Divide(2, 2) c1.cd(1) gmean.SetMinimum(0.) gmean.Draw("APL") imean.Draw("P, SAME") drawRegion(channel) c1.cd(2) gsigma.SetMinimum(0.) gsigma.Draw("APL") isigma.Draw("P, SAME") drawRegion(channel) c1.cd(3) galpha1.Draw("APL") ialpha1.Draw("P, SAME") drawRegion(channel) galpha1.GetYaxis().SetRangeUser(0., 5.) c1.cd(4) gslope1.Draw("APL") islope1.Draw("P, SAME") drawRegion(channel) gslope1.GetYaxis().SetRangeUser(0., 125.) if False: c1.cd(5) galpha2.Draw("APL") ialpha2.Draw("P, SAME") drawRegion(channel) c1.cd(6) gslope2.Draw("APL") islope2.Draw("P, SAME") drawRegion(channel) gslope2.GetYaxis().SetRangeUser(0., 10.) c1.Print(PLOTDIR+stype+category+"/"+stype+"_SignalShape.pdf") c1.Print(PLOTDIR+stype+category+"/"+stype+"_SignalShape.png") c2 = TCanvas("c2", "Signal Efficiency", 800, 600) c2.cd(1) gnorm.SetMarkerColor(cColor) gnorm.SetMarkerStyle(20) gnorm.SetLineColor(cColor) gnorm.SetLineWidth(2) gnorm.Draw("APL") inorm.Draw("P, SAME") gnorm.GetXaxis().SetRangeUser(genPoints[0]-100, genPoints[-1]+100) gnorm.GetYaxis().SetRangeUser(0., gnorm.GetMaximum()*1.25) drawCMS(-1,YEAR , "Simulation") drawAnalysis(channel) drawRegion(channel) c2.Print(PLOTDIR+stype+category+"/"+stype+"_SignalNorm.pdf") c2.Print(PLOTDIR+stype+category+"/"+stype+"_SignalNorm.png") #*******************************************************# # # # Generate workspace # # # #*******************************************************# # create workspace w = RooWorkspace("ZH_RunII", "workspace") for m in massPoints: getattr(w, "import")(signal[m], RooFit.Rename(signal[m].GetName())) getattr(w, "import")(signalNorm[m], RooFit.Rename(signalNorm[m].GetName())) getattr(w, "import")(signalXS[m], RooFit.Rename(signalXS[m].GetName())) w.writeToFile("%s%s.root" % (WORKDIR, stype+channel), True) print "Workspace", "%s%s.root" % (WORKDIR, stype+channel), "saved successfully" sys.exit()
dGamma = RooRealVar('dGamma', 'dGamma', -0.106, -3., 3.) dM = RooRealVar('dM', 'dM', 17.768, 0.1, 20.) C = RooRealVar('C', 'C', 1., 0., 2.) one = const(1.) zero = const(0.) tau = Inverse('tau', 'tau', gamma) # tauk = Inverse('tauk', 'tauk', kgamma) ## acceptance spline_knots = [ 0.5, 1.0, 1.5, 2.0, 3.0, 12.0 ] spline_coeffs = [ 5.03902e-01, 7.32741e-01, 9.98736e-01, 1.16514e+00, 1.25167e+00, 1.28624e+00 ] assert(len(spline_knots) == len(spline_coeffs)) # knot binning knotbinning = RooBinning(time.getMin(), time.getMax(), '{}_knotbinning'.format(mode)) for v in spline_knots: knotbinning.addBoundary(v) knotbinning.removeBoundary(time.getMin()) knotbinning.removeBoundary(time.getMax()) oldbinning, lo, hi = time.getBinning(), time.getMin(), time.getMax() time.setBinning(knotbinning, '{}_knotbinning'.format(mode)) time.setBinning(oldbinning) time.setRange(lo, hi) del knotbinning, oldbinning, lo, hi # knot coefficients coefflist = RooArgList() for i, v in enumerate(spline_coeffs): coefflist.add(const(v)) i = len(spline_coeffs)
def signal(category): interPar = True n = len(genPoints) cColor = color[category] if category in color else 4 nBtag = category.count('b') isAH = False #relict from using Alberto's more complex script if not os.path.exists(PLOTDIR + "MC_signal_" + YEAR): os.makedirs(PLOTDIR + "MC_signal_" + YEAR) #*******************************************************# # # # Variables and selections # # # #*******************************************************# X_mass = RooRealVar("jj_mass_widejet", "m_{jj}", X_min, X_max, "GeV") j1_pt = RooRealVar("jpt_1", "jet1 pt", 0., 13000., "GeV") jj_deltaEta = RooRealVar("jj_deltaEta_widejet", "", 0., 5.) jbtag_WP_1 = RooRealVar("jbtag_WP_1", "", -1., 4.) jbtag_WP_2 = RooRealVar("jbtag_WP_2", "", -1., 4.) fatjetmass_1 = RooRealVar("fatjetmass_1", "", -1., 2500.) fatjetmass_2 = RooRealVar("fatjetmass_2", "", -1., 2500.) jid_1 = RooRealVar("jid_1", "j1 ID", -1., 8.) jid_2 = RooRealVar("jid_2", "j2 ID", -1., 8.) jnmuons_1 = RooRealVar("jnmuons_1", "j1 n_{#mu}", -1., 8.) jnmuons_2 = RooRealVar("jnmuons_2", "j2 n_{#mu}", -1., 8.) jnmuons_loose_1 = RooRealVar("jnmuons_loose_1", "jnmuons_loose_1", -1., 8.) jnmuons_loose_2 = RooRealVar("jnmuons_loose_2", "jnmuons_loose_2", -1., 8.) nmuons = RooRealVar("nmuons", "n_{#mu}", -1., 10.) nelectrons = RooRealVar("nelectrons", "n_{e}", -1., 10.) HLT_AK8PFJet500 = RooRealVar("HLT_AK8PFJet500", "", -1., 1.) HLT_PFJet500 = RooRealVar("HLT_PFJet500", "", -1., 1.) HLT_CaloJet500_NoJetID = RooRealVar("HLT_CaloJet500_NoJetID", "", -1., 1.) HLT_PFHT900 = RooRealVar("HLT_PFHT900", "", -1., 1.) HLT_AK8PFJet550 = RooRealVar("HLT_AK8PFJet550", "", -1., 1.) HLT_PFJet550 = RooRealVar("HLT_PFJet550", "", -1., 1.) HLT_CaloJet550_NoJetID = RooRealVar("HLT_CaloJet550_NoJetID", "", -1., 1.) HLT_PFHT1050 = RooRealVar("HLT_PFHT1050", "", -1., 1.) #HLT_DoublePFJets100_CaloBTagDeepCSV_p71 =RooRealVar("HLT_DoublePFJets100_CaloBTagDeepCSV_p71" , "", -1., 1. ) #HLT_DoublePFJets116MaxDeta1p6_DoubleCaloBTagDeepCSV_p71 =RooRealVar("HLT_DoublePFJets116MaxDeta1p6_DoubleCaloBTagDeepCSV_p71", "", -1., 1. ) #HLT_DoublePFJets128MaxDeta1p6_DoubleCaloBTagDeepCSV_p71 =RooRealVar("HLT_DoublePFJets128MaxDeta1p6_DoubleCaloBTagDeepCSV_p71", "", -1., 1. ) #HLT_DoublePFJets200_CaloBTagDeepCSV_p71 =RooRealVar("HLT_DoublePFJets200_CaloBTagDeepCSV_p71" , "", -1., 1. ) #HLT_DoublePFJets350_CaloBTagDeepCSV_p71 =RooRealVar("HLT_DoublePFJets350_CaloBTagDeepCSV_p71" , "", -1., 1. ) #HLT_DoublePFJets40_CaloBTagDeepCSV_p71 =RooRealVar("HLT_DoublePFJets40_CaloBTagDeepCSV_p71" , "", -1., 1. ) weight = RooRealVar("eventWeightLumi", "", -1.e9, 1.e9) # Define the RooArgSet which will include all the variables defined before # there is a maximum of 9 variables in the declaration, so the others need to be added with 'add' variables = RooArgSet(X_mass) variables.add( RooArgSet(j1_pt, jj_deltaEta, jbtag_WP_1, jbtag_WP_2, fatjetmass_1, fatjetmass_2, jnmuons_1, jnmuons_2, weight)) variables.add( RooArgSet(nmuons, nelectrons, jid_1, jid_2, jnmuons_loose_1, jnmuons_loose_2)) variables.add( RooArgSet(HLT_AK8PFJet500, HLT_PFJet500, HLT_CaloJet500_NoJetID, HLT_PFHT900, HLT_AK8PFJet550, HLT_PFJet550, HLT_CaloJet550_NoJetID, HLT_PFHT1050)) #variables.add(RooArgSet(HLT_DoublePFJets100_CaloBTagDeepCSV_p71, HLT_DoublePFJets116MaxDeta1p6_DoubleCaloBTagDeepCSV_p71, HLT_DoublePFJets128MaxDeta1p6_DoubleCaloBTagDeepCSV_p71, HLT_DoublePFJets200_CaloBTagDeepCSV_p71, HLT_DoublePFJets350_CaloBTagDeepCSV_p71, HLT_DoublePFJets40_CaloBTagDeepCSV_p71)) X_mass.setRange("X_reasonable_range", X_mass.getMin(), X_mass.getMax()) X_mass.setRange("X_integration_range", X_mass.getMin(), X_mass.getMax()) if VARBINS: binsXmass = RooBinning(len(abins) - 1, abins) X_mass.setBinning(binsXmass) plot_binning = RooBinning( int((X_mass.getMax() - X_mass.getMin()) / 100.), X_mass.getMin(), X_mass.getMax()) else: X_mass.setBins(int((X_mass.getMax() - X_mass.getMin()) / 10)) binsXmass = RooBinning(int((X_mass.getMax() - X_mass.getMin()) / 100.), X_mass.getMin(), X_mass.getMax()) plot_binning = binsXmass X_mass.setBinning(plot_binning, "PLOT") #X_mass.setBins(int((X_mass.getMax() - X_mass.getMin())/10)) #binsXmass = RooBinning(int((X_mass.getMax() - X_mass.getMin())/100), X_mass.getMin(), X_mass.getMax()) #X_mass.setBinning(binsXmass, "PLOT") massArg = RooArgSet(X_mass) # Cuts if BTAGGING == 'semimedium': SRcut = aliasSM[category] #SRcut = aliasSM[category+"_vetoAK8"] else: SRcut = alias[category].format(WP=working_points[BTAGGING]) #SRcut = alias[category+"_vetoAK8"].format(WP=working_points[BTAGGING]) if ADDSELECTION: SRcut += SELECTIONS[options.selection] print " Cut:\t", SRcut #*******************************************************# # # # Signal fits # # # #*******************************************************# treeSign = {} setSignal = {} vmean = {} vsigma = {} valpha1 = {} vslope1 = {} valpha2 = {} vslope2 = {} smean = {} ssigma = {} salpha1 = {} sslope1 = {} salpha2 = {} sslope2 = {} sbrwig = {} signal = {} signalExt = {} signalYield = {} signalIntegral = {} signalNorm = {} signalXS = {} frSignal = {} frSignal1 = {} frSignal2 = {} frSignal3 = {} # Signal shape uncertainties (common amongst all mass points) xmean_jes = RooRealVar( "CMS" + YEAR + "_sig_" + category + "_p1_scale_jes", "Variation of the resonance position with the jet energy scale", 0.02, -1., 1.) #0.001 smean_jes = RooRealVar( "CMS" + YEAR + "_sig_" + category + "_p1_jes", "Change of the resonance position with the jet energy scale", 0., -10, 10) xsigma_jer = RooRealVar( "CMS" + YEAR + "_sig_" + category + "_p2_scale_jer", "Variation of the resonance width with the jet energy resolution", 0.10, -1., 1.) ssigma_jer = RooRealVar( "CMS" + YEAR + "_sig_" + category + "_p2_jer", "Change of the resonance width with the jet energy resolution", 0., -10, 10) xmean_jes.setConstant(True) smean_jes.setConstant(True) xsigma_jer.setConstant(True) ssigma_jer.setConstant(True) for m in massPoints: signalMass = "%s_M%d" % (stype, m) signalName = "ZpBB_{}_{}_M{}".format(YEAR, category, m) sampleName = "ZpBB_M{}".format(m) signalColor = sample[sampleName][ 'linecolor'] if signalName in sample else 1 # define the signal PDF vmean[m] = RooRealVar(signalName + "_vmean", "Crystal Ball mean", m, m * 0.96, m * 1.05) smean[m] = RooFormulaVar(signalName + "_mean", "@0*(1+@1*@2)", RooArgList(vmean[m], xmean_jes, smean_jes)) vsigma[m] = RooRealVar(signalName + "_vsigma", "Crystal Ball sigma", m * 0.0233, m * 0.019, m * 0.025) ssigma[m] = RooFormulaVar( signalName + "_sigma", "@0*(1+@1*@2)", RooArgList(vsigma[m], xsigma_jer, ssigma_jer)) valpha1[m] = RooRealVar( signalName + "_valpha1", "Crystal Ball alpha 1", 0.2, 0.05, 0.28 ) # number of sigmas where the exp is attached to the gaussian core. >0 left, <0 right salpha1[m] = RooFormulaVar(signalName + "_alpha1", "@0", RooArgList(valpha1[m])) #vslope1[m] = RooRealVar(signalName + "_vslope1", "Crystal Ball slope 1", 10., 0.1, 20.) # slope of the power tail vslope1[m] = RooRealVar(signalName + "_vslope1", "Crystal Ball slope 1", 13., 10., 20.) # slope of the power tail sslope1[m] = RooFormulaVar(signalName + "_slope1", "@0", RooArgList(vslope1[m])) valpha2[m] = RooRealVar(signalName + "_valpha2", "Crystal Ball alpha 2", 1.) valpha2[m].setConstant(True) salpha2[m] = RooFormulaVar(signalName + "_alpha2", "@0", RooArgList(valpha2[m])) #vslope2[m] = RooRealVar(signalName + "_vslope2", "Crystal Ball slope 2", 6., 2.5, 15.) # slope of the higher power tail ## FIXME test FIXME vslope2_estimation = -5.88111436852 + m * 0.00728809389442 + m * m * ( -1.65059568762e-06) + m * m * m * (1.25128996309e-10) vslope2[m] = RooRealVar(signalName + "_vslope2", "Crystal Ball slope 2", vslope2_estimation, vslope2_estimation * 0.9, vslope2_estimation * 1.1) # slope of the higher power tail ## FIXME end FIXME sslope2[m] = RooFormulaVar( signalName + "_slope2", "@0", RooArgList(vslope2[m])) # slope of the higher power tail signal[m] = RooDoubleCrystalBall(signalName, "m_{%s'} = %d GeV" % ('X', m), X_mass, smean[m], ssigma[m], salpha1[m], sslope1[m], salpha2[m], sslope2[m]) # extend the PDF with the yield to perform an extended likelihood fit signalYield[m] = RooRealVar(signalName + "_yield", "signalYield", 50, 0., 1.e15) signalNorm[m] = RooRealVar(signalName + "_norm", "signalNorm", 1., 0., 1.e15) signalXS[m] = RooRealVar(signalName + "_xs", "signalXS", 1., 0., 1.e15) signalExt[m] = RooExtendPdf(signalName + "_ext", "extended p.d.f", signal[m], signalYield[m]) # ---------- if there is no simulated signal, skip this mass point ---------- if m in genPoints: if VERBOSE: print " - Mass point", m # define the dataset for the signal applying the SR cuts treeSign[m] = TChain("tree") if YEAR == 'run2': pd = sample[sampleName]['files'] if len(pd) > 3: print "multiple files given than years for a single masspoint:", pd sys.exit() for ss in pd: if not '2016' in ss and not '2017' in ss and not '2018' in ss: print "unknown year given in:", ss sys.exit() else: pd = [x for x in sample[sampleName]['files'] if YEAR in x] if len(pd) > 1: print "multiple files given for a single masspoint/year:", pd sys.exit() for ss in pd: if options.unskimmed: j = 0 while True: if os.path.exists(NTUPLEDIR + ss + "/" + ss + "_flatTuple_{}.root".format(j)): treeSign[m].Add(NTUPLEDIR + ss + "/" + ss + "_flatTuple_{}.root".format(j)) j += 1 else: print "found {} files for sample:".format(j), ss break else: if os.path.exists(NTUPLEDIR + ss + ".root"): treeSign[m].Add(NTUPLEDIR + ss + ".root") else: print "found no file for sample:", ss if treeSign[m].GetEntries() <= 0.: if VERBOSE: print " - 0 events available for mass", m, "skipping mass point..." signalNorm[m].setVal(-1) vmean[m].setConstant(True) vsigma[m].setConstant(True) salpha1[m].setConstant(True) sslope1[m].setConstant(True) salpha2[m].setConstant(True) sslope2[m].setConstant(True) signalNorm[m].setConstant(True) signalXS[m].setConstant(True) continue #setSignal[m] = RooDataSet("setSignal_"+signalName, "setSignal", variables, RooFit.Cut(SRcut), RooFit.WeightVar("eventWeightLumi*BTagAK4Weight_deepJet"), RooFit.Import(treeSign[m])) setSignal[m] = RooDataSet("setSignal_" + signalName, "setSignal", variables, RooFit.Cut(SRcut), RooFit.WeightVar(weight), RooFit.Import(treeSign[m])) if VERBOSE: print " - Dataset with", setSignal[m].sumEntries( ), "events loaded" # FIT entries = setSignal[m].sumEntries() if entries < 0. or entries != entries: entries = 0 signalYield[m].setVal(entries) # Instead of eventWeightLumi #signalYield[m].setVal(entries * LUMI / (300000 if YEAR=='run2' else 100000) ) if treeSign[m].GetEntries(SRcut) > 5: if VERBOSE: print " - Running fit" frSignal[m] = signalExt[m].fitTo(setSignal[m], RooFit.Save(1), RooFit.Extended(True), RooFit.SumW2Error(True), RooFit.PrintLevel(-1)) if VERBOSE: print "********** Fit result [", m, "] **", category, "*" * 40, "\n", frSignal[ m].Print(), "\n", "*" * 80 if VERBOSE: frSignal[m].correlationMatrix().Print() drawPlot(signalMass + "_" + category, stype + category, X_mass, signal[m], setSignal[m], frSignal[m]) else: print " WARNING: signal", stype, "and mass point", m, "in category", category, "has 0 entries or does not exist" # Remove HVT cross sections #xs = getCrossSection(stype, channel, m) xs = 1. signalXS[m].setVal(xs * 1000.) signalIntegral[m] = signalExt[m].createIntegral( massArg, RooFit.NormSet(massArg), RooFit.Range("X_integration_range")) boundaryFactor = signalIntegral[m].getVal() if boundaryFactor < 0. or boundaryFactor != boundaryFactor: boundaryFactor = 0 if VERBOSE: print " - Fit normalization vs integral:", signalYield[ m].getVal(), "/", boundaryFactor, "events" signalNorm[m].setVal(boundaryFactor * signalYield[m].getVal() / signalXS[m].getVal() ) # here normalize to sigma(X) x Br = 1 [fb] vmean[m].setConstant(True) vsigma[m].setConstant(True) valpha1[m].setConstant(True) vslope1[m].setConstant(True) valpha2[m].setConstant(True) vslope2[m].setConstant(True) signalNorm[m].setConstant(True) signalXS[m].setConstant(True) #*******************************************************# # # # Signal interpolation # # # #*******************************************************# ### FIXME FIXME just for a test FIXME FIXME #print #print #print "slope2 fit results:" #print #y_vals = [] #for m in genPoints: # y_vals.append(vslope2[m].getVal()) #print "m =", genPoints #print "y =", y_vals #sys.exit() ### FIXME FIXME test end FIXME FIXME # ====== CONTROL PLOT ====== color_scheme = [ 636, 635, 634, 633, 632, 633, 636, 635, 634, 633, 632, 633, 636, 635, 634, 633, 632, 633, 636, 635, 634, 633, 632, 633, 636, 635, 634, 633, 632, 633, 636, 635, 634, 633, 632, 633, 636, 635, 634, 633, 632, 633 ] c_signal = TCanvas("c_signal", "c_signal", 800, 600) c_signal.cd() frame_signal = X_mass.frame() for j, m in enumerate(genPoints): if m in signalExt.keys(): #print "color:",(j%9)+1 #print "signalNorm[m].getVal() =", signalNorm[m].getVal() #print "RooAbsReal.NumEvent =", RooAbsReal.NumEvent signal[m].plotOn( frame_signal, RooFit.LineColor(color_scheme[j]), RooFit.Normalization(signalNorm[m].getVal(), RooAbsReal.NumEvent), RooFit.Range("X_reasonable_range")) frame_signal.GetXaxis().SetRangeUser(0, 10000) frame_signal.Draw() drawCMS(-1, "Simulation Preliminary", year=YEAR) #drawCMS(-1, "Work in Progress", year=YEAR, suppressCMS=True) #drawCMS(-1, "", year=YEAR, suppressCMS=True) drawAnalysis(category) drawRegion(category) c_signal.SaveAs(PLOTDIR + "MC_signal_" + YEAR + "/" + stype + "_" + category + "_Signal.pdf") c_signal.SaveAs(PLOTDIR + "MC_signal_" + YEAR + "/" + stype + "_" + category + "_Signal.png") #if VERBOSE: raw_input("Press Enter to continue...") # ====== CONTROL PLOT ====== # Normalization gnorm = TGraphErrors() gnorm.SetTitle(";m_{X} (GeV);integral (GeV)") gnorm.SetMarkerStyle(20) gnorm.SetMarkerColor(1) gnorm.SetMaximum(0) inorm = TGraphErrors() inorm.SetMarkerStyle(24) fnorm = TF1("fnorm", "pol9", 700, 3000) fnorm.SetLineColor(920) fnorm.SetLineStyle(7) fnorm.SetFillColor(2) fnorm.SetLineColor(cColor) # Mean gmean = TGraphErrors() gmean.SetTitle(";m_{X} (GeV);gaussian mean (GeV)") gmean.SetMarkerStyle(20) gmean.SetMarkerColor(cColor) gmean.SetLineColor(cColor) imean = TGraphErrors() imean.SetMarkerStyle(24) fmean = TF1("fmean", "pol1", 0, 10000) fmean.SetLineColor(2) fmean.SetFillColor(2) # Width gsigma = TGraphErrors() gsigma.SetTitle(";m_{X} (GeV);gaussian width (GeV)") gsigma.SetMarkerStyle(20) gsigma.SetMarkerColor(cColor) gsigma.SetLineColor(cColor) isigma = TGraphErrors() isigma.SetMarkerStyle(24) fsigma = TF1("fsigma", "pol1", 0, 10000) fsigma.SetLineColor(2) fsigma.SetFillColor(2) # Alpha1 galpha1 = TGraphErrors() galpha1.SetTitle(";m_{X} (GeV);crystal ball lower alpha") galpha1.SetMarkerStyle(20) galpha1.SetMarkerColor(cColor) galpha1.SetLineColor(cColor) ialpha1 = TGraphErrors() ialpha1.SetMarkerStyle(24) falpha1 = TF1("falpha", "pol1", 0, 10000) #pol0 falpha1.SetLineColor(2) falpha1.SetFillColor(2) # Slope1 gslope1 = TGraphErrors() gslope1.SetTitle(";m_{X} (GeV);exponential lower slope (1/Gev)") gslope1.SetMarkerStyle(20) gslope1.SetMarkerColor(cColor) gslope1.SetLineColor(cColor) islope1 = TGraphErrors() islope1.SetMarkerStyle(24) fslope1 = TF1("fslope", "pol1", 0, 10000) #pol0 fslope1.SetLineColor(2) fslope1.SetFillColor(2) # Alpha2 galpha2 = TGraphErrors() galpha2.SetTitle(";m_{X} (GeV);crystal ball upper alpha") galpha2.SetMarkerStyle(20) galpha2.SetMarkerColor(cColor) galpha2.SetLineColor(cColor) ialpha2 = TGraphErrors() ialpha2.SetMarkerStyle(24) falpha2 = TF1("falpha", "pol1", 0, 10000) #pol0 falpha2.SetLineColor(2) falpha2.SetFillColor(2) # Slope2 gslope2 = TGraphErrors() gslope2.SetTitle(";m_{X} (GeV);exponential upper slope (1/Gev)") gslope2.SetMarkerStyle(20) gslope2.SetMarkerColor(cColor) gslope2.SetLineColor(cColor) islope2 = TGraphErrors() islope2.SetMarkerStyle(24) fslope2 = TF1("fslope", "pol1", 0, 10000) #pol0 fslope2.SetLineColor(2) fslope2.SetFillColor(2) n = 0 for i, m in enumerate(genPoints): if not m in signalNorm.keys(): continue if signalNorm[m].getVal() < 1.e-6: continue if gnorm.GetMaximum() < signalNorm[m].getVal(): gnorm.SetMaximum(signalNorm[m].getVal()) gnorm.SetPoint(n, m, signalNorm[m].getVal()) #gnorm.SetPointError(i, 0, signalNorm[m].getVal()/math.sqrt(treeSign[m].GetEntriesFast())) gmean.SetPoint(n, m, vmean[m].getVal()) gmean.SetPointError(n, 0, min(vmean[m].getError(), vmean[m].getVal() * 0.02)) gsigma.SetPoint(n, m, vsigma[m].getVal()) gsigma.SetPointError( n, 0, min(vsigma[m].getError(), vsigma[m].getVal() * 0.05)) galpha1.SetPoint(n, m, valpha1[m].getVal()) galpha1.SetPointError( n, 0, min(valpha1[m].getError(), valpha1[m].getVal() * 0.10)) gslope1.SetPoint(n, m, vslope1[m].getVal()) gslope1.SetPointError( n, 0, min(vslope1[m].getError(), vslope1[m].getVal() * 0.10)) galpha2.SetPoint(n, m, salpha2[m].getVal()) galpha2.SetPointError( n, 0, min(valpha2[m].getError(), valpha2[m].getVal() * 0.10)) gslope2.SetPoint(n, m, sslope2[m].getVal()) gslope2.SetPointError( n, 0, min(vslope2[m].getError(), vslope2[m].getVal() * 0.10)) #tmpVar = w.var(var+"_"+signalString) #print m, tmpVar.getVal(), tmpVar.getError() n = n + 1 gmean.Fit(fmean, "Q0", "SAME") gsigma.Fit(fsigma, "Q0", "SAME") galpha1.Fit(falpha1, "Q0", "SAME") gslope1.Fit(fslope1, "Q0", "SAME") galpha2.Fit(falpha2, "Q0", "SAME") gslope2.Fit(fslope2, "Q0", "SAME") # gnorm.Fit(fnorm, "Q0", "", 700, 5000) #for m in [5000, 5500]: gnorm.SetPoint(gnorm.GetN(), m, gnorm.Eval(m, 0, "S")) #gnorm.Fit(fnorm, "Q", "SAME", 700, 6000) gnorm.Fit(fnorm, "Q", "SAME", 1800, 8000) ## adjusted recently for m in massPoints: if vsigma[m].getVal() < 10.: vsigma[m].setVal(10.) # Interpolation method syield = gnorm.Eval(m) spline = gnorm.Eval(m, 0, "S") sfunct = fnorm.Eval(m) #delta = min(abs(1.-spline/sfunct), abs(1.-spline/syield)) delta = abs(1. - spline / sfunct) if sfunct > 0 else 0 syield = spline if interPar: #jmean = gmean.Eval(m) #jsigma = gsigma.Eval(m) #jalpha1 = galpha1.Eval(m) #jslope1 = gslope1.Eval(m) #jalpha2 = galpha2.Eval(m) #jslope2 = gslope2.Eval(m) jmean = gmean.Eval(m, 0, "S") jsigma = gsigma.Eval(m, 0, "S") jalpha1 = galpha1.Eval(m, 0, "S") jslope1 = gslope1.Eval(m, 0, "S") jalpha2 = galpha2.Eval(m, 0, "S") jslope2 = gslope2.Eval(m, 0, "S") else: jmean = fmean.GetParameter( 0) + fmean.GetParameter(1) * m + fmean.GetParameter(2) * m * m jsigma = fsigma.GetParameter(0) + fsigma.GetParameter( 1) * m + fsigma.GetParameter(2) * m * m jalpha1 = falpha1.GetParameter(0) + falpha1.GetParameter( 1) * m + falpha1.GetParameter(2) * m * m jslope1 = fslope1.GetParameter(0) + fslope1.GetParameter( 1) * m + fslope1.GetParameter(2) * m * m jalpha2 = falpha2.GetParameter(0) + falpha2.GetParameter( 1) * m + falpha2.GetParameter(2) * m * m jslope2 = fslope2.GetParameter(0) + fslope2.GetParameter( 1) * m + fslope2.GetParameter(2) * m * m inorm.SetPoint(inorm.GetN(), m, syield) signalNorm[m].setVal(max(0., syield)) imean.SetPoint(imean.GetN(), m, jmean) if jmean > 0: vmean[m].setVal(jmean) isigma.SetPoint(isigma.GetN(), m, jsigma) if jsigma > 0: vsigma[m].setVal(jsigma) ialpha1.SetPoint(ialpha1.GetN(), m, jalpha1) if not jalpha1 == 0: valpha1[m].setVal(jalpha1) islope1.SetPoint(islope1.GetN(), m, jslope1) if jslope1 > 0: vslope1[m].setVal(jslope1) ialpha2.SetPoint(ialpha2.GetN(), m, jalpha2) if not jalpha2 == 0: valpha2[m].setVal(jalpha2) islope2.SetPoint(islope2.GetN(), m, jslope2) if jslope2 > 0: vslope2[m].setVal(jslope2) #### newly introduced, not yet sure if helpful: vmean[m].removeError() vsigma[m].removeError() valpha1[m].removeError() valpha2[m].removeError() vslope1[m].removeError() vslope2[m].removeError() #signalNorm[m].setConstant(False) ## newly put here to ensure it's freely floating in the combine fit #c1 = TCanvas("c1", "Crystal Ball", 1200, 1200) #if not isAH else 1200 #c1.Divide(2, 3) c1 = TCanvas("c1", "Crystal Ball", 1800, 800) c1.Divide(3, 2) c1.cd(1) gmean.SetMinimum(0.) gmean.Draw("APL") imean.Draw("P, SAME") drawRegion(category) drawCMS(-1, "Simulation Preliminary", year=YEAR) ## new FIXME c1.cd(2) gsigma.SetMinimum(0.) gsigma.Draw("APL") isigma.Draw("P, SAME") drawRegion(category) drawCMS(-1, "Simulation Preliminary", year=YEAR) ## new FIXME c1.cd(3) galpha1.Draw("APL") ialpha1.Draw("P, SAME") drawRegion(category) drawCMS(-1, "Simulation Preliminary", year=YEAR) ## new FIXME galpha1.GetYaxis().SetRangeUser(0., 1.1) #adjusted upper limit from 5 to 2 c1.cd(4) gslope1.Draw("APL") islope1.Draw("P, SAME") drawRegion(category) drawCMS(-1, "Simulation Preliminary", year=YEAR) ## new FIXME gslope1.GetYaxis().SetRangeUser(0., 150.) #adjusted upper limit from 125 to 60 if True: #isAH: c1.cd(5) galpha2.Draw("APL") ialpha2.Draw("P, SAME") drawRegion(category) drawCMS(-1, "Simulation Preliminary", year=YEAR) ## new FIXME galpha2.GetYaxis().SetRangeUser(0., 2.) c1.cd(6) gslope2.Draw("APL") islope2.Draw("P, SAME") drawRegion(category) drawCMS(-1, "Simulation Preliminary", year=YEAR) ## new FIXME gslope2.GetYaxis().SetRangeUser(0., 20.) c1.Print(PLOTDIR + "MC_signal_" + YEAR + "/" + stype + "_" + category + "_SignalShape.pdf") c1.Print(PLOTDIR + "MC_signal_" + YEAR + "/" + stype + "_" + category + "_SignalShape.png") c2 = TCanvas("c2", "Signal Efficiency", 800, 600) c2.cd(1) gnorm.SetMarkerColor(cColor) gnorm.SetMarkerStyle(20) gnorm.SetLineColor(cColor) gnorm.SetLineWidth(2) gnorm.Draw("APL") inorm.Draw("P, SAME") gnorm.GetXaxis().SetRangeUser(genPoints[0] - 100, genPoints[-1] + 100) gnorm.GetYaxis().SetRangeUser(0., gnorm.GetMaximum() * 1.25) drawCMS(-1, "Simulation Preliminary", year=YEAR) #drawCMS(-1, "Work in Progress", year=YEAR, suppressCMS=True) #drawCMS(-1, "", year=YEAR, suppressCMS=True) drawAnalysis(category) drawRegion(category) c2.Print(PLOTDIR + "MC_signal_" + YEAR + "/" + stype + "_" + category + "_SignalNorm.pdf") c2.Print(PLOTDIR + "MC_signal_" + YEAR + "/" + stype + "_" + category + "_SignalNorm.png") #*******************************************************# # # # Generate workspace # # # #*******************************************************# # create workspace w = RooWorkspace("Zprime_" + YEAR, "workspace") for m in massPoints: getattr(w, "import")(signal[m], RooFit.Rename(signal[m].GetName())) getattr(w, "import")(signalNorm[m], RooFit.Rename(signalNorm[m].GetName())) getattr(w, "import")(signalXS[m], RooFit.Rename(signalXS[m].GetName())) w.writeToFile(WORKDIR + "MC_signal_%s_%s.root" % (YEAR, category), True) print "Workspace", WORKDIR + "MC_signal_%s_%s.root" % ( YEAR, category), "saved successfully"
def signal(category): interPar = True n = len(genPoints) cColor = color[category] if category in color else 4 nBtag = category.count('b') isAH = False #relict from using Alberto's more complex script if not os.path.exists(PLOTDIR+"MC_signal_"+YEAR): os.makedirs(PLOTDIR+"MC_signal_"+YEAR) #*******************************************************# # # # Variables and selections # # # #*******************************************************# X_mass = RooRealVar ( "jj_mass_widejet", "m_{jj}", X_min, X_max, "GeV") j1_pt = RooRealVar( "jpt_1", "jet1 pt", 0., 13000., "GeV") jj_deltaEta = RooRealVar( "jj_deltaEta_widejet", "", 0., 5.) jbtag_WP_1 = RooRealVar("jbtag_WP_1", "", -1., 4. ) jbtag_WP_2 = RooRealVar("jbtag_WP_2", "", -1., 4. ) fatjetmass_1 = RooRealVar("fatjetmass_1", "", -1., 2500. ) fatjetmass_2 = RooRealVar("fatjetmass_2", "", -1., 2500. ) jid_1 = RooRealVar( "jid_1", "j1 ID", -1., 8.) jid_2 = RooRealVar( "jid_2", "j2 ID", -1., 8.) jnmuons_1 = RooRealVar( "jnmuons_1", "j1 n_{#mu}", -1., 8.) jnmuons_2 = RooRealVar( "jnmuons_2", "j2 n_{#mu}", -1., 8.) jmuonpt_1 = RooRealVar( "jmuonpt_1", "j1 muon pt", 0., 13000.) jmuonpt_2 = RooRealVar( "jmuonpt_2", "j2 muon pt", 0., 13000.) nmuons = RooRealVar( "nmuons", "n_{#mu}", -1., 10. ) nelectrons = RooRealVar("nelectrons", "n_{e}", -1., 10. ) HLT_AK8PFJet500 = RooRealVar("HLT_AK8PFJet500" , "", -1., 1. ) HLT_PFJet500 = RooRealVar("HLT_PFJet500" , "" , -1., 1. ) HLT_CaloJet500_NoJetID = RooRealVar("HLT_CaloJet500_NoJetID" , "" , -1., 1. ) HLT_PFHT900 = RooRealVar("HLT_PFHT900" , "" , -1., 1. ) HLT_AK8PFJet550 = RooRealVar("HLT_AK8PFJet550" , "", -1., 1. ) HLT_PFJet550 = RooRealVar("HLT_PFJet550" , "" , -1., 1. ) HLT_CaloJet550_NoJetID = RooRealVar("HLT_CaloJet550_NoJetID" , "" , -1., 1. ) HLT_PFHT1050 = RooRealVar("HLT_PFHT1050" , "" , -1., 1. ) HLT_DoublePFJets100_CaloBTagDeepCSV_p71 =RooRealVar("HLT_DoublePFJets100_CaloBTagDeepCSV_p71" , "", -1., 1. ) HLT_DoublePFJets116MaxDeta1p6_DoubleCaloBTagDeepCSV_p71 =RooRealVar("HLT_DoublePFJets116MaxDeta1p6_DoubleCaloBTagDeepCSV_p71", "", -1., 1. ) HLT_DoublePFJets128MaxDeta1p6_DoubleCaloBTagDeepCSV_p71 =RooRealVar("HLT_DoublePFJets128MaxDeta1p6_DoubleCaloBTagDeepCSV_p71", "", -1., 1. ) HLT_DoublePFJets200_CaloBTagDeepCSV_p71 =RooRealVar("HLT_DoublePFJets200_CaloBTagDeepCSV_p71" , "", -1., 1. ) HLT_DoublePFJets350_CaloBTagDeepCSV_p71 =RooRealVar("HLT_DoublePFJets350_CaloBTagDeepCSV_p71" , "", -1., 1. ) HLT_DoublePFJets40_CaloBTagDeepCSV_p71 =RooRealVar("HLT_DoublePFJets40_CaloBTagDeepCSV_p71" , "", -1., 1. ) weight = RooRealVar( "eventWeightLumi", "", -1.e9, 1.e9 ) # Define the RooArgSet which will include all the variables defined before # there is a maximum of 9 variables in the declaration, so the others need to be added with 'add' variables = RooArgSet(X_mass) variables.add(RooArgSet(j1_pt, jj_deltaEta, jbtag_WP_1, jbtag_WP_2, fatjetmass_1, fatjetmass_2, jnmuons_1, jnmuons_2, weight)) variables.add(RooArgSet(nmuons, nelectrons, jid_1, jid_2, jmuonpt_1, jmuonpt_2)) variables.add(RooArgSet(HLT_AK8PFJet500, HLT_PFJet500, HLT_CaloJet500_NoJetID, HLT_PFHT900, HLT_AK8PFJet550, HLT_PFJet550, HLT_CaloJet550_NoJetID, HLT_PFHT1050)) variables.add(RooArgSet(HLT_DoublePFJets100_CaloBTagDeepCSV_p71, HLT_DoublePFJets116MaxDeta1p6_DoubleCaloBTagDeepCSV_p71, HLT_DoublePFJets128MaxDeta1p6_DoubleCaloBTagDeepCSV_p71, HLT_DoublePFJets200_CaloBTagDeepCSV_p71, HLT_DoublePFJets350_CaloBTagDeepCSV_p71, HLT_DoublePFJets40_CaloBTagDeepCSV_p71)) X_mass.setRange("X_reasonable_range", X_mass.getMin(), X_mass.getMax()) X_mass.setRange("X_integration_range", X_mass.getMin(), X_mass.getMax()) if VARBINS: binsXmass = RooBinning(len(abins)-1, abins) X_mass.setBinning(binsXmass) plot_binning = RooBinning(int((X_mass.getMax()-X_mass.getMin())/100), X_mass.getMin(), X_mass.getMax()) else: X_mass.setBins(int((X_mass.getMax()-X_mass.getMin())/10)) binsXmass = RooBinning(int((X_mass.getMax()-X_mass.getMin())/100), X_mass.getMin(), X_mass.getMax()) plot_binning = binsXmass X_mass.setBinning(plot_binning, "PLOT") #X_mass.setBins(int((X_mass.getMax() - X_mass.getMin())/10)) #binsXmass = RooBinning(int((X_mass.getMax() - X_mass.getMin())/100), X_mass.getMin(), X_mass.getMax()) #X_mass.setBinning(binsXmass, "PLOT") massArg = RooArgSet(X_mass) # Cuts if BTAGGING=='semimedium': SRcut = aliasSM[category] #SRcut = aliasSM[category+"_vetoAK8"] else: SRcut = alias[category].format(WP=working_points[BTAGGING]) #SRcut = alias[category+"_vetoAK8"].format(WP=working_points[BTAGGING]) if ADDSELECTION: SRcut += SELECTIONS[options.selection] print " Cut:\t", SRcut #*******************************************************# # # # Signal fits # # # #*******************************************************# treeSign = {} setSignal = {} vmean = {} vsigma = {} valpha1 = {} vslope1 = {} valpha2 = {} vslope2 = {} smean = {} ssigma = {} salpha1 = {} sslope1 = {} salpha2 = {} sslope2 = {} sbrwig = {} signal = {} signalExt = {} signalYield = {} signalIntegral = {} signalNorm = {} signalXS = {} frSignal = {} frSignal1 = {} frSignal2 = {} frSignal3 = {} # Signal shape uncertainties (common amongst all mass points) xmean_jes = RooRealVar("CMS"+YEAR+"_sig_"+category+"_p1_scale_jes", "Variation of the resonance position with the jet energy scale", 0.02, -1., 1.) #0.001 smean_jes = RooRealVar("CMS"+YEAR+"_sig_"+category+"_p1_jes", "Change of the resonance position with the jet energy scale", 0., -10, 10) xsigma_jer = RooRealVar("CMS"+YEAR+"_sig_"+category+"_p2_scale_jer", "Variation of the resonance width with the jet energy resolution", 0.10, -1., 1.) ssigma_jer = RooRealVar("CMS"+YEAR+"_sig_"+category+"_p2_jer", "Change of the resonance width with the jet energy resolution", 0., -10, 10) xmean_jes.setConstant(True) smean_jes.setConstant(True) xsigma_jer.setConstant(True) ssigma_jer.setConstant(True) for m in massPoints: signalMass = "%s_M%d" % (stype, m) signalName = "ZpBB_{}_{}_M{}".format(YEAR, category, m) sampleName = "bstar_M{}".format(m) signalColor = sample[sampleName]['linecolor'] if signalName in sample else 1 # define the signal PDF vmean[m] = RooRealVar(signalName + "_vmean", "Crystal Ball mean", m, m*0.96, m*1.05) smean[m] = RooFormulaVar(signalName + "_mean", "@0*(1+@1*@2)", RooArgList(vmean[m], xmean_jes, smean_jes)) vsigma[m] = RooRealVar(signalName + "_vsigma", "Crystal Ball sigma", m*0.0233, m*0.019, m*0.025) ssigma[m] = RooFormulaVar(signalName + "_sigma", "@0*(1+@1*@2)", RooArgList(vsigma[m], xsigma_jer, ssigma_jer)) valpha1[m] = RooRealVar(signalName + "_valpha1", "Crystal Ball alpha 1", 0.2, 0.05, 0.28) # number of sigmas where the exp is attached to the gaussian core. >0 left, <0 right salpha1[m] = RooFormulaVar(signalName + "_alpha1", "@0", RooArgList(valpha1[m])) #vslope1[m] = RooRealVar(signalName + "_vslope1", "Crystal Ball slope 1", 10., 0.1, 20.) # slope of the power tail vslope1[m] = RooRealVar(signalName + "_vslope1", "Crystal Ball slope 1", 13., 10., 20.) # slope of the power tail sslope1[m] = RooFormulaVar(signalName + "_slope1", "@0", RooArgList(vslope1[m])) valpha2[m] = RooRealVar(signalName + "_valpha2", "Crystal Ball alpha 2", 1.) valpha2[m].setConstant(True) salpha2[m] = RooFormulaVar(signalName + "_alpha2", "@0", RooArgList(valpha2[m])) #vslope2[m] = RooRealVar(signalName + "_vslope2", "Crystal Ball slope 2", 6., 2.5, 15.) # slope of the higher power tail ## FIXME test FIXME vslope2_estimation = -5.88111436852 + m*0.00728809389442 + m*m*(-1.65059568762e-06) + m*m*m*(1.25128996309e-10) vslope2[m] = RooRealVar(signalName + "_vslope2", "Crystal Ball slope 2", vslope2_estimation, vslope2_estimation*0.9, vslope2_estimation*1.1) # slope of the higher power tail ## FIXME end FIXME sslope2[m] = RooFormulaVar(signalName + "_slope2", "@0", RooArgList(vslope2[m])) # slope of the higher power tail signal[m] = RooDoubleCrystalBall(signalName, "m_{%s'} = %d GeV" % ('X', m), X_mass, smean[m], ssigma[m], salpha1[m], sslope1[m], salpha2[m], sslope2[m]) # extend the PDF with the yield to perform an extended likelihood fit signalYield[m] = RooRealVar(signalName+"_yield", "signalYield", 50, 0., 1.e15) signalNorm[m] = RooRealVar(signalName+"_norm", "signalNorm", 1., 0., 1.e15) signalXS[m] = RooRealVar(signalName+"_xs", "signalXS", 1., 0., 1.e15) signalExt[m] = RooExtendPdf(signalName+"_ext", "extended p.d.f", signal[m], signalYield[m]) # ---------- if there is no simulated signal, skip this mass point ---------- if m in genPoints: if VERBOSE: print " - Mass point", m # define the dataset for the signal applying the SR cuts treeSign[m] = TChain("tree") if YEAR=='run2': pd = sample[sampleName]['files'] if len(pd)>3: print "multiple files given than years for a single masspoint:",pd sys.exit() for ss in pd: if not '2016' in ss and not '2017' in ss and not '2018' in ss: print "unknown year given in:", ss sys.exit() else: pd = [x for x in sample[sampleName]['files'] if YEAR in x] if len(pd)>1: print "multiple files given for a single masspoint/year:",pd sys.exit() for ss in pd: if options.unskimmed: j=0 while True: if os.path.exists(NTUPLEDIR + ss + "/" + ss + "_flatTuple_{}.root".format(j)): treeSign[m].Add(NTUPLEDIR + ss + "/" + ss + "_flatTuple_{}.root".format(j)) j += 1 else: print "found {} files for sample:".format(j), ss break else: if os.path.exists(NTUPLEDIR + ss + ".root"): treeSign[m].Add(NTUPLEDIR + ss + ".root") else: print "found no file for sample:", ss if treeSign[m].GetEntries() <= 0.: if VERBOSE: print " - 0 events available for mass", m, "skipping mass point..." signalNorm[m].setVal(-1) vmean[m].setConstant(True) vsigma[m].setConstant(True) salpha1[m].setConstant(True) sslope1[m].setConstant(True) salpha2[m].setConstant(True) sslope2[m].setConstant(True) signalNorm[m].setConstant(True) signalXS[m].setConstant(True) continue #setSignal[m] = RooDataSet("setSignal_"+signalName, "setSignal", variables, RooFit.Cut(SRcut), RooFit.WeightVar("eventWeightLumi*BTagAK4Weight_deepJet"), RooFit.Import(treeSign[m])) setSignal[m] = RooDataSet("setSignal_"+signalName, "setSignal", variables, RooFit.Cut(SRcut), RooFit.WeightVar(weight), RooFit.Import(treeSign[m])) if VERBOSE: print " - Dataset with", setSignal[m].sumEntries(), "events loaded" # FIT entries = setSignal[m].sumEntries() if entries < 0. or entries != entries: entries = 0 signalYield[m].setVal(entries) # Instead of eventWeightLumi #signalYield[m].setVal(entries * LUMI / (300000 if YEAR=='run2' else 100000) ) if treeSign[m].GetEntries(SRcut) > 5: if VERBOSE: print " - Running fit" frSignal[m] = signalExt[m].fitTo(setSignal[m], RooFit.Save(1), RooFit.Extended(True), RooFit.SumW2Error(True), RooFit.PrintLevel(-1)) if VERBOSE: print "********** Fit result [", m, "] **", category, "*"*40, "\n", frSignal[m].Print(), "\n", "*"*80 if VERBOSE: frSignal[m].correlationMatrix().Print() drawPlot(signalMass+"_"+category, stype+category, X_mass, signal[m], setSignal[m], frSignal[m]) else: print " WARNING: signal", stype, "and mass point", m, "in category", category, "has 0 entries or does not exist" # Remove HVT cross sections #xs = getCrossSection(stype, channel, m) xs = 1. signalXS[m].setVal(xs * 1000.) signalIntegral[m] = signalExt[m].createIntegral(massArg, RooFit.NormSet(massArg), RooFit.Range("X_integration_range")) boundaryFactor = signalIntegral[m].getVal() if boundaryFactor < 0. or boundaryFactor != boundaryFactor: boundaryFactor = 0 if VERBOSE: print " - Fit normalization vs integral:", signalYield[m].getVal(), "/", boundaryFactor, "events" signalNorm[m].setVal( boundaryFactor * signalYield[m].getVal() / signalXS[m].getVal()) # here normalize to sigma(X) x Br = 1 [fb]
def dijet(category): channel = 'bb' stype = channel isSB = True # relict from using Alberto's more complex script isData = not ISMC nTupleDir = NTUPLEDIR samples = data if isData else back pd = [] for sample_name in samples: if YEAR == 'run2': pd += sample[sample_name]['files'] else: pd += [x for x in sample[sample_name]['files'] if YEAR in x] print "datasets:", pd if not os.path.exists(PLOTDIR): os.makedirs(PLOTDIR) if BIAS: print "Running in BIAS mode" order = 0 RSS = {} X_mass = RooRealVar("jj_mass_widejet", "m_{jj}", X_min, X_max, "GeV") weight = RooRealVar("MANtag_weight", "", -1.e9, 1.e9) variables = RooArgSet(X_mass) variables.add(RooArgSet(weight)) if VARBINS: binsXmass = RooBinning(len(abins) - 1, abins) X_mass.setBinning(RooBinning(len(abins_narrow) - 1, abins_narrow)) plot_binning = RooBinning( int((X_mass.getMax() - X_mass.getMin()) / 100), X_mass.getMin(), X_mass.getMax()) else: X_mass.setBins(int((X_mass.getMax() - X_mass.getMin()) / 10)) binsXmass = RooBinning(int((X_mass.getMax() - X_mass.getMin()) / 100), X_mass.getMin(), X_mass.getMax()) plot_binning = binsXmass baseCut = "" print stype, "|", baseCut print " - Reading from Tree" treeBkg = TChain("tree") for ss in pd: if os.path.exists(nTupleDir + ss + "_" + BTAGGING + ".root"): treeBkg.Add(nTupleDir + ss + "_" + BTAGGING + ".root") else: print "found no file for sample:", ss setData = RooDataSet("setData", "Data (QCD+TTbar MC)", variables, RooFit.Cut(baseCut), RooFit.WeightVar(weight), RooFit.Import(treeBkg)) nevents = setData.sumEntries() dataMin, dataMax = array('d', [0.]), array('d', [0.]) setData.getRange(X_mass, dataMin, dataMax) xmin, xmax = dataMin[0], dataMax[0] lastBin = X_mass.getMax() if VARBINS: for b in narrow_bins: if b > xmax: lastBin = b break print "Imported", ( "data" if isData else "MC" ), "RooDataSet with", nevents, "events between [%.1f, %.1f]" % (xmin, xmax) #xmax = xmax+binsXmass.averageBinWidth() # start form next bin # 1 parameter print "fitting 1 parameter model" p1_1 = RooRealVar("CMS" + YEAR + "_" + category + "_p1_1", "p1", 7.0, 0., 2000.) modelBkg1 = RooGenericPdf("Bkg1", "Bkg. fit (2 par.)", "1./pow(@0/13000, @1)", RooArgList(X_mass, p1_1)) normzBkg1 = RooRealVar( modelBkg1.GetName() + "_norm", "Number of background events", nevents, 0., 5. * nevents) #range dependent of actual number of events! modelExt1 = RooExtendPdf(modelBkg1.GetName() + "_ext", modelBkg1.GetTitle(), modelBkg1, normzBkg1) fitRes1 = modelExt1.fitTo(setData, RooFit.Extended(True), RooFit.Save(1), RooFit.SumW2Error(not isData), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.PrintLevel(1 if VERBOSE else -1)) fitRes1.Print() RSS[1] = drawFit("Bkg1", category, X_mass, modelBkg1, setData, binsXmass, [fitRes1], normzBkg1.getVal()) # 2 parameters print "fitting 2 parameter model" p2_1 = RooRealVar("CMS" + YEAR + "_" + category + "_p2_1", "p1", 0., -100., 1000.) p2_2 = RooRealVar("CMS" + YEAR + "_" + category + "_p2_2", "p2", p1_1.getVal(), -100., 600.) modelBkg2 = RooGenericPdf("Bkg2", "Bkg. fit (3 par.)", "pow(1-@0/13000, @1) / pow(@0/13000, @2)", RooArgList(X_mass, p2_1, p2_2)) normzBkg2 = RooRealVar(modelBkg2.GetName() + "_norm", "Number of background events", nevents, 0., 5. * nevents) modelExt2 = RooExtendPdf(modelBkg2.GetName() + "_ext", modelBkg2.GetTitle(), modelBkg2, normzBkg2) fitRes2 = modelExt2.fitTo(setData, RooFit.Extended(True), RooFit.Save(1), RooFit.SumW2Error(not isData), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.PrintLevel(1 if VERBOSE else -1)) fitRes2.Print() RSS[2] = drawFit("Bkg2", category, X_mass, modelBkg2, setData, binsXmass, [fitRes2], normzBkg2.getVal()) # 3 parameters print "fitting 3 parameter model" p3_1 = RooRealVar("CMS" + YEAR + "_" + category + "_p3_1", "p1", p2_1.getVal(), -2000., 2000.) p3_2 = RooRealVar("CMS" + YEAR + "_" + category + "_p3_2", "p2", p2_2.getVal(), -400., 2000.) p3_3 = RooRealVar("CMS" + YEAR + "_" + category + "_p3_3", "p3", -2.5, -500., 500.) modelBkg3 = RooGenericPdf( "Bkg3", "Bkg. fit (4 par.)", "pow(1-@0/13000, @1) / pow(@0/13000, @2+@3*log(@0/13000))", RooArgList(X_mass, p3_1, p3_2, p3_3)) normzBkg3 = RooRealVar(modelBkg3.GetName() + "_norm", "Number of background events", nevents, 0., 5. * nevents) modelExt3 = RooExtendPdf(modelBkg3.GetName() + "_ext", modelBkg3.GetTitle(), modelBkg3, normzBkg3) fitRes3 = modelExt3.fitTo(setData, RooFit.Extended(True), RooFit.Save(1), RooFit.SumW2Error(not isData), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.PrintLevel(1 if VERBOSE else -1)) fitRes3.Print() RSS[3] = drawFit("Bkg3", category, X_mass, modelBkg3, setData, binsXmass, [fitRes3], normzBkg3.getVal()) # 4 parameters print "fitting 4 parameter model" p4_1 = RooRealVar("CMS" + YEAR + "_" + category + "_p4_1", "p1", p3_1.getVal(), -2000., 2000.) p4_2 = RooRealVar("CMS" + YEAR + "_" + category + "_p4_2", "p2", p3_2.getVal(), -2000., 2000.) p4_3 = RooRealVar("CMS" + YEAR + "_" + category + "_p4_3", "p3", p3_3.getVal(), -50., 50.) p4_4 = RooRealVar("CMS" + YEAR + "_" + category + "_p4_4", "p4", 0.1, -50., 50.) modelBkg4 = RooGenericPdf( "Bkg4", "Bkg. fit (5 par.)", "pow(1 - @0/13000, @1) / pow(@0/13000, @2+@3*log(@0/13000)+@4*pow(log(@0/13000), 2))", RooArgList(X_mass, p4_1, p4_2, p4_3, p4_4)) normzBkg4 = RooRealVar(modelBkg4.GetName() + "_norm", "Number of background events", nevents, 0., 5. * nevents) modelExt4 = RooExtendPdf(modelBkg4.GetName() + "_ext", modelBkg4.GetTitle(), modelBkg4, normzBkg4) fitRes4 = modelExt4.fitTo(setData, RooFit.Extended(True), RooFit.Save(1), RooFit.SumW2Error(not isData), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.PrintLevel(1 if VERBOSE else -1)) fitRes4.Print() RSS[4] = drawFit("Bkg4", category, X_mass, modelBkg4, setData, binsXmass, [fitRes4], normzBkg4.getVal()) # Normalization parameters are should be set constant, but shape ones should not # if BIAS: # p1_1.setConstant(True) # p2_1.setConstant(True) # p2_2.setConstant(True) # p3_1.setConstant(True) # p3_2.setConstant(True) # p3_3.setConstant(True) # p4_1.setConstant(True) # p4_2.setConstant(True) # p4_3.setConstant(True) # p4_4.setConstant(True) normzBkg1.setConstant(True) normzBkg2.setConstant(True) normzBkg3.setConstant(True) normzBkg4.setConstant(True) #*******************************************************# # # # Fisher # # # #*******************************************************# # Fisher test with open(PLOTDIR + "/Fisher_" + category + ".tex", 'w') as fout: fout.write(r"\begin{tabular}{c|c|c|c|c}") fout.write("\n") fout.write(r"function & $\chi^2$ & RSS & ndof & F-test \\") fout.write("\n") fout.write("\hline") fout.write("\n") CL_high = False for o1 in range(1, 5): o2 = min(o1 + 1, 5) fout.write("%d par & %.2f & %.2f & %d & " % (o1 + 1, RSS[o1]["chi2"], RSS[o1]["rss"], RSS[o1]["nbins"] - RSS[o1]["npar"])) if o2 > len(RSS): fout.write(r"\\") fout.write("\n") continue #order==0 and CL = fisherTest(RSS[o1]['rss'], RSS[o2]['rss'], o1 + 1., o2 + 1., RSS[o1]["nbins"]) fout.write("CL=%.3f " % (CL)) if CL > 0.10: # The function with less parameters is enough if not CL_high: order = o1 #fout.write( "%d par are sufficient " % (o1+1)) CL_high = True else: #fout.write( "%d par are needed " % (o2+1)) if not CL_high: order = o2 fout.write(r"\\") fout.write("\n") fout.write("\hline") fout.write("\n") fout.write(r"\end{tabular}") print "saved F-test table as", PLOTDIR + "/Fisher_" + category + ".tex" #print "-"*25 #print "function & $\\chi^2$ & RSS & ndof & F-test & result \\\\" #print "\\multicolumn{6}{c}{", "Zprime_to_bb", "} \\\\" #print "\\hline" #CL_high = False #for o1 in range(1, 5): # o2 = min(o1 + 1, 5) # print "%d par & %.2f & %.2f & %d & " % (o1+1, RSS[o1]["chi2"], RSS[o1]["rss"], RSS[o1]["nbins"]-RSS[o1]["npar"]), # if o2 > len(RSS): # print "\\\\" # continue #order==0 and # CL = fisherTest(RSS[o1]['rss'], RSS[o2]['rss'], o1+1., o2+1., RSS[o1]["nbins"]) # print "%d par vs %d par CL=%f & " % (o1+1, o2+1, CL), # if CL > 0.10: # The function with less parameters is enough # if not CL_high: # order = o1 # print "%d par are sufficient" % (o1+1), # CL_high=True # else: # print "%d par are needed" % (o2+1), # if not CL_high: # order = o2 # print "\\\\" #print "\\hline" #print "-"*25 #print "@ Order is", order, "("+category+")" #order = min(3, order) #order = 2 if order == 1: modelBkg = modelBkg1 #.Clone("Bkg") modelAlt = modelBkg2 #.Clone("BkgAlt") normzBkg = normzBkg1 #.Clone("Bkg_norm") fitRes = fitRes1 elif order == 2: modelBkg = modelBkg2 #.Clone("Bkg") modelAlt = modelBkg3 #.Clone("BkgAlt") normzBkg = normzBkg2 #.Clone("Bkg_norm") fitRes = fitRes2 elif order == 3: modelBkg = modelBkg3 #.Clone("Bkg") modelAlt = modelBkg4 #.Clone("BkgAlt") normzBkg = normzBkg3 #.Clone("Bkg_norm") fitRes = fitRes3 elif order == 4: modelBkg = modelBkg4 #.Clone("Bkg") modelAlt = modelBkg3 #.Clone("BkgAlt") normzBkg = normzBkg4 #.Clone("Bkg_norm") fitRes = fitRes4 else: print "Functions with", order + 1, "or more parameters are needed to fit the background" exit() modelBkg.SetName("Bkg_" + YEAR + "_" + category) modelAlt.SetName("Alt_" + YEAR + "_" + category) normzBkg.SetName("Bkg_" + YEAR + "_" + category + "_norm") print "-" * 25 # Generate pseudo data setToys = RooDataSet() setToys.SetName("data_toys") setToys.SetTitle("Data (toys)") if not isData: print " - Generating", nevents, "events for toy data" setToys = modelBkg.generate(RooArgSet(X_mass), nevents) #setToys = modelAlt.generate(RooArgSet(X_mass), nevents) print "toy data generated" if VERBOSE: raw_input("Press Enter to continue...") #*******************************************************# # # # Plot # # # #*******************************************************# print "starting to plot" c = TCanvas("c_" + category, category, 800, 800) c.Divide(1, 2) setTopPad(c.GetPad(1), RATIO) setBotPad(c.GetPad(2), RATIO) c.cd(1) frame = X_mass.frame() setPadStyle(frame, 1.25, True) if VARBINS: frame.GetXaxis().SetRangeUser(X_mass.getMin(), lastBin) signal = getSignal( category, stype, 2000) #replacing Alberto's getSignal by own dummy function graphData = setData.plotOn(frame, RooFit.Binning(plot_binning), RooFit.Scaling(False), RooFit.Invisible()) modelBkg.plotOn(frame, RooFit.VisualizeError(fitRes, 1, False), RooFit.LineColor(602), RooFit.FillColor(590), RooFit.FillStyle(1001), RooFit.DrawOption("FL"), RooFit.Name("1sigma")) modelBkg.plotOn(frame, RooFit.LineColor(602), RooFit.FillColor(590), RooFit.FillStyle(1001), RooFit.DrawOption("L"), RooFit.Name(modelBkg.GetName())) modelAlt.plotOn(frame, RooFit.LineStyle(7), RooFit.LineColor(613), RooFit.FillColor(609), RooFit.FillStyle(1001), RooFit.DrawOption("L"), RooFit.Name(modelAlt.GetName())) if not isSB and signal[0] is not None: # FIXME remove /(2./3.) signal[0].plotOn( frame, RooFit.Normalization(signal[1] * signal[2], RooAbsReal.NumEvent), RooFit.LineStyle(3), RooFit.LineWidth(6), RooFit.LineColor(629), RooFit.DrawOption("L"), RooFit.Name("Signal")) graphData = setData.plotOn( frame, RooFit.Binning(plot_binning), RooFit.Scaling(False), RooFit.XErrorSize(0 if not VARBINS else 1), RooFit.DataError(RooAbsData.Poisson if isData else RooAbsData.SumW2), RooFit.DrawOption("PE0"), RooFit.Name(setData.GetName())) fixData(graphData.getHist(), True, True, not isData) pulls = frame.pullHist(setData.GetName(), modelBkg.GetName(), True) chi = frame.chiSquare(setData.GetName(), modelBkg.GetName(), True) #setToys.plotOn(frame, RooFit.DataError(RooAbsData.Poisson), RooFit.DrawOption("PE0"), RooFit.MarkerColor(2)) frame.GetYaxis().SetTitle("Events / ( 100 GeV )") frame.GetYaxis().SetTitleOffset(1.05) frame.Draw() #print "frame drawn" # Get Chi2 # chi2[1] = frame.chiSquare(modelBkg1.GetName(), setData.GetName()) # chi2[2] = frame.chiSquare(modelBkg2.GetName(), setData.GetName()) # chi2[3] = frame.chiSquare(modelBkg3.GetName(), setData.GetName()) # chi2[4] = frame.chiSquare(modelBkg4.GetName(), setData.GetName()) frame.SetMaximum(frame.GetMaximum() * 10) frame.SetMinimum(max(frame.GetMinimum(), 1.e-1)) c.GetPad(1).SetLogy() drawAnalysis(category) drawRegion(category, True) #drawCMS(LUMI, "Simulation Preliminary") drawCMS(LUMI, "Work in Progress", suppressCMS=True) leg = TLegend(0.575, 0.6, 0.95, 0.9) leg.SetBorderSize(0) leg.SetFillStyle(0) #1001 leg.SetFillColor(0) leg.AddEntry(setData.GetName(), setData.GetTitle() + " (%d events)" % nevents, "PEL") leg.AddEntry(modelBkg.GetName(), modelBkg.GetTitle(), "FL") #.SetTextColor(629) leg.AddEntry(modelAlt.GetName(), modelAlt.GetTitle(), "L") if not isSB and signal[0] is not None: leg.AddEntry("Signal", signal[0].GetTitle(), "L") leg.SetY1(0.9 - leg.GetNRows() * 0.05) leg.Draw() latex = TLatex() latex.SetNDC() latex.SetTextSize(0.04) latex.SetTextFont(42) if not isSB: latex.DrawLatex(leg.GetX1() * 1.16, leg.GetY1() - 0.04, "HVT model B (g_{V}=3)") # latex.DrawLatex(0.67, leg.GetY1()-0.045, "#sigma_{X} = 1.0 pb") c.cd(2) frame_res = X_mass.frame() setPadStyle(frame_res, 1.25) frame_res.addPlotable(pulls, "P") setBotStyle(frame_res, RATIO, False) if VARBINS: frame_res.GetXaxis().SetRangeUser(X_mass.getMin(), lastBin) frame_res.GetYaxis().SetRangeUser(-5, 5) frame_res.GetYaxis().SetTitle("pulls(#sigma)") frame_res.GetYaxis().SetTitleOffset(0.3) frame_res.Draw() fixData(pulls, False, True, False) drawChi2(RSS[order]["chi2"], RSS[order]["nbins"] - (order + 1), True) line = drawLine(X_mass.getMin(), 0, lastBin, 0) if VARBINS: c.SaveAs(PLOTDIR + "/BkgSR_" + category + ".pdf") c.SaveAs(PLOTDIR + "/BkgSR_" + category + ".png") else: c.SaveAs(PLOTDIR + "/BkgSR_" + category + ".pdf") c.SaveAs(PLOTDIR + "/BkgSR_" + category + ".png") #*******************************************************# # # # Generate workspace # # # #*******************************************************# if BIAS: gSystem.Load("libHiggsAnalysisCombinedLimit.so") from ROOT import RooMultiPdf cat = RooCategory("pdf_index", "Index of Pdf which is active") pdfs = RooArgList(modelBkg, modelAlt) roomultipdf = RooMultiPdf("roomultipdf", "All Pdfs", cat, pdfs) normulti = RooRealVar("roomultipdf_norm", "Number of background events", nevents, 0., 1.e6) normzBkg.setConstant( False ) ## newly put here to ensure it's freely floating in the combine fit # create workspace w = RooWorkspace("Zprime_" + YEAR, "workspace") # Dataset if isData: getattr(w, "import")(setData, RooFit.Rename("data_obs")) else: getattr(w, "import")(setToys, RooFit.Rename("data_obs")) #getattr(w, "import")(setData, RooFit.Rename("data_obs")) if BIAS: getattr(w, "import")(cat, RooFit.Rename(cat.GetName())) getattr(w, "import")(normulti, RooFit.Rename(normulti.GetName())) getattr(w, "import")(roomultipdf, RooFit.Rename(roomultipdf.GetName())) getattr(w, "import")(modelBkg, RooFit.Rename(modelBkg.GetName())) getattr(w, "import")(modelAlt, RooFit.Rename(modelAlt.GetName())) getattr(w, "import")(normzBkg, RooFit.Rename(normzBkg.GetName())) w.writeToFile(WORKDIR + "%s_%s.root" % (DATA_TYPE + "_" + YEAR, category), True) print "Workspace", WORKDIR + "%s_%s.root" % ( DATA_TYPE + "_" + YEAR, category), "saved successfully" if VERBOSE: raw_input("Press Enter to continue...")
def alpha(channel): nElec = channel.count('e') nMuon = channel.count('m') nLept = nElec + nMuon nBtag = channel.count('b') # Channel-dependent settings # Background function. Semi-working options are: EXP, EXP2, EXPN, EXPTAIL if nLept == 0: treeName = 'SR' signName = 'XZh' colorVjet = sample['DYJetsToNuNu']['linecolor'] triName = "HLT_PFMET" leptCut = "0==0" topVeto = selection["TopVetocut"] massVar = "X_cmass" binFact = 1 #fitFunc = "EXP" #fitFunc = "EXP2" #fitFunc = "EXPN" #fitFunc = "EXPTAIL" fitFunc = "EXPN" if nBtag < 2 else "EXP" fitAltFunc = "EXPTAIL" if nBtag < 2 else "EXPTAIL" fitFuncVjet = "ERFEXP" if nBtag < 2 else "ERFEXP" fitFuncVV = "EXPGAUS" fitFuncTop = "GAUS2" elif nLept == 1: treeName = 'WCR' signName = 'XWh' colorVjet = sample['WJetsToLNu']['linecolor'] triName = "HLT_Ele" if nElec > 0 else "HLT_Mu" leptCut = "isWtoEN" if nElec > 0 else "isWtoMN" topVeto = selection["TopVetocut"] massVar = "X_mass" binFact = 2 if nElec > 0: fitFunc = "EXP" if nBtag < 2 else "EXP" fitAltFunc = "EXPTAIL" if nBtag < 2 else "EXPTAIL" else: fitFunc = "EXPTAIL" if nBtag < 2 else "EXP" fitAltFunc = "EXPN" if nBtag < 2 else "EXPTAIL" fitFuncVjet = "ERFEXP" if nBtag < 2 else "ERFEXP" fitFuncVV = "EXPGAUS" fitFuncTop = "GAUS3" if nBtag < 2 else "GAUS2" else: treeName = 'XZh' signName = 'XZh' colorVjet = sample['DYJetsToLL']['linecolor'] triName = "HLT_Ele" if nElec > 0 else "HLT_Mu" leptCut = "isZtoEE" if nElec > 0 else "isZtoMM" topVeto = "0==0" massVar = "X_mass" binFact = 5 if nElec > 0: fitFunc = "EXP" if nBtag < 2 else "EXP" fitAltFunc = "POW" if nBtag < 2 else "POW" else: fitFunc = "EXP" if nBtag < 2 else "EXP" fitAltFunc = "POW" if nBtag < 2 else "POW" fitFuncVjet = "ERFEXP" if nBtag < 2 else "EXP" fitFuncVV = "EXPGAUS2" fitFuncTop = "GAUS" btagCut = selection["2Btag"] if nBtag == 2 else selection["1Btag"] print "--- Channel", channel, "---" print " number of electrons:", nElec, " muons:", nMuon, " b-tags:", nBtag print " read tree:", treeName, "and trigger:", triName if ALTERNATIVE: print " using ALTERNATIVE fit functions" print "-"*11*2 # Silent RooFit RooMsgService.instance().setGlobalKillBelow(RooFit.FATAL) #*******************************************************# # # # Variables and selections # # # #*******************************************************# # Define all the variables from the trees that will be used in the cuts and fits # this steps actually perform a "projection" of the entire tree on the variables in thei ranges, so be careful once setting the limits X_mass = RooRealVar( massVar, "m_{X}" if nLept > 0 else "m_{T}^{X}", XBINMIN, XBINMAX, "GeV") J_mass = RooRealVar( "fatjet1_prunedMassCorr", "corrected pruned mass", HBINMIN, HBINMAX, "GeV") CSV1 = RooRealVar( "fatjet1_CSVR1", "", -1.e99, 1.e4 ) CSV2 = RooRealVar( "fatjet1_CSVR2", "", -1.e99, 1.e4 ) nBtag = RooRealVar( "fatjet1_nBtag", "", 0., 4 ) CSVTop = RooRealVar( "bjet1_CSVR", "", -1.e99, 1.e4 ) isZtoEE = RooRealVar("isZtoEE", "", 0., 2 ) isZtoMM = RooRealVar("isZtoMM", "", 0., 2 ) isWtoEN = RooRealVar("isWtoEN", "", 0., 2 ) isWtoMN = RooRealVar("isWtoMN", "", 0., 2 ) weight = RooRealVar( "eventWeightLumi", "", -1.e9, 1. ) # Define the RooArgSet which will include all the variables defined before # there is a maximum of 9 variables in the declaration, so the others need to be added with 'add' variables = RooArgSet(X_mass, J_mass, CSV1, CSV2, nBtag, CSVTop) variables.add(RooArgSet(isZtoEE, isZtoMM, isWtoEN, isWtoMN, weight)) # Define the ranges in fatJetMass - these will be used to define SB and SR J_mass.setRange("LSBrange", LOWMIN, LOWMAX) J_mass.setRange("HSBrange", HIGMIN, HIGMAX) J_mass.setRange("VRrange", LOWMAX, SIGMIN) J_mass.setRange("SRrange", SIGMIN, SIGMAX) J_mass.setBins(54) # Define the selection for the various categories (base + SR / LSBcut / HSBcut ) baseCut = leptCut + " && " + btagCut + "&&" + topVeto massCut = massVar + ">%d" % XBINMIN baseCut += " && " + massCut # Cuts SRcut = baseCut + " && %s>%d && %s<%d" % (J_mass.GetName(), SIGMIN, J_mass.GetName(), SIGMAX) LSBcut = baseCut + " && %s>%d && %s<%d" % (J_mass.GetName(), LOWMIN, J_mass.GetName(), LOWMAX) HSBcut = baseCut + " && %s>%d && %s<%d" % (J_mass.GetName(), HIGMIN, J_mass.GetName(), HIGMAX) SBcut = baseCut + " && ((%s>%d && %s<%d) || (%s>%d && %s<%d))" % (J_mass.GetName(), LOWMIN, J_mass.GetName(), LOWMAX, J_mass.GetName(), HIGMIN, J_mass.GetName(), HIGMAX) VRcut = baseCut + " && %s>%d && %s<%d" % (J_mass.GetName(), LOWMAX, J_mass.GetName(), SIGMIN) # Binning binsJmass = RooBinning(HBINMIN, HBINMAX) binsJmass.addUniform(HBINS, HBINMIN, HBINMAX) binsXmass = RooBinning(XBINMIN, XBINMAX) binsXmass.addUniform(binFact*XBINS, XBINMIN, XBINMAX) #*******************************************************# # # # Input files # # # #*******************************************************# # Import the files using TChains (separately for the bkg "classes" that we want to describe: here DY and VV+ST+TT) treeData = TChain(treeName) treeMC = TChain(treeName) treeVjet = TChain(treeName) treeVV = TChain(treeName) treeTop = TChain(treeName) # treeSign = {} # nevtSign = {} # Read data pd = getPrimaryDataset(triName) if len(pd)==0: raw_input("Warning: Primary Dataset not recognized, continue?") for i, s in enumerate(pd): treeData.Add(NTUPLEDIR + s + ".root") # Read V+jets backgrounds for i, s in enumerate(["WJetsToLNu_HT", "DYJetsToNuNu_HT", "DYJetsToLL_HT"]): for j, ss in enumerate(sample[s]['files']): treeVjet.Add(NTUPLEDIR + ss + ".root") # Read VV backgrounds for i, s in enumerate(["VV"]): for j, ss in enumerate(sample[s]['files']): treeVV.Add(NTUPLEDIR + ss + ".root") # Read Top backgrounds for i, s in enumerate(["ST", "TTbar"]): for j, ss in enumerate(sample[s]['files']): treeTop.Add(NTUPLEDIR + ss + ".root") # Sum all background MC treeMC.Add(treeVjet) treeMC.Add(treeVV) treeMC.Add(treeTop) # create a dataset to host data in sideband (using this dataset we are automatically blind in the SR!) setDataSB = RooDataSet("setDataSB", "setDataSB", variables, RooFit.Cut(SBcut), RooFit.WeightVar(weight), RooFit.Import(treeData)) setDataLSB = RooDataSet("setDataLSB", "setDataLSB", variables, RooFit.Import(setDataSB), RooFit.Cut(LSBcut), RooFit.WeightVar(weight)) setDataHSB = RooDataSet("setDataHSB", "setDataHSB", variables, RooFit.Import(setDataSB), RooFit.Cut(HSBcut), RooFit.WeightVar(weight)) # Observed data (WARNING, BLIND!) setDataSR = RooDataSet("setDataSR", "setDataSR", variables, RooFit.Cut(SRcut), RooFit.WeightVar(weight), RooFit.Import(treeData)) setDataVR = RooDataSet("setDataVR", "setDataVR", variables, RooFit.Cut(VRcut), RooFit.WeightVar(weight), RooFit.Import(treeData)) # Observed in the VV mass, just for plotting purposes # same for the bkg datasets from MC, where we just apply the base selections (not blind) setVjet = RooDataSet("setVjet", "setVjet", variables, RooFit.Cut(baseCut), RooFit.WeightVar(weight), RooFit.Import(treeVjet)) setVjetSB = RooDataSet("setVjetSB", "setVjetSB", variables, RooFit.Import(setVjet), RooFit.Cut(SBcut), RooFit.WeightVar(weight)) setVjetSR = RooDataSet("setVjetSR", "setVjetSR", variables, RooFit.Import(setVjet), RooFit.Cut(SRcut), RooFit.WeightVar(weight)) setVV = RooDataSet("setVV", "setVV", variables, RooFit.Cut(baseCut), RooFit.WeightVar(weight), RooFit.Import(treeVV)) setVVSB = RooDataSet("setVVSB", "setVVSB", variables, RooFit.Import(setVV), RooFit.Cut(SBcut), RooFit.WeightVar(weight)) setVVSR = RooDataSet("setVVSR", "setVVSR", variables, RooFit.Import(setVV), RooFit.Cut(SRcut), RooFit.WeightVar(weight)) setTop = RooDataSet("setTop", "setTop", variables, RooFit.Cut(baseCut), RooFit.WeightVar(weight), RooFit.Import(treeTop)) setTopSB = RooDataSet("setTopSB", "setTopSB", variables, RooFit.Import(setTop), RooFit.Cut(SBcut), RooFit.WeightVar(weight)) setTopSR = RooDataSet("setTopSR", "setTopSR", variables, RooFit.Import(setTop), RooFit.Cut(SRcut), RooFit.WeightVar(weight)) print " Data events SB: %.2f" % setDataSB.sumEntries() print " V+jets entries: %.2f" % setVjet.sumEntries() print " VV, VH entries: %.2f" % setVV.sumEntries() print " Top,ST entries: %.2f" % setTop.sumEntries() # the relative normalization of the varius bkg is taken from MC by counting all the events in the full fatJetMass range #coef = RooRealVar("coef", "coef", setVV.sumEntries()/setVjet.sumEntries(),0.,1.) coef_VV_Vjet = RooRealVar("coef2_1", "coef2_1", setVV.sumEntries()/setVjet.sumEntries(), 0., 1.) coef_Top_VVVjet = RooRealVar("coef3_21", "coef3_21", setTop.sumEntries()/(setVjet.sumEntries()+setVV.sumEntries()),0.,1.); coef_VV_Vjet.setConstant(True) coef_Top_VVVjet.setConstant(True) # Define entries entryVjet = RooRealVar("entryVjets", "V+jets normalization", setVjet.sumEntries(), 0., 1.e6) entryVV = RooRealVar("entryVV", "VV normalization", setVV.sumEntries(), 0., 1.e6) entryTop = RooRealVar("entryTop", "Top normalization", setTop.sumEntries(), 0., 1.e6) entrySB = RooRealVar("entrySB", "Data SB normalization", setDataSB.sumEntries(SBcut), 0., 1.e6) entrySB.setError(math.sqrt(entrySB.getVal())) entryLSB = RooRealVar("entryLSB", "Data LSB normalization", setDataSB.sumEntries(LSBcut), 0., 1.e6) entryLSB.setError(math.sqrt(entryLSB.getVal())) entryHSB = RooRealVar("entryHSB", "Data HSB normalization", setDataSB.sumEntries(HSBcut), 0., 1.e6) entryHSB.setError(math.sqrt(entryHSB.getVal())) #*******************************************************# # # # NORMALIZATION # # # #*******************************************************# # set reasonable ranges for J_mass and X_mass # these are used in the fit in order to avoid ROOFIT to look in regions very far away from where we are fitting J_mass.setRange("h_reasonable_range", LOWMIN, HIGMAX) X_mass.setRange("X_reasonable_range", XBINMIN, XBINMAX) # Set RooArgSets once for all, see https://root.cern.ch/phpBB3/viewtopic.php?t=11758 jetMassArg = RooArgSet(J_mass) #*******************************************************# # # # V+jets normalization # # # #*******************************************************# # Variables for V+jets constVjet = RooRealVar("constVjet", "slope of the exp", -0.020, -1., 0.) offsetVjet = RooRealVar("offsetVjet", "offset of the erf", 30., -50., 200.) widthVjet = RooRealVar("widthVjet", "width of the erf", 100., 1., 200.) offsetVjet.setConstant(True) a0Vjet = RooRealVar("a0Vjet", "width of the erf", -0.1, -5, 0) a1Vjet = RooRealVar("a1Vjet", "width of the erf", 0.6, 0, 5) a2Vjet = RooRealVar("a2Vjet", "width of the erf", -0.1, -1, 1) # Define V+jets model if fitFuncVjet == "ERFEXP": modelVjet = RooErfExpPdf("modelVjet", "error function for V+jets mass", J_mass, constVjet, offsetVjet, widthVjet) elif fitFuncVjet == "EXP": modelVjet = RooExponential("modelVjet", "exp for V+jets mass", J_mass, constVjet) elif fitFuncVjet == "POL": modelVjet = RooChebychev("modelVjet", "polynomial for V+jets mass", J_mass, RooArgList(a0Vjet, a1Vjet, a2Vjet)) elif fitFuncVjet == "POW": modelVjet = RooGenericPdf("modelVjet", "powerlaw for X mass", "@0^@1", RooArgList(J_mass, a0Vjet)) else: print " ERROR! Pdf", fitFuncVjet, "is not implemented for Vjets" exit() # fit to main bkg in MC (whole range) frVjet = modelVjet.fitTo(setVjet, RooFit.SumW2Error(True), RooFit.Range("h_reasonable_range"), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.Save(1), RooFit.PrintLevel(1 if VERBOSE else -1)) # integrals and number of events iSBVjet = modelVjet.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("LSBrange,HSBrange")) iLSBVjet = modelVjet.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("LSBrange")) iHSBVjet = modelVjet.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("HSBrange")) iSRVjet = modelVjet.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("SRrange")) iVRVjet = modelVjet.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("VRrange")) # Do not remove the following lines, integrals are computed here iALVjet = modelVjet.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg)) nSBVjet = iSBVjet.getVal()/iALVjet.getVal()*setVjet.sumEntries(SBcut) nLSBVjet = iLSBVjet.getVal()/iALVjet.getVal()*setVjet.sumEntries(LSBcut) nHSBVjet = iHSBVjet.getVal()/iALVjet.getVal()*setVjet.sumEntries(HSBcut) nSRVjet = iSRVjet.getVal()/iALVjet.getVal()*setVjet.sumEntries(SRcut) drawPlot("JetMass_Vjet", channel, J_mass, modelVjet, setVjet, binsJmass, frVjet) if VERBOSE: print "********** Fit result [JET MASS Vjets] *"+"*"*40, "\n", frVjet.Print(), "\n", "*"*80 #*******************************************************# # # # VV, VH normalization # # # #*******************************************************# # Variables for VV # Error function and exponential to model the bulk constVV = RooRealVar("constVV", "slope of the exp", -0.030, -0.1, 0.) offsetVV = RooRealVar("offsetVV", "offset of the erf", 90., 1., 300.) widthVV = RooRealVar("widthVV", "width of the erf", 50., 1., 100.) erfrVV = RooErfExpPdf("baseVV", "error function for VV jet mass", J_mass, constVV, offsetVV, widthVV) expoVV = RooExponential("baseVV", "error function for VV jet mass", J_mass, constVV) # gaussian for the V mass peak meanVV = RooRealVar("meanVV", "mean of the gaussian", 90., 60., 100.) sigmaVV = RooRealVar("sigmaVV", "sigma of the gaussian", 10., 6., 30.) fracVV = RooRealVar("fracVV", "fraction of gaussian wrt erfexp", 3.2e-1, 0., 1.) gausVV = RooGaussian("gausVV", "gaus for VV jet mass", J_mass, meanVV, sigmaVV) # gaussian for the H mass peak meanVH = RooRealVar("meanVH", "mean of the gaussian", 125., 100., 150.) sigmaVH = RooRealVar("sigmaVH", "sigma of the gaussian", 30., 5., 40.) fracVH = RooRealVar("fracVH", "fraction of gaussian wrt erfexp", 1.5e-2, 0., 1.) gausVH = RooGaussian("gausVH", "gaus for VH jet mass", J_mass, meanVH, sigmaVH) # Define VV model if fitFuncVV == "ERFEXPGAUS": modelVV = RooAddPdf("modelVV", "error function + gaus for VV jet mass", RooArgList(gausVV, erfrVV), RooArgList(fracVV)) elif fitFuncVV == "ERFEXPGAUS2": modelVV = RooAddPdf("modelVV", "error function + gaus + gaus for VV jet mass", RooArgList(gausVH, gausVV, erfrVV), RooArgList(fracVH, fracVV)) elif fitFuncVV == "EXPGAUS": modelVV = RooAddPdf("modelVV", "error function + gaus for VV jet mass", RooArgList(gausVV, expoVV), RooArgList(fracVV)) elif fitFuncVV == "EXPGAUS2": modelVV = RooAddPdf("modelVV", "error function + gaus + gaus for VV jet mass", RooArgList(gausVH, gausVV, expoVV), RooArgList(fracVH, fracVV)) else: print " ERROR! Pdf", fitFuncVV, "is not implemented for VV" exit() # fit to secondary bkg in MC (whole range) frVV = modelVV.fitTo(setVV, RooFit.SumW2Error(True), RooFit.Range("h_reasonable_range"), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.Save(1), RooFit.PrintLevel(1 if VERBOSE else -1)) # integrals and number of events iSBVV = modelVV.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("LSBrange,HSBrange")) iLSBVV = modelVV.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("LSBrange")) iHSBVV = modelVV.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("HSBrange")) iSRVV = modelVV.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("SRrange")) iVRVV = modelVV.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("VRrange")) # Do not remove the following lines, integrals are computed here iALVV = modelVV.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg)) nSBVV = iSBVV.getVal()/iALVV.getVal()*setVV.sumEntries(SBcut) nLSBVV = iLSBVV.getVal()/iALVV.getVal()*setVV.sumEntries(LSBcut) nHSBVV = iHSBVV.getVal()/iALVV.getVal()*setVV.sumEntries(HSBcut) nSRVV = iSRVV.getVal()/iALVV.getVal()*setVV.sumEntries(SRcut) rSBSRVV = nSRVV/nSBVV drawPlot("JetMass_VV", channel, J_mass, modelVV, setVV, binsJmass, frVV) if VERBOSE: print "********** Fit result [JET MASS VV] ****"+"*"*40, "\n", frVV.Print(), "\n", "*"*80 #*******************************************************# # # # Top, ST normalization # # # #*******************************************************# # Variables for Top # Error Function * Exponential to model the bulk constTop = RooRealVar("constTop", "slope of the exp", -0.030, -1., 0.) offsetTop = RooRealVar("offsetTop", "offset of the erf", 175.0, 50., 250.) widthTop = RooRealVar("widthTop", "width of the erf", 100.0, 1., 300.) gausTop = RooGaussian("baseTop", "gaus for Top jet mass", J_mass, offsetTop, widthTop) erfrTop = RooErfExpPdf("baseTop", "error function for Top jet mass", J_mass, constTop, offsetTop, widthTop) # gaussian for the W mass peak meanW = RooRealVar("meanW", "mean of the gaussian", 80., 70., 90.) sigmaW = RooRealVar("sigmaW", "sigma of the gaussian", 10., 2., 20.) fracW = RooRealVar("fracW", "fraction of gaussian wrt erfexp", 0.1, 0., 1.) gausW = RooGaussian("gausW", "gaus for W jet mass", J_mass, meanW, sigmaW) # gaussian for the Top mass peak meanT = RooRealVar("meanT", "mean of the gaussian", 175., 150., 200.) sigmaT = RooRealVar("sigmaT", "sigma of the gaussian", 12., 5., 50.) fracT = RooRealVar("fracT", "fraction of gaussian wrt erfexp", 0.1, 0., 1.) gausT = RooGaussian("gausT", "gaus for T jet mass", J_mass, meanT, sigmaT) # Define Top model if fitFuncTop == "ERFEXPGAUS2": modelTop = RooAddPdf("modelTop", "error function + gaus + gaus for Top jet mass", RooArgList(gausW, gausT, erfrTop), RooArgList(fracW, fracT)) elif fitFuncTop == "ERFEXPGAUS": modelTop = RooAddPdf("modelTop", "error function + gaus for Top jet mass", RooArgList(gausT, erfrTop), RooArgList(fracT)) elif fitFuncTop == "GAUS3": modelTop = RooAddPdf("modelTop", "gaus + gaus + gaus for Top jet mass", RooArgList(gausW, gausT, gausTop), RooArgList(fracW, fracT)) elif fitFuncTop == "GAUS2": modelTop = RooAddPdf("modelTop", "gaus + gaus for Top jet mass", RooArgList(gausT, gausTop), RooArgList(fracT)) elif fitFuncTop == "GAUS": modelTop = RooGaussian("modelTop", "gaus for Top jet mass", J_mass, offsetTop, widthTop) else: print " ERROR! Pdf", fitFuncTop, "is not implemented for Top" exit() # fit to secondary bkg in MC (whole range) frTop = modelTop.fitTo(setTop, RooFit.SumW2Error(True), RooFit.Range("h_reasonable_range"), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.Save(1), RooFit.PrintLevel(1 if VERBOSE else -1)) # integrals and number of events iSBTop = modelTop.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("LSBrange,HSBrange")) iLSBTop = modelTop.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("LSBrange")) iHSBTop = modelTop.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("HSBrange")) iSRTop = modelTop.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("SRrange")) iVRTop = modelTop.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("VRrange")) # Do not remove the following lines, integrals are computed here iALTop = modelTop.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg)) nSBTop = iSBTop.getVal()/iALTop.getVal()*setTop.sumEntries(SBcut) nLSBTop = iLSBTop.getVal()/iALTop.getVal()*setTop.sumEntries(LSBcut) nHSBTop = iHSBTop.getVal()/iALTop.getVal()*setTop.sumEntries(HSBcut) nSRTop = iSRTop.getVal()/iALTop.getVal()*setTop.sumEntries(SRcut) drawPlot("JetMass_Top", channel, J_mass, modelTop, setTop, binsJmass, frTop) if VERBOSE: print "********** Fit result [JET MASS TOP] ***"+"*"*40, "\n", frTop.Print(), "\n", "*"*80 #*******************************************************# # # # All bkg normalization # # # #*******************************************************# constVjet.setConstant(True) offsetVjet.setConstant(True) widthVjet.setConstant(True) a0Vjet.setConstant(True) a1Vjet.setConstant(True) a2Vjet.setConstant(True) constVV.setConstant(True) offsetVV.setConstant(True) widthVV.setConstant(True) meanVV.setConstant(True) sigmaVV.setConstant(True) fracVV.setConstant(True) meanVH.setConstant(True) sigmaVH.setConstant(True) fracVH.setConstant(True) constTop.setConstant(True) offsetTop.setConstant(True) widthTop.setConstant(True) meanW.setConstant(True) sigmaW.setConstant(True) fracW.setConstant(True) meanT.setConstant(True) sigmaT.setConstant(True) fracT.setConstant(True) # Final background model by adding the main+secondary pdfs (using 'coef': ratio of the secondary/main, from MC) model = RooAddPdf("model", "model", RooArgList(modelTop, modelVV, modelVjet), RooArgList(coef_Top_VVVjet, coef_VV_Vjet))#FIXME model.fixAddCoefRange("h_reasonable_range") # Extended fit model to data in SB # all the 3 sidebands (Low / High / the 2 combined) could be used # currently using the LOW+HIGH (the others are commented out) yieldLSB = RooRealVar("yieldLSB", "Lower SB normalization", 10, 0., 1.e6) yieldHSB = RooRealVar("yieldHSB", "Higher SB normalization", 10, 0., 1.e6) yieldSB = RooRealVar("yieldSB", "All SB normalization", 10, 0., 1.e6) #model_ext = RooExtendPdf("model_ext", "extended p.d.f", model, yieldLSB) #model_ext = RooExtendPdf("model_ext", "extended p.d.f", model, yieldHSB) model_ext = RooExtendPdf("model_ext", "extended p.d.f", model, yieldSB) #frMass = model_ext.fitTo(setDataSB, RooFit.ConditionalObservables(RooArgSet(J_mass)),RooFit.SumW2Error(True),RooFit.Extended(True),RooFit.Range("LSBrange"),RooFit.PrintLevel(-1)) #frMass = model_ext.fitTo(setDataSB, RooFit.ConditionalObservables(RooArgSet(J_mass)),RooFit.SumW2Error(True),RooFit.Extended(True),RooFit.Range("HSBrange"),RooFit.PrintLevel(-1)) #frMass = model_ext.fitTo(setDataSB, RooFit.ConditionalObservables(RooArgSet(J_mass)), RooFit.SumW2Error(True), RooFit.Extended(True), RooFit.Range("LSBrange,HSBrange"), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.PrintLevel(1 if VERBOSE else -1)) #print "********** Fit result [JET MASS DATA] **"+"*"*40 #print frMass.Print() #print "*"*80 # Calculate integral of the model obtained from the fit to data (fraction of PDF that is within a given region) #nSB = model_ext.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("LSBrange,HSBrange")) #nSB = model_ext.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("LSBrange")) #nSB = model_ext.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("HSBrange")) #nSR = model_ext.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("SRrange")) #nVR = model_ext.createIntegral(jetMassArg, RooFit.NormSet(jetMassArg), RooFit.Range("VRrange")) # scale the yieldSB from SB to SR using the ratio of the PDFs defined by the two integrals SRyield = RooFormulaVar("SRyield", "extrapolation to SR","(@0-@1*@3-@2*@4) * @5/@6 +@1*@7+@2*@8", RooArgList(entrySB, entryVV, entryTop, iSBVV, iSBTop, iSRVjet, iSBVjet, iSRVV, iSRTop)) VRyield = RooFormulaVar("VRyield", "extrapolation to VR","(@0-@1*@3-@2*@4) * @5/@6 +@1*@7+@2*@8", RooArgList(entrySB, entryVV, entryTop, iSBVV, iSBTop, iVRVjet, iSBVjet, iVRVV, iVRTop)) HSByield = RooFormulaVar("SRyield", "extrapolation to SR","(@0-@1*@3-@2*@4) * @5/@6 +@1*@7+@2*@8", RooArgList(entryLSB, entryVV, entryTop, iLSBVV, iLSBTop, iHSBVjet, iLSBVjet, iHSBVV, iHSBTop)) # RooFormulaVar SRyield("SRyield","extrapolation to SR","(@0/@1)*@2",RooArgList(*nSR,*nSB,yieldLowerSB)) # RooFormulaVar SRyield("SRyield","extrapolation to SR","(@0/@1)*@2",RooArgList(*nSR,*nSB,yieldHigherSB)) #SRyield = RooFormulaVar("SRyield", "extrapolation to SR","(@0/@1)*@2", RooArgList(nSR, nSB, entrySB)) bkgYield = SRyield.getVal() bkgYield_error = math.sqrt(SRyield.getPropagatedError(frVjet)**2 + SRyield.getPropagatedError(frVV)**2 + SRyield.getPropagatedError(frTop)**2 + (entrySB.getError()*rSBSRVV)**2) bkgNorm = entrySB.getVal() + SRyield.getVal() + VRyield.getVal() bkgYield_eig_norm = RooRealVar("predSR_eig_norm", "expected yield in SR", bkgYield, 0., 1.e6) bkgYieldExt = HSByield.getVal() drawPlot("JetMass", channel, J_mass, model, setDataSB, binsJmass, None, None, "", bkgNorm, True) print channel, "normalization = %.3f +/- %.3f, observed = %.0f" % (bkgYield, bkgYield_error, setDataSR.sumEntries() if not BLIND else -1) if VERBOSE: raw_input("Press Enter to continue...")
def alpha(channel): nElec = channel.count('e') nMuon = channel.count('m') nLept = nElec + nMuon nBtag = channel.count('b') # Channel-dependent settings # Background function. Semi-working options are: EXP, EXP2, EXPN, EXPTAIL if nLept == 0: treeName = 'SR' signName = 'XZh' colorVjet = sample['DYJetsToNuNu']['linecolor'] triName = "HLT_PFMET" leptCut = "0==0" topVeto = selection["TopVetocut"] massVar = "X_cmass" binFact = 1 #fitFunc = "EXP" #fitFunc = "EXP2" #fitFunc = "EXPN" #fitFunc = "EXPTAIL" fitFunc = "EXPN" if nBtag < 2 else "EXP" fitAltFunc = "EXPTAIL" if nBtag < 2 else "EXPTAIL" fitFuncVjet = "ERFEXP" if nBtag < 2 else "ERFEXP" fitFuncVV = "EXPGAUS" fitFuncTop = "GAUS2" elif nLept == 1: treeName = 'WCR' signName = 'XWh' colorVjet = sample['WJetsToLNu']['linecolor'] triName = "HLT_Ele" if nElec > 0 else "HLT_Mu" leptCut = "isWtoEN" if nElec > 0 else "isWtoMN" topVeto = selection["TopVetocut"] massVar = "X_mass" binFact = 2 if nElec > 0: fitFunc = "EXP" if nBtag < 2 else "EXP" fitAltFunc = "EXPTAIL" if nBtag < 2 else "EXPTAIL" else: fitFunc = "EXPTAIL" if nBtag < 2 else "EXP" fitAltFunc = "EXPN" if nBtag < 2 else "EXPTAIL" fitFuncVjet = "ERFEXP" if nBtag < 2 else "ERFEXP" fitFuncVV = "EXPGAUS" fitFuncTop = "GAUS3" if nBtag < 2 else "GAUS2" else: treeName = 'XZh' signName = 'XZh' colorVjet = sample['DYJetsToLL']['linecolor'] triName = "HLT_Ele" if nElec > 0 else "HLT_Mu" leptCut = "isZtoEE" if nElec > 0 else "isZtoMM" topVeto = "0==0" massVar = "X_mass" binFact = 5 if nElec > 0: fitFunc = "EXP" if nBtag < 2 else "EXP" fitAltFunc = "POW" if nBtag < 2 else "POW" else: fitFunc = "EXP" if nBtag < 2 else "EXP" fitAltFunc = "POW" if nBtag < 2 else "POW" fitFuncVjet = "ERFEXP" if nBtag < 2 else "EXP" fitFuncVV = "EXPGAUS2" fitFuncTop = "GAUS" btagCut = selection["2Btag"] if nBtag == 2 else selection["1Btag"] print "--- Channel", channel, "---" print " number of electrons:", nElec, " muons:", nMuon, " b-tags:", nBtag print " read tree:", treeName, "and trigger:", triName if ALTERNATIVE: print " using ALTERNATIVE fit functions" print "-"*11*2 # Silent RooFit RooMsgService.instance().setGlobalKillBelow(RooFit.FATAL) #*******************************************************# # # # Variables and selections # # # #*******************************************************# # Define all the variables from the trees that will be used in the cuts and fits # this steps actually perform a "projection" of the entire tree on the variables in thei ranges, so be careful once setting the limits X_mass = RooRealVar( massVar, "m_{X}" if nLept > 0 else "m_{T}^{X}", XBINMIN, XBINMAX, "GeV") J_mass = RooRealVar( "fatjet1_prunedMassCorr", "corrected pruned mass", HBINMIN, HBINMAX, "GeV") CSV1 = RooRealVar( "fatjet1_CSVR1", "", -1.e99, 1.e4 ) CSV2 = RooRealVar( "fatjet1_CSVR2", "", -1.e99, 1.e4 ) nBtag = RooRealVar( "fatjet1_nBtag", "", 0., 4 ) CSVTop = RooRealVar( "bjet1_CSVR", "", -1.e99, 1.e4 ) isZtoEE = RooRealVar("isZtoEE", "", 0., 2 ) isZtoMM = RooRealVar("isZtoMM", "", 0., 2 ) isWtoEN = RooRealVar("isWtoEN", "", 0., 2 ) isWtoMN = RooRealVar("isWtoMN", "", 0., 2 ) weight = RooRealVar( "eventWeightLumi", "", -1.e9, 1. ) # Define the RooArgSet which will include all the variables defined before # there is a maximum of 9 variables in the declaration, so the others need to be added with 'add' variables = RooArgSet(X_mass, J_mass, CSV1, CSV2, nBtag, CSVTop) variables.add(RooArgSet(isZtoEE, isZtoMM, isWtoEN, isWtoMN, weight)) # Define the ranges in fatJetMass - these will be used to define SB and SR J_mass.setRange("LSBrange", LOWMIN, LOWMAX) J_mass.setRange("HSBrange", HIGMIN, HIGMAX) J_mass.setRange("VRrange", LOWMAX, SIGMIN) J_mass.setRange("SRrange", SIGMIN, SIGMAX) J_mass.setBins(54) # Define the selection for the various categories (base + SR / LSBcut / HSBcut ) baseCut = leptCut + " && " + btagCut + "&&" + topVeto massCut = massVar + ">%d" % XBINMIN baseCut += " && " + massCut # Cuts SRcut = baseCut + " && %s>%d && %s<%d" % (J_mass.GetName(), SIGMIN, J_mass.GetName(), SIGMAX) LSBcut = baseCut + " && %s>%d && %s<%d" % (J_mass.GetName(), LOWMIN, J_mass.GetName(), LOWMAX) HSBcut = baseCut + " && %s>%d && %s<%d" % (J_mass.GetName(), HIGMIN, J_mass.GetName(), HIGMAX) SBcut = baseCut + " && ((%s>%d && %s<%d) || (%s>%d && %s<%d))" % (J_mass.GetName(), LOWMIN, J_mass.GetName(), LOWMAX, J_mass.GetName(), HIGMIN, J_mass.GetName(), HIGMAX) VRcut = baseCut + " && %s>%d && %s<%d" % (J_mass.GetName(), LOWMAX, J_mass.GetName(), SIGMIN) # Binning binsJmass = RooBinning(HBINMIN, HBINMAX) binsJmass.addUniform(HBINS, HBINMIN, HBINMAX) binsXmass = RooBinning(XBINMIN, XBINMAX) binsXmass.addUniform(binFact*XBINS, XBINMIN, XBINMAX) #*******************************************************# # # # Input files # # # #*******************************************************# # Import the files using TChains (separately for the bkg "classes" that we want to describe: here DY and VV+ST+TT) treeData = TChain(treeName) treeMC = TChain(treeName) treeVjet = TChain(treeName) treeVV = TChain(treeName) treeTop = TChain(treeName) # treeSign = {} # nevtSign = {} # Read data print "read data start" pd = getPrimaryDataset(triName) if len(pd)==0: raw_input("Warning: Primary Dataset not recognized, continue?") for i, s in enumerate(pd): treeData.Add(NTUPLEDIR + s + ".root") # Read V+jets backgrounds print "read V+jet start" for i, s in enumerate(["WJetsToLNu_HT", "DYJetsToNuNu_HT", "DYJetsToLL_HT"]): for j, ss in enumerate(sample[s]['files']): treeVjet.Add(NTUPLEDIR + ss + ".root") # Read VV backgrounds print "read VV start" for i, s in enumerate(["VV"]): for j, ss in enumerate(sample[s]['files']): treeVV.Add(NTUPLEDIR + ss + ".root") # Read Top backgrounds print "read Top start" for i, s in enumerate(["ST", "TTbar"]): for j, ss in enumerate(sample[s]['files']): treeTop.Add(NTUPLEDIR + ss + ".root") # Sum all background MC treeMC.Add(treeVjet) treeMC.Add(treeVV) treeMC.Add(treeTop) # print "prepare SB dataset" # create a dataset to host data in sideband (using this dataset we are automatically blind in the SR!) # setDataSB = RooDataSet("setDataSB", "setDataSB", variables, RooFit.Cut(SBcut), RooFit.WeightVar(weight), RooFit.Import(treeData)) # setDataLSB = RooDataSet("setDataLSB", "setDataLSB", variables, RooFit.Import(setDataSB), RooFit.Cut(LSBcut), RooFit.WeightVar(weight)) # setDataHSB = RooDataSet("setDataHSB", "setDataHSB", variables, RooFit.Import(setDataSB), RooFit.Cut(HSBcut), RooFit.WeightVar(weight)) # print "prepare SR dataset" # Observed data (WARNING, BLIND!) # setDataSR = RooDataSet("setDataSR", "setDataSR", variables, RooFit.Cut(SRcut), RooFit.WeightVar(weight), RooFit.Import(treeData)) # setDataVR = RooDataSet("setDataVR", "setDataVR", variables, RooFit.Cut(VRcut), RooFit.WeightVar(weight), RooFit.Import(treeData)) # Observed in the VV mass, just for plotting purposes print "prepare MC dataset" # same for the bkg datasets from MC, where we just apply the base selections (not blind) setVjet = RooDataSet("setVjet", "setVjet", variables, RooFit.Cut(baseCut), RooFit.WeightVar(weight), RooFit.Import(treeVjet)) setVjetSB = RooDataSet("setVjetSB", "setVjetSB", variables, RooFit.Import(setVjet), RooFit.Cut(SBcut), RooFit.WeightVar(weight)) setVjetSR = RooDataSet("setVjetSR", "setVjetSR", variables, RooFit.Import(setVjet), RooFit.Cut(SRcut), RooFit.WeightVar(weight)) print "finish Vjet dataset" # setVV = RooDataSet("setVV", "setVV", variables, RooFit.Cut(baseCut), RooFit.WeightVar(weight), RooFit.Import(treeVV)) # setVVSB = RooDataSet("setVVSB", "setVVSB", variables, RooFit.Import(setVV), RooFit.Cut(SBcut), RooFit.WeightVar(weight)) # setVVSR = RooDataSet("setVVSR", "setVVSR", variables, RooFit.Import(setVV), RooFit.Cut(SRcut), RooFit.WeightVar(weight)) # print "finish VV dataset" # setTop = RooDataSet("setTop", "setTop", variables, RooFit.Cut(baseCut), RooFit.WeightVar(weight), RooFit.Import(treeTop)) # setTopSB = RooDataSet("setTopSB", "setTopSB", variables, RooFit.Import(setTop), RooFit.Cut(SBcut), RooFit.WeightVar(weight)) # setTopSR = RooDataSet("setTopSR", "setTopSR", variables, RooFit.Import(setTop), RooFit.Cut(SRcut), RooFit.WeightVar(weight)) # print "finish Top dataset" # print " Data events SB: %.2f" % setDataSB.sumEntries() print " V+jets entries: %.2f" % setVjet.sumEntries() # print " VV, VH entries: %.2f" % setVV.sumEntries() # print " Top,ST entries: %.2f" % setTop.sumEntries() # the relative normalization of the varius bkg is taken from MC by counting all the events in the full fatJetMass range #coef = RooRealVar("coef", "coef", setVV.sumEntries()/setVjet.sumEntries(),0.,1.) # coef_VV_Vjet = RooRealVar("coef2_1", "coef2_1", setVV.sumEntries()/setVjet.sumEntries(), 0., 1.) # coef_Top_VVVjet = RooRealVar("coef3_21", "coef3_21", setTop.sumEntries()/(setVjet.sumEntries()+setVV.sumEntries()),0.,1.); # coef_VV_Vjet.setConstant(True) # coef_Top_VVVjet.setConstant(True) # Define entries entryVjet = RooRealVar("entryVjets", "V+jets normalization", setVjet.sumEntries(), 0., 1.e6) # entryVV = RooRealVar("entryVV", "VV normalization", setVV.sumEntries(), 0., 1.e6) # entryTop = RooRealVar("entryTop", "Top normalization", setTop.sumEntries(), 0., 1.e6) # entrySB = RooRealVar("entrySB", "Data SB normalization", setDataSB.sumEntries(SBcut), 0., 1.e6) # entrySB.setError(math.sqrt(entrySB.getVal())) # entryLSB = RooRealVar("entryLSB", "Data LSB normalization", setDataSB.sumEntries(LSBcut), 0., 1.e6) # entryLSB.setError(math.sqrt(entryLSB.getVal())) # entryHSB = RooRealVar("entryHSB", "Data HSB normalization", setDataSB.sumEntries(HSBcut), 0., 1.e6) # entryHSB.setError(math.sqrt(entryHSB.getVal())) #*******************************************************# # # # NORMALIZATION # # # #*******************************************************# # set reasonable ranges for J_mass and X_mass # these are used in the fit in order to avoid ROOFIT to look in regions very far away from where we are fitting J_mass.setRange("h_reasonable_range", LOWMIN, HIGMAX) X_mass.setRange("X_reasonable_range", XBINMIN, XBINMAX) # Set RooArgSets once for all, see https://root.cern.ch/phpBB3/viewtopic.php?t=11758 jetMassArg = RooArgSet(J_mass) ############################## # # # Yu-hsiang test region # # # ############################## # test it in the channel "XZhnnb" print "the channel is", channel if channel == "XZhnnb": # ------------------------------------------------------------------- # draw the setVjet Jmass_frame = J_mass.frame(RooFit.Title("test frame")) setVjet.plotOn(Jmass_frame) # ------------------------------------------------------------------- # use a PDF to fit the dataset print "fitFuncVjet is", fitFuncVjet constVjet_value_initial = -0.020 offsetVjet_value_initial = 30. widthVjet_value_initial = 100. constVjet_test = RooRealVar("constVjet_test", "slope of the exp", constVjet_value_initial , -1., 0.) offsetVjet_test = RooRealVar("offsetVjet_test", "offset of the erf", offsetVjet_value_initial, -50., 200.) widthVjet_test = RooRealVar("widthVjet_test", "width of the erf", widthVjet_value_initial, 1., 200.) modelVjet_test = RooErfExpPdf("modelVjet_test", "error function for V+jets mass", J_mass, constVjet_test, offsetVjet_test, widthVjet_test) # constVjet_test.Print() # offsetVjet_test.Print() # widthVjet_test.Print() # constVjet_test.setConstant(True) # offsetVjet_test.setConstant(True) # widthVjet_test.setConstant(True) frVjet_test = modelVjet_test.fitTo(setVjet, RooFit.SumW2Error(True), RooFit.Range("h_reasonable_range"), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.Save(1), RooFit.PrintLevel(1 if VERBOSE else -1)) # constVjet_test.Print() # offsetVjet_test.Print() # widthVjet_test.Print() constVjet_value_fit_MC = constVjet_test.getVal() offsetVjet_value_fit_MC = offsetVjet_test.getVal() widthVjet_value_fit_MC = widthVjet_test.getVal() print "constVjet_value_fit_MC:", constVjet_value_fit_MC, "offsetVjet_value_fit_MC:",offsetVjet_value_fit_MC,"widthVjet_value_fit_MC:",widthVjet_value_fit_MC modelVjet_test.plotOn(Jmass_frame,RooFit.LineColor(4)) # ------------------------------------------------------------------- # use the shape of fit to generate the psudo-data Entries_pseudo_data = setVjet.sumEntries() # Entries_pseudo_data = 502 # Entries_pseudo_data = 5021 pseudo_data = modelVjet_test.generate(RooArgSet(J_mass),Entries_pseudo_data ) # pseudo_data = modelVjet_test.generate(RooArgSet(J_mass),setVjet.sumEntries()) # pseudo_data = modelVjet_test.generate(RooArgSet(J_mass),502 ) # pseudo_data = modelVjet_test.generate(RooArgSet(J_mass),5021 ) # pseudo_data.Print("v") Jmass_frame2 = J_mass.frame(RooFit.Title("test frame2")) pseudo_data.plotOn(Jmass_frame2) modelVjet_test.plotOn(Jmass_frame2,RooFit.LineColor(4)) # ------------------------------------------------------------------- # make another dataset that remove the signal region pseudo_data_SB = RooDataSet("pseudo_data_SB", "pseudo_data_SB", RooArgSet(J_mass), RooFit.Import(pseudo_data), RooFit.Cut("fatjet1_prunedMassCorr<65 || fatjet1_prunedMassCorr>135") ) pseudo_data_SB.plotOn(Jmass_frame2,RooFit.LineColor(2)) # ------------------------------------------------------------------- # use another PDF to fit the pseudo-data in SB only constVjet_test2 = RooRealVar("constVjet_test2", "slope of the exp", constVjet_value_fit_MC , -1., 0.) offsetVjet_test2 = RooRealVar("offsetVjet_test2", "offset of the erf", offsetVjet_value_fit_MC , -50., 200.) widthVjet_test2 = RooRealVar("widthVjet_test2", "width of the erf", widthVjet_value_fit_MC , 1., 200.) modelVjet_test2 = RooErfExpPdf("modelVjet_test2", "error function for V+jets mass", J_mass, constVjet_test2, offsetVjet_test2, widthVjet_test2) frVjet_test2 = modelVjet_test2.fitTo(pseudo_data_SB, RooFit.SumW2Error(True), RooFit.Range("LSBrange,HSBrange"), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.Save(1), RooFit.PrintLevel(1 if VERBOSE else -1)) # frVjet_test2 = modelVjet_test2.fitTo(pseudo_data_SB, RooFit.SumW2Error(True), RooFit.Range("h_reasonable_range"), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.Save(1), RooFit.PrintLevel(1 if VERBOSE else -1)) constVjet_value_fit_pseudo_data_SB = constVjet_test2.getVal() offsetVjet_value_fit_pseudo_data_SB = offsetVjet_test2.getVal() widthVjet_value_fit_pseudo_data_SB = widthVjet_test2.getVal() print "constVjet_value_fit_pseudo_data_SB:", constVjet_value_fit_pseudo_data_SB, "offsetVjet_value_fit_pseudo_data_SB:",offsetVjet_value_fit_pseudo_data_SB,"widthVjet_value_fit_pseudo_data_SB:",widthVjet_value_fit_pseudo_data_SB Jmass_frame3 = J_mass.frame(RooFit.Title("test frame3, fit the pseudo-data in SB only")) pseudo_data_SB.plotOn(Jmass_frame3) modelVjet_test2.plotOn(Jmass_frame3,RooFit.LineColor(4),RooFit.Range("h_reasonable_range")) # ------------------------------------------------------------------- # calculate the Gen_value, the Fit_value and the Bias= ( Fit_value - Gen_value)/Gen_value iGen_value = modelVjet_test.createIntegral(RooArgSet(J_mass), RooFit.Range("VRrange,SRrange")) print "iGen_value:", iGen_value.getVal() iFit_value = modelVjet_test2.createIntegral(RooArgSet(J_mass), RooFit.Range("VRrange,SRrange")) print "iFit_value:", iFit_value.getVal() Bias_value = ( iFit_value.getVal() - iGen_value.getVal() ) / iGen_value.getVal() print "Bias_value of VR+SR:", Bias_value # -------------- iGen_value = modelVjet_test.createIntegral(RooArgSet(J_mass), RooFit.Range("SRrange")) print "iGen_value:", iGen_value.getVal() iFit_value = modelVjet_test2.createIntegral(RooArgSet(J_mass), RooFit.Range("SRrange")) print "iFit_value:", iFit_value.getVal() Bias_value = ( iFit_value.getVal() - iGen_value.getVal() ) / iGen_value.getVal() print "Bias_value of SR:", Bias_value # iGen_value = modelVjet_test.createIntegral(RooArgSet(J_mass),RooFit.NormSet(RooArgSet(J_mass)), RooFit.Range("VRrange,SRrange")) # print "iGen_value:", iGen_value.getVal() # iGen_value = modelVjet_test.createIntegral(RooArgSet(J_mass),RooFit.NormSet(RooArgSet(J_mass)), RooFit.Range("VRrange,SRrange")) # print "iGen_value:", iGen_value.getVal() # iGen_value = modelVjet_test.createIntegral(RooArgSet(J_mass), RooFit.Range("h_reasonable_range")) # print "iGen_value:", iGen_value.getVal() # iGen_value = modelVjet_test.createIntegral(RooArgSet(J_mass)) # print "iGen_value:", iGen_value.getVal() # ------------------------------------------------------------------- # repeat thousand times to see bias distribution h_Bias = TH1D("h_Bias","h_Bias",80,-1,1); Jmass_frame4 = J_mass.frame(RooFit.Title("test frame4")) times_max = 50000 constVjet_test.setConstant(True) offsetVjet_test.setConstant(True) widthVjet_test.setConstant(True) constVjet_test3 = RooRealVar("constVjet_test3", "slope of the exp", constVjet_value_fit_MC , -1., 0.) offsetVjet_test3 = RooRealVar("offsetVjet_test3", "offset of the erf", offsetVjet_value_fit_MC , -50., 200.) widthVjet_test3 = RooRealVar("widthVjet_test3", "width of the erf", widthVjet_value_fit_MC , 1., 200.) for times in range(0,times_max): # inside loop # print "times:", times if times % 10 == 0 : print "Processing times:", times+1 ,"of", times_max # generate pseudo-data # n_1_prime = gRandom->Poisson(n_1); Entries_pseudo_data_fluc = gRandom.Poisson( Entries_pseudo_data ) # print "Entries_pseudo_data:", Entries_pseudo_data # print "Entries_pseudo_data_fluc:", Entries_pseudo_data_fluc # pseudo_data2 = modelVjet_test.generate(RooArgSet(J_mass),Entries_pseudo_data ) pseudo_data2 = modelVjet_test.generate(RooArgSet(J_mass),Entries_pseudo_data_fluc ) # pseudo_data2.plotOn(Jmass_frame3,RooFit.LineColor(4),RooFit.Range("h_reasonable_range")) # take out VR+SR pseudo_data_SB2 = RooDataSet("pseudo_data_SB2", "pseudo_data_SB2", RooArgSet(J_mass), RooFit.Import(pseudo_data2), RooFit.Cut("fatjet1_prunedMassCorr<65 || fatjet1_prunedMassCorr>135") ) # use other PDF to fit # print "constVjet_value_fit_MC:",constVjet_value_fit_MC constVjet_test3.setVal(constVjet_value_fit_MC) offsetVjet_test3.setVal(offsetVjet_value_fit_MC) widthVjet_test3.setVal(widthVjet_value_fit_MC) modelVjet_test3 = RooErfExpPdf("modelVjet_test3", "error function for V+jets mass", J_mass, constVjet_test3, offsetVjet_test3, widthVjet_test3) frVjet_test3 = modelVjet_test3.fitTo(pseudo_data_SB2, RooFit.SumW2Error(True), RooFit.Range("LSBrange,HSBrange"), RooFit.Strategy(2), RooFit.Minimizer("Minuit2"), RooFit.Save(1), RooFit.PrintLevel(1 if VERBOSE else -1)) # calculate the bias iGen_value2 = modelVjet_test.createIntegral(jetMassArg,RooFit.NormSet(jetMassArg), RooFit.Range("SRrange")) # print "iGen_value2:", iGen_value2.getVal() iFit_value2 = modelVjet_test3.createIntegral(jetMassArg,RooFit.NormSet(jetMassArg), RooFit.Range("SRrange")) # print "iFit_value2:", iFit_value2.getVal() Bias_value2 = ( iFit_value2.getVal() - iGen_value2.getVal() ) / iGen_value2.getVal() # print "Bias_value2 of VR+SR:", Bias_value2 h_Bias.Fill(Bias_value2) # ------------------------------------------------------------------- # plot and save Save_Dir = "/afs/cern.ch/user/y/yuchang/www/jacopo_plotsAlpha/yu_hsiang_bias_study" c_test = TCanvas("test","test draw",800,600) c_test.cd() Jmass_frame.Draw() c_test.SaveAs(Save_Dir+"/"+"VJet_MC_fit_get_shape.pdf") c_test2 = TCanvas("test2","test draw 2",800,600) c_test2.cd() Jmass_frame2.Draw() c_test2.SaveAs(Save_Dir+"/"+"use_shape_to_generate_pseudo_data.pdf") # c_test2.SaveAs(Save_Dir+"/"+"use_shape_to_generate_pseudo_data_test.pdf") c_test3 = TCanvas("test3","test draw 3",800,600) c_test3.cd() Jmass_frame3.Draw() c_test3.SaveAs(Save_Dir+"/"+"fit_pseudo_data_in_SB_only.pdf") c_test4 = TCanvas("test4","test draw 4",800,600) c_test4.cd() h_Bias.Draw() c_test4.SaveAs(Save_Dir+"/"+"h_Bias.pdf")
one = const(1.) zero = const(0.) tau = Inverse('tau', 'tau', gamma) # tauk = Inverse('tauk', 'tauk', kgamma) ## acceptance spline_knots = [0.5, 1.0, 1.5, 2.0, 3.0, 12.0] spline_coeffs = [ 0.03902e-01, 7.32741e-01, 9.98736e-01, 1.16514e+00, 1.25167e+00, 1.28624e+00 ] assert (len(spline_knots) == len(spline_coeffs)) # knot binning mode = "Bs2DsPi" knotbinning = RooBinning(time.getMin(), time.getMax(), '{}_knotbinning'.format(mode)) for v in spline_knots: knotbinning.addBoundary(v) knotbinning.removeBoundary(time.getMin()) knotbinning.removeBoundary(time.getMax()) oldbinning, lo, hi = time.getBinning(), time.getMin(), time.getMax() time.setBinning(knotbinning, '{}_knotbinning'.format(mode)) time.setBinning(oldbinning) time.setRange(lo, hi) del knotbinning, oldbinning, lo, hi # knot coefficients coefflist = RooArgList() for i, v in enumerate(spline_coeffs): coefflist.add(const(v)) i = len(spline_coeffs)
def rooFit108(): print ">>> setup model - a B decay with mixing..." dt = RooRealVar("dt","dt",-20,20) dm = RooRealVar("dm","dm",0.472) tau = RooRealVar("tau","tau",1.547) w = RooRealVar("w","mistag rate",0.1) dw = RooRealVar("dw","delta mistag rate",0.) # Build categories - possible values states # https://root.cern/doc/v610/classRooCategory.html mixState = RooCategory("mixState","B0/B0bar mixing state") mixState.defineType("mixed",-1) mixState.defineType("unmixed",1) tagFlav = RooCategory("tagFlav","Flavour of the tagged B0") tagFlav.defineType("B0",1) tagFlav.defineType("B0bar",-1) # Build a gaussian resolution model dterr = RooRealVar("dterr","dterr",0.1,1.0) bias1 = RooRealVar("bias1","bias1",0) sigma1 = RooRealVar("sigma1","sigma1",0.1) gm1 = RooGaussModel("gm1","gauss model 1",dt,bias1,sigma1) # Construct Bdecay (x) gauss # https://root.cern/doc/v610/classRooBMixDecay.html bmix = RooBMixDecay("bmix","decay",dt,mixState,tagFlav,tau,dm,w,dw,gm1,RooBMixDecay.DoubleSided) print ">>> sample data from data..." data = bmix.generate(RooArgSet(dt,mixState,tagFlav),2000) # RooDataSet print ">>> show dt distribution with custom binning..." # Make plot of dt distribution of data in range (-15,15) with fine binning for dt>0 # and coarse binning for dt<0 tbins = RooBinning(-15,15) # Create binning object with range (-15,15) tbins.addUniform(60,-15,0) # Add 60 bins with uniform spacing in range (-15,0) tbins.addUniform(15,0,15) # Add 15 bins with uniform spacing in range (0,15) dtframe = dt.frame(Range(-15,15),Title("dt distribution with custom binning")) # RooPlot data.plotOn(dtframe,Binning(tbins)) bmix.plotOn(dtframe) # NB: Note that bin density for each bin is adjusted to that of default frame # binning as shown in Y axis label (100 bins --> Events/0.4*Xaxis-dim) so that # all bins represent a consistent density distribution print ">>> plot mixstate asymmetry with custom binning..." # Make plot of dt distribution of data asymmetry in 'mixState' with variable binning abins = RooBinning(-10,10) # Create binning object with range (-10,10) abins.addBoundary(0) # Add boundaries at 0 abins.addBoundaryPair(1) # Add boundaries at (-1,1) abins.addBoundaryPair(2) # Add boundaries at (-2,2) abins.addBoundaryPair(3) # Add boundaries at (-3,3) abins.addBoundaryPair(4) # Add boundaries at (-4,4) abins.addBoundaryPair(6) # Add boundaries at (-6,6) aframe = dt.frame(Range(-10,10),Title("MixState asymmetry distribution with custom binning")) # RooPlot # Plot mixState asymmetry of data with specified customg binning data.plotOn(aframe,Asymmetry(mixState),Binning(abins)) # Plot corresponding property of pdf bmix.plotOn(aframe,Asymmetry(mixState)) # Adjust vertical range of plot to sensible values for an asymmetry aframe.SetMinimum(-1.1) aframe.SetMaximum( 1.1) # NB: For asymmetry distributions no density corrects are needed (and are thus not applied) print "\n>>> draw on canvas..." canvas = TCanvas("canvas","canvas",100,100,1400,600) canvas.Divide(2) canvas.cd(1) gPad.SetLeftMargin(0.15); gPad.SetRightMargin(0.02) dtframe.GetYaxis().SetLabelOffset(0.008) dtframe.GetYaxis().SetTitleOffset(1.6) dtframe.GetYaxis().SetTitleSize(0.045) dtframe.GetXaxis().SetTitleSize(0.045) dtframe.Draw() canvas.cd(2) gPad.SetLeftMargin(0.15); gPad.SetRightMargin(0.02) aframe.GetYaxis().SetLabelOffset(0.008) aframe.GetYaxis().SetTitleOffset(1.6) aframe.GetYaxis().SetTitleSize(0.045) aframe.GetXaxis().SetTitleSize(0.045) aframe.Draw() canvas.SaveAs("rooFit108.png")