def generate(histList, varName, varLow, varHigh, histSig="", weightSig=0.): """ Generate toy data @param histList List of histograms @param varname Variable name to use @param varLow Lower edge of left bin @param varHigh Upper edge of right bin @param histSig Optional signal histogram @param weightSig Optional signal weight """ testHist_pred = TH1D() for (iHist, hist) in enumerate(histList): if not iHist: testHist_pred = hist.Clone("hPRED") else: testHist_pred.Add(hist) testHist_pred_ds = TH1D("hPSDATA", "hPSDATA", testHist_pred.GetNbinsX(), testHist_pred.GetXaxis().GetBinLowEdge(1), testHist_pred.GetXaxis().GetBinUpEdge(testHist_pred.GetNbinsX())) nEvents_pred = int(testHist_pred.Integral()) print "nEvents_pred = %d" % nEvents_pred var = RooRealVar(varName, varName, varLow, varHigh) dh_pred = RooDataHist("dhPSDATA", "dhPSDATA", RooArgList(var), RooFit.Import(testHist_pred)) ph_pred = RooHistPdf("phPSDATA", "phPSDATA", RooArgSet(var), dh_pred) ds_pred = ph_pred.generate(RooArgSet(var), nEvents_pred) testHist_pred_ds = ds_pred.fillHistogram(testHist_pred_ds, RooArgList(var)) return testHist_pred_ds
def performFitInLeptonAbsEta(data_histogram, signal_histogram, bkg1_histogram, bkg2_histogram): N_Data = data_histogram.Integral() N_signal = signal_histogram.Integral() N_bkg1 = bkg1_histogram.Integral() N_bkg2 = bkg2_histogram.Integral() leptonAbsEta = RooRealVar("leptonAbsEta", "leptonAbsEta", 0., 3.) variables = RooArgList() variables.add(leptonAbsEta) variable_set = RooArgSet() variable_set.add(leptonAbsEta) lowerBound = 0 upperBound = N_Data * 2 data_RooDataHist = RooDataHist("data", "dataset with leptonAbsEta", variables, data_histogram) signal_RooDataHist = RooDataHist("rh_signal", "signal", variables, signal_histogram) bkg1_RooDataHist = RooDataHist("rh_bkg1", "bkg1", variables, bkg1_histogram) bkg2_RooDataHist = RooDataHist("rh_bkg2", "bkg2", variables, bkg2_histogram) signal_RooHistPdf = RooHistPdf("pdf_signal", "Signal PDF", variable_set, signal_RooDataHist, 0) signal_RooHistPdf = RooHistPdf("pdf_signal", "Signal PDF", variable_set, signal_RooDataHist, 0)
def generate_hist(self, hist, varname, n): _var = RooRealVar(varname, varname, hist.GetMean()) _dh = RooDataHist("dh", "dh", RooArgList(_var), hist) _pdf = RooHistPdf("pdf", "pdf", RooArgSet(_var), _dh) _ds = _pdf.generateBinned(RooArgSet(_var), n) _h = _ds.createHistogram('hist', _var) #_h.Draw() #raw_input('press <enter> to continue...') return copy.deepcopy(_h)
def makeHistPdf(hist, ws, x): theVars = RooArgList(x) v = RooArgSet(x) dataHist = RooDataHist(hist.GetName() + '_dh', 'dataHist', theVars, hist) hpdf = RooHistPdf(hist.GetName() + '_pdf', 'hist pdf', v, dataHist) getattr(ws, 'import')(hpdf) return hpdf
def get_roofit_model( histograms, fit_boundaries, name = 'model' ): data_label = 'data' samples = sorted( histograms.keys() ) samples.remove( data_label ) roofit_histograms = {} roofit_pdfs = {} roofit_variables = {} variables = RooArgList() variable_set = RooArgSet() fit_variable = RooRealVar( name , name, fit_boundaries[0], fit_boundaries[1] ) variables.add( fit_variable ) variable_set.add( fit_variable ) roofit_histograms[data_label] = RooDataHist( data_label, data_label, variables, histograms[data_label] ) pdf_arglist = RooArgList() variable_arglist = RooArgList() N_total = histograms[data_label].Integral() * 2 N_min = 0 for sample in samples: roofit_histogram = RooDataHist( sample, sample, variables, histograms[sample] ) roofit_histograms[sample] = roofit_histogram roofit_pdf = RooHistPdf ( 'pdf' + sample, 'pdf' + sample, variable_set, roofit_histogram, 0 ) roofit_pdfs[sample] = roofit_pdf roofit_variable = RooRealVar( sample, "number of " + sample + " events", histograms[sample].Integral(), N_min, N_total, "event" ) roofit_variables[sample] = roofit_variable pdf_arglist.add( roofit_pdf ) variable_arglist.add( roofit_variable ) model = RooAddPdf( name, name, pdf_arglist, variable_arglist ) return model, roofit_histograms, fit_variable
def _make_underlying_model(self): self.pdfs = {} self.yields = {} # yields are plain floats self.ryields = {} # keep track of roofit objects for memory management nbins, xmin, xmax = self.plot.histos[0].GetBinning() self.xvar = RooRealVar("x", "x", xmin, xmax) self.xvar.setBins(nbins) self.pdfs = {} self.hists = [] pdfs = RooArgList() yields = RooArgList() for compname, comp in self.plot.histosDict.iteritems(): if comp.weighted.Integral() == 0: continue assert (isinstance(comp, Histogram)) hist = RooDataHist(compname, compname, RooArgList(self.xvar), comp.weighted) SetOwnership(hist, False) # self.hists.append(hist) pdf = RooHistPdf(compname, compname, RooArgSet(self.xvar), hist) self.pdfs[compname] = pdf # self.pdfs[compname].Print() pdfs.add(pdf) nevts = comp.Integral(xmin=xmin, xmax=xmax) nmin = min(0, nevts * (1 - comp.uncertainty)) nmax = nevts * (1 + comp.uncertainty) theyield = RooRealVar('n{}'.format(compname), 'n{}'.format(compname), nevts, nmin, nmax) self.ryields[compname] = theyield self.yields[compname] = nevts yields.add(theyield) self.underlying_model = RooAddPdf('model', 'model', pdfs, yields)
def fit(self, save_to, signal_name=None, fix_p3=False, fit_range=[300., 1200.], fit_strategy=1): # Run a RooFit fit # Create background PDF p1 = RooRealVar('p1','p1',args.p1,0.,100.) p2 = RooRealVar('p2','p2',args.p2,0.,60.) p3 = RooRealVar('p3','p3',args.p3,-10.,10.) if args.fix_p3: p3.setConstant() background_pdf = RooGenericPdf('background_pdf','(pow(1-@0/%.1f,@1)/pow(@0/%.1f,@2+@3*log(@0/%.1f)))'%(self.collision_energy,self.collision_energy,self.collision_energy),RooArgList(self.mjj_,p1,p2,p3)) background_pdf.Print() data_integral = data_histogram.Integral(data_histogram.GetXaxis().FindBin(float(fit_range[0])),data_histogram.GetXaxis().FindBin(float(fit_range[1]))) background_norm = RooRealVar('background_norm','background_norm',data_integral,0.,1e+08) background_norm.Print() # Create signal PDF and fit model if signal_name: signal_pdf = RooHistPdf('signal_pdf', 'signal_pdf', RooArgSet(self.mjj_), self.signal_roohistograms_[signal_name]) signal_pdf.Print() signal_norm = RooRealVar('signal_norm','signal_norm',0,-1e+05,1e+05) signal_norm.Print() model = RooAddPdf("model","s+b",RooArgList(background_pdf,signal_pdf),RooArgList(background_norm,signal_norm)) else: model = RooAddPdf("model","b",RooArgList(background_pdf),RooArgList(background_norm)) # Run fit res = model.fitTo(data_, RooFit.Save(kTRUE), RooFit.Strategy(fit_strategy)) # Save to workspace self.workspace_ = RooWorkspace('w','workspace') #getattr(w,'import')(background,ROOT.RooCmdArg()) getattr(self.workspace_,'import')(background_pdf,RooFit.Rename("background")) getattr(self.workspace_,'import')(background_norm,ROOT.RooCmdArg()) getattr(self.workspace_,'import')(self.data_roohistogram_,RooFit.Rename("data_obs")) getattr(self.workspace_, 'import')(model, RooFit.Rename("model")) if signal_name: getattr(self.workspace_,'import')(signal_roohistogram,RooFit.Rename("signal")) getattr(self.workspace_,'import')(signal_pdf,RooFit.Rename("signal_pdf")) getattr(self.workspace_,'import')(signal_norm,ROOT.RooCmdArg()) self.workspace_.Print() self.workspace_.writeToFile(save_to) if signal_name: roofit_results[signal_name] = save_to else: roofit_results["background"] = save_to
def get_num_sig_bkg(hist_DataTemplate, hist_SignalTemplate, hist_BackgdTemplate, fit_range_min, fit_range_max): '''Given 3 input histograms (TH1F), and a fit range, this function finds the amount of signal and background that sum up to the data histogram. It does histogram fits.''' # Find range of data template data_min = hist_DataTemplate.GetXaxis().GetXmin() data_max = hist_DataTemplate.GetXaxis().GetXmax() # Create basic variables x = RooRealVar("x", "x", data_min, data_max) x.setBins(hist_DataTemplate.GetXaxis().GetNbins()) # Binned x values nsig = RooRealVar("nsig", "number of signal events", 0, hist_DataTemplate.Integral()) nbkg = RooRealVar("nbkg", "number of background events", 0, hist_DataTemplate.Integral()) # Create RooDataHists from input TH1Fs dh = RooDataHist("dh", "dh", RooArgList(x), hist_DataTemplate) ds = RooDataHist("ds", "ds", RooArgList(x), hist_SignalTemplate) db = RooDataHist("db", "db", RooArgList(x), hist_BackgdTemplate) # Create Probability Distribution Functions from Monte Carlo sigPDF = RooHistPdf("sigPDF", "sigPDF", RooArgSet(x), ds) bkgPDF = RooHistPdf("bkgPDF", "bkgPDF", RooArgSet(x), db) model = RooAddPdf("model", "(g1+g2)+a", RooArgList(bkgPDF, sigPDF), RooArgList(nbkg, nsig)) # Find the edges of the bins that contain the fit range min/max data_min = hist_DataTemplate.GetXaxis().GetBinLowEdge( hist_DataTemplate.GetXaxis().FindFixBin(fit_range_min)) data_max = hist_DataTemplate.GetXaxis().GetBinUpEdge( hist_DataTemplate.GetXaxis().FindFixBin(fit_range_max)) r = model.fitTo(dh, RooFit.Save(), RooFit.Minos(0), RooFit.PrintEvalErrors(0), RooFit.Extended(), RooFit.Range(data_min, data_max)) r.Print("v") #print nsig.getVal(), nsig.getError(), nbkg.getVal(), nbkg.getError() return [nsig.getVal(), nsig.getError(), nbkg.getVal(), nbkg.getError()]
def generate(histList, varName, varLow, varHigh, histSig="", weightSig=0.): """ Generate toy data @param histList List of histograms @param varname Variable name to use @param varLow Lower edge of left bin @param varHigh Upper edge of right bin @param histSig Optional signal histogram @param weightSig Optional signal weight """ testHist_pred = TH1D() for (iHist, hist) in enumerate(histList): if not iHist: testHist_pred = hist.Clone("hPRED") else: testHist_pred.Add(hist) testHist_pred_ds = TH1D( "hPSDATA", "hPSDATA", testHist_pred.GetNbinsX(), testHist_pred.GetXaxis().GetBinLowEdge(1), testHist_pred.GetXaxis().GetBinUpEdge(testHist_pred.GetNbinsX())) nEvents_pred = int(testHist_pred.Integral()) print "nEvents_pred = %d" % nEvents_pred var = RooRealVar(varName, varName, varLow, varHigh) dh_pred = RooDataHist("dhPSDATA", "dhPSDATA", RooArgList(var), RooFit.Import(testHist_pred)) ph_pred = RooHistPdf("phPSDATA", "phPSDATA", RooArgSet(var), dh_pred) ds_pred = ph_pred.generate(RooArgSet(var), nEvents_pred) testHist_pred_ds = ds_pred.fillHistogram(testHist_pred_ds, RooArgList(var)) return testHist_pred_ds
def generate(histList,varName,varLow,varHigh,histSig="",weightSig=0.): testHist_pred = TH1D() for (iHist,hist) in enumerate(histList): if not iHist: testHist_pred = hist.Clone("hPRED") else: testHist_pred.Add(hist) testHist_pred_ds = TH1D("hPSDATA","hPSDATA",testHist_pred.GetNbinsX(),testHist_pred.GetXaxis().GetBinLowEdge(1),testHist_pred.GetXaxis().GetBinUpEdge(testHist_pred.GetNbinsX())) nEvents_pred = int(testHist_pred.Integral()) print "nEvents_pred = %d" % nEvents_pred var = RooRealVar(varName,varName,varLow,varHigh) dh_pred = RooDataHist("dhPSDATA","dhPSDATA",RooArgList(var),RooFit.Import(testHist_pred)) ph_pred = RooHistPdf("phPSDATA","phPSDATA",RooArgSet(var),dh_pred) ds_pred = ph_pred.generate(RooArgSet(var),nEvents_pred) testHist_pred_ds = ds_pred.fillHistogram(testHist_pred_ds,RooArgList(var)) return testHist_pred_ds
def makePDFs(Files, pdf_list, evntCount): for (inputMass, inputFilename) in Files: histo = load_histos(inputFilename) evntCount.append(histo.Integral()) # could construct name and title from inputmass if 'nom' in inputFilename: myString = inputFilename.partition("230_")[2].partition( "_result")[0] + str(inputMass) else: myString = inputFilename.partition("jes_")[2].partition( "_result")[0] + str(inputMass) # Convert the TH1F Histogram (data_hist) into a RooDataHist object data_hist = RooDataHist(myString, myString, RooArgList(x), histo) # Turn the RooDataHist object into a RooHistPdf object pdf = RooHistPdf(myString, myString, RooArgSet(x), data_hist) # both the data_hist and pdf must survive pdf_list.append([data_hist, pdf])
def Hist2Pdf(self, hist, pdfName, ws, order=0): if ws.pdf(pdfName): return ws.pdf(pdfName) try: obs = [self.pars.varNames[x] for x in self.pars.var] except AttributeError: obs = self.pars.var varList = RooArgList() for v in obs: varList.add(ws.var(v)) newHist = RooDataHist(pdfName + '_hist', pdfName + '_hist', varList, hist) thePdf = RooHistPdf(pdfName, pdfName, RooArgSet(varList), newHist, order) getattr(ws, 'import')(thePdf) return ws.pdf(pdfName)
def _make_underlying_model(self): self.pdfs = {} self.yields = {} # yields are plain floats self.ryields = {} # keep track of roofit objects for memory management h = self._histos[0] nbins = h.GetXaxis().GetNbins() xmin = h.GetXaxis().GetXmin() xmax = h.GetXaxis().GetXmax() self.xvar = RooRealVar("x", "x", xmin, xmax) self.xvar.setBins(nbins) self.pdfs = {} self.hists = [] pdfs = RooArgList() yields = RooArgList() for histo in self._histos: if histo.Integral() == 0: continue compname = histo.GetName() hist = RooDataHist(compname, compname, RooArgList(self.xvar), histo) SetOwnership(hist, False) # self.hists.append(hist) pdf = RooHistPdf(compname, compname, RooArgSet(self.xvar), hist) self.pdfs[compname] = pdf # self.pdfs[compname].Print() pdfs.add(pdf) nevts = histo.Integral() uncertainty = self._uncertainty nmin = min(0, nevts * (1 - uncertainty)) nmax = nevts * (1 + uncertainty) theyield = RooRealVar('n{}'.format(compname), 'n{}'.format(compname), nevts, nmin, nmax) self.ryields[compname] = theyield self.yields[compname] = nevts yields.add(theyield) self.underlying_model = RooAddPdf('model', 'model', pdfs, yields)
def broadenspec(ms, E_0): spec = decayspec(ms, E_0) smear = core(E_0_center) newspec = TH1D("", "", spec.GetNbinsX(), -17.5, 17.5) for i in range(1, spec.GetNbinsX() + 1): newspec.SetBinContent(i, spec.GetBinContent(i)) #x = RooRealVar("x","x",-30+E_0_center, 5+E_0_center) x = RooRealVar("x", "x", -17.5, 17.5) data = RooDataHist("", "", RooArgList(x), newspec) specpdf = RooHistPdf("", "", RooArgSet(x), data) #y = RooRealVar("y","y",-30, 5) x.setBins(10000) smearpdf = RooFit.bindPdf(smear, x) fft = RooFFTConvPdf("tt", "tt", x, specpdf, smearpdf) #fft.setShift(0, -18574) #c1 = TCanvas() #frame = x.frame() #fft.plotOn(frame) #frame.Draw() tf = fft.asTF(RooArgList(x)) tf.SetNpx(10000) rtf = tf.Clone() return rtf
# Not to be included in the Moment Morphing (just a check) file3 = R.TFile(f3) hist3 = file3.Get('my_model_hist') hist3.SetDirectory(0) hist3_events = hist3.Integral() # Setup Workspace and frame w = R.RooWorkspace('w') x = w.factory('x[70,230]') x.setBins(32) frame = x.frame() # Z = 125 GeV data_hist1 = RooDataHist('dhist1', 'dhist1', RooArgList(x), hist1) pdf1 = RooHistPdf('phist1', 'phist1', RooArgSet(x), data_hist1) pdf1.plotOn(frame, RooFit.LineColor(R.kGreen), RooFit.Normalization(hist1_events)) # Z = 175 GeV data_hist2 = RooDataHist('dhist2', 'dhist2', RooArgList(x), hist2) pdf2 = RooHistPdf('phist2', 'phist2', RooArgSet(x), data_hist2) pdf2.plotOn(frame, RooFit.LineColor(R.kGreen), RooFit.Normalization(hist2_events)) # Not to be included in the Moment Morphing (just a check) data_hist3 = RooDataHist('dhist3', 'dhist3', RooArgList(x), hist3) pdf3 = RooHistPdf('phist3', 'phist3', RooArgSet(x), data_hist3) pdf3.plotOn(frame, RooFit.LineColor(R.kBlue), RooFit.Normalization(hist3_events)) data_hist3.plotOn(frame) # Create a RooArgList to store pdfs and fill it
mmgMassFunc = w.factory('''FormulaVar::mmgMassFunc( "((mmgMass - mmgMode) / mmgScale + mmgMode) - fPho*phoScale/100.", {mmgMass, mmgMode[91.2,70,110], mmgScale[1.,0.1,5], fPho, phoScale} )''') mmgMode = w.var('mmgMode') mmgScale = w.var('mmgScale') ## Get the nominal model for translation, use rho=2 model = RooKeysPdf('model', 'model', mmgMass, mmgData, RooKeysPdf.NoMirror, 2) ## Sample nominal model to binned data, no Poisson fluctuation modelHist = model.createHistogram('mmgMass', 10000) modelDH = RooDataHist('modelDH', 'modelDH', RooArgList(mmgMass), modelHist) ## Use the sampled model to build a transformed model, interpolation order=2 tmodel = RooHistPdf('tmodel', 'tmodel', RooArgList(mmgMassFunc), RooArgList(mmgMass), modelDH, 2) ## Find the mode of the tmodel. mmgMode.setVal(modelHist.GetBinCenter(modelHist.GetMaximumBin())) mmgMode.setConstant(True) fPho.setConstant(True) ## Fit the photon scale phoScale.setConstant(False) mmgScale.setConstant(True) fac, s = 1, 0 mmgMass.SetTitle('scaledMmgMass3(%f, mmgMass, mmMass)' % fac) phoPtRangeMod = (phoPtRange[0] * fac, phoPtRange[1] * fac)
full_ch.Add("/mnt/home/kklimaszewski/LHCb/Bs2JpsieePhi/M_Bs_Fits/mc/DVNtuples_Bs2JpsieePhi_13154001_MCfull_R14ac_TupleBsDetached_PIDCorr_S21_NewSel_tupleB.root") # Run selection ch = full_ch.CopyTree("sigmam>0. && sigmam<250. && time>0.3 && time<14. && sigmat<0.12 && BDT_response_NewSel>0.2 && eminus_bremmult==0 && eplus_bremmult==0") #fit.mass.setBins(_comp['config']['bins']) # Create hist PDF data = RooDataSet( 'data_set', '', RooArgSet(x), RooFit.Import(ch) ) hist = data.binnedClone() p1 = RooHistPdf( 'histpdf', '', RooArgSet(x), hist, 2 # Order of interpolation function ) #p2 = RooGaussian( p2 = RooGaussModel( "comp_2", "", x, mean, sigma ) #pdf = RooNumConvPdf("pdf", 'convolution', x, p1, p2) x.setBins(10000,"fft") ; pdf = RooFFTConvPdf("pdf", 'convolution', x, p2, p1)
cf_p = TCanvas('cf_p', 'fit, parametrized') cf_p_frame = x.frame() data.plotOn(cf_p_frame) model.plotOn(cf_p_frame) cf_p_frame.Draw() ######### model definition, template nsig_tpl = 10000 nbgd_tpl = 1000000 exp_sig_data = sig.generate(RooArgSet(x), nsig_tpl) exp_sig_hist = exp_sig_data.binnedClone() tsig = RooHistPdf('tsig', 'tsig', RooArgSet(x), exp_sig_hist) exp_bgd_data = bgd.generate(RooArgSet(x), nbgd_tpl) exp_bgd_hist = exp_bgd_data.binnedClone() tbgd = RooHistPdf('tbgd', 'tbgd', RooArgSet(x), exp_bgd_hist) # modelsig = RooAddPdf("modelsig", "modelsig", RooArgList(tsig), RooArgList(vysig)) # tmodel = RooAddPdf("tmodel", "tmodel", RooArgList(tsig), RooArgList(vysig)) tmodel = RooAddPdf("tmodel", "tmodel", RooArgList(tsig, tbgd), RooArgList(vysig, vybgd)) ######### data generation, template tdata = tmodel.generate(RooArgSet(x), ndata) ######### fit, template
def shapeCards(datahistosFile, histosFile, signalFile, signalSample, hist, signalMass, minMass, maxMass, outputName, outputFileTheta): """function to run Roofit and save workspace for RooStats""" warnings.filterwarnings( action='ignore', category=RuntimeWarning, message='.*class stack<RooAbsArg\*,deque<RooAbsArg\*> >') ############################################################# DATA #hData = histosFile.Get('massAve_deltaEtaDijet_QCDPtAll') #hData = datahistosFile.Get('massAve_prunedMassAsymVsdeltaEtaDijet_DATA_ABCDProj') dataFile = TFile(datahistosFile) hData = dataFile.Get(hist + '_DATA') hData.Rebin(args.reBin) #hData = hData.Rebin( len( boostedMassAveBins )-1, hData.GetName(), boostedMassAveBins ) #hData = histosFile.Get(hist+'_QCDPtAll_A') #hData.Add(htmpSignal) #hData.Scale(1/hData.Integral()) #maxMass = boostedMassAveBins[ hData.FindLastBinAbove( 0, 1) ] #minMass = signalMass-30 #maxMass = signalMass+30 massAve = RooRealVar('massAve', 'massAve', minMass, maxMass) #massAveData = RooRealVar( 'massAveData', 'massAveData', minMass, maxMass ) rooDataHist = RooDataHist('rooDatahist', 'rooDatahist', RooArgList(massAve), hData) # if isData else hPseudo ) rooDataHist.Print() ############################################################################################ ####################### Signal if 'gaus' in args.job: hSignal = TH1F('massAve_RPVStop', 'massAve_RPVStop', maxMass / args.reBin, minMass, maxMass) for q in range(hSignal.GetNbinsX() + 1): gausEval = signalFile.Eval(hSignal.GetXaxis().GetBinCenter(q)) hSignal.SetBinContent(q, gausEval) #meanSig = RooRealVar( 'meanSig', 'mean of signal', sigGaus.GetParameter( 1 ) ) #sigmaSig = RooRealVar( 'sigmaSig', 'sigma of signal', sigGaus.GetParameter( 2 ) ) #signalPdf = RooGaussian( 'signal', 'signal', massAve, meanSig, sigmaSig ) #signalPdf.Print() else: signalHistosFile = TFile(signalFile) hSignal = signalHistosFile.Get(hist + '_' + signalSample) hSignal.Rebin(args.reBin) hSignal.Scale(twoProngSF) signalXS = search(dictXS, 'RPVStopStopToJets_UDD312_M-' + str(signalMass)) rooSigHist = RooDataHist('rooSigHist', 'rooSigHist', RooArgList(massAve), hSignal) sigAcc = rooSigHist.sumEntries( ) #round(hSignal.Integral( hSignal.GetXaxis().FindBin( minMass ), hSignal.GetXaxis().FindBin( maxMass )), 2) rooSigHist.Print() #signal = RooHistPdf('signal','signal',RooArgSet(massAve),rooSigHist) #signal.Print() #signal_norm = RooRealVar('signal_norm','signal_norm',0,-1e+04,1e+04) #if args.fitBonly: signal_norm.setConstant() #signal_norm.Print() ##################################################################### hSigSyst = signalUnc(hSignal, signalMass) hSigSystDataHist = {} if args.jesUnc: hSigSystDataHist['JESUp'] = RooDataHist('hSignalJESUp', 'hSignalJESUp', RooArgList(massAve), hSigSyst['JESUp']) hSigSystDataHist['JESDown'] = RooDataHist('hSignalJESDown', 'hSignalJESDown', RooArgList(massAve), hSigSyst['JESDown']) if args.jerUnc: hSigSystDataHist['JERUp'] = RooDataHist('hSignalJERUp', 'hSignalJERUp', RooArgList(massAve), hSigSyst['JERUp']) hSigSystDataHist['JERDown'] = RooDataHist('hSignalJERDown', 'hSignalJERDown', RooArgList(massAve), hSigSyst['JERDown']) #################################### Background if args.altBkg: newBkgHistoFile = datahistosFile.replace('DATA', 'DATA_ABCDBkg') newBkgFile = TFile(newBkgHistoFile) htmpBkg = newBkgFile.Get( 'massAve_prunedMassAsymVsdeltaEtaDijet_DATA_ABCDProj') if (htmpBkg.GetBinWidth(1) != args.reBin): print '|----- Bin size in DATA_C histogram is different than rest.' sys.exit(0) else: htmpBkg = dataFile.Get( 'massAve_prunedMassAsymVsdeltaEtaDijet_DATA_ABCDProj') htmpBkg.Rebin(args.reBin) #hBkg = histosFile.Get('massAve_prunedMassAsymVsdeltaEtaDijet_QCDPtAll_ABCDProj') #hBkg = histosFile.Get(hist+'_QCDPtAll_BCD') #htmpBkg = htmpBkg.Rebin( len( boostedMassAveBins )-1, htmpBkg.GetName(), boostedMassAveBins ) hBkg = htmpBkg.Clone() hBkg.Reset() for ibin in range(htmpBkg.GetNbinsX()): binCont = htmpBkg.GetBinContent(ibin) binErr = htmpBkg.GetBinError(ibin) if binCont == 0: hBkg.SetBinContent(ibin, 0) hBkg.SetBinError(ibin, 1.8) else: hBkg.SetBinContent(ibin, binCont) hBkg.SetBinError(ibin, binErr) #hBkg.Scale(1/hBkg.Integral()) hPseudo = createPseudoExperiment(hBkg, bkgAcc) ###### Adding statistical uncertanty hBkgStatUncUp = hBkg.Clone() hBkgStatUncUp.Reset() hBkgStatUncDown = hBkg.Clone() hBkgStatUncDown.Reset() for i in range(hBkg.GetNbinsX() + 1): cont = hBkg.GetBinContent(i) contErr = hBkg.GetBinError(i) hBkgStatUncUp.SetBinContent(i, cont + (1 * contErr)) hBkgStatUncDown.SetBinContent(i, cont - (1 * contErr)) hBkgStatUncUpDataHist = RooDataHist('hBkgStatUncUp', 'hBkgStatUncUp', RooArgList(massAve), hBkgStatUncUp) hBkgStatUncDownDataHist = RooDataHist('hBkgStatUncDown', 'hBkgStatUncDown', RooArgList(massAve), hBkgStatUncDown) if 'template' in args.job: rooBkgHist = RooDataHist('rooBkgHist', 'rooBkgHist', RooArgList(massAve), hBkg) bkgAcc = rooBkgHist.sumEntries() rooBkgHist.Print() background = RooHistPdf('background', 'background', RooArgSet(massAve), rooBkgHist) background.Print() else: massAveBkg = RooRealVar('massAveBkg', 'massAveBkg', minMass, maxMass) p1 = RooRealVar('p1', 'p1', 1, 0., 100.) p2 = RooRealVar('p2', 'p2', 1, 0., 60.) p3 = RooRealVar('p3', 'p3', 1, -10., 10.) bkgAcc = round( hBkg.Integral(hBkg.GetXaxis().FindBin(minMass), hBkg.GetXaxis().FindBin(maxMass)), 2) background = RooGenericPdf( 'background', '(pow(1-@0/%.1f,@1)/pow(@0/%.1f,@2+@3*log(@0/%.1f)))' % (1300, 1300, 1300), RooArgList(massAveBkg, p1, p2, p3)) background.Print() hBkgSyst = {} hBkgSystDataHist = {} if args.bkgUnc: print ' |---> Adding bkg unc' hBkgSyst['BkgUncUp'] = hBkg.Clone() hBkgSyst['BkgUncDown'] = hBkg.Clone() for key in hBkgSyst: hBkgSyst[key].Reset() hBkgSyst[key].SetName(hBkgSyst[key].GetName() + '_' + key) for q in range(0, hBkg.GetNbinsX()): binCont = hBkg.GetBinContent(q) bkgUncUp = 1. + (args.bkgUncValue / 100.) hBkgSyst['BkgUncUp'].SetBinContent(q, binCont * bkgUncUp) bkgUncDown = 1. - (args.bkgUncValue / 100.) hBkgSyst['BkgUncDown'].SetBinContent(q, binCont * bkgUncDown) hBkgSystDataHist['BkgUncUp'] = RooDataHist('hBkgBkgUncUp', 'hBkgBkgUncUp', RooArgList(massAve), hBkgSyst['BkgUncUp']) hBkgSystDataHist['BkgUncDown'] = RooDataHist('hBkgBkgUncDown', 'hBkgBkgUncDown', RooArgList(massAve), hBkgSyst['BkgUncDown']) ############################################################################################ #model = RooAddPdf("model","s+b",RooArgList(background,signal),RooArgList(background_norm,signal_norm)) #res = model.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(0)) #res.Print() ############################ Create Workspace myWS = RooWorkspace("myWS") getattr(myWS, 'import')(rooBkgHist, RooFit.Rename("background")) #getattr(myWS,'import')(background,RooFit.Rename("background")) #getattr(myWS,'import')(signal_norm) #getattr(myWS,'import')(background_norm) ''' if 'gaus' in args.job: getattr(myWS,'import')(signalPdf,RooFit.Rename("signal")) if args.jesUnc: getattr(myWS,'import')(signalPdfJESUp,RooFit.Rename("signal__JESUp")) getattr(myWS,'import')(signalPdfJESDown,RooFit.Rename("signal__JESDown")) else: ''' getattr(myWS, 'import')(rooSigHist, RooFit.Rename("signal")) if args.jesUnc: getattr(myWS, 'import')(hSigSystDataHist['JESUp'], RooFit.Rename("signal__JESUp")) getattr(myWS, 'import')(hSigSystDataHist['JESDown'], RooFit.Rename("signal__JESDown")) if args.jerUnc: getattr(myWS, 'import')(hSigSystDataHist['JERUp'], RooFit.Rename("signal__JERUp")) getattr(myWS, 'import')(hSigSystDataHist['JERDown'], RooFit.Rename("signal__JERDown")) if args.bkgUnc: getattr(myWS, 'import')(hBkgSystDataHist['BkgUncUp'], RooFit.Rename("background__BkgUncUp")) getattr(myWS, 'import')(hBkgSystDataHist['BkgUncDown'], RooFit.Rename("background__BkgUncDown")) getattr(myWS, 'import')(hBkgStatUncUpDataHist, RooFit.Rename("background__BkgStatUncUp")) getattr(myWS, 'import')(hBkgStatUncDownDataHist, RooFit.Rename("background__BkgStatUncDown")) getattr(myWS, 'import')(rooDataHist, RooFit.Rename("data_obs")) myWS.Print() outputRootFile = currentDir + '/Rootfiles/workspace_' + outputName + '.root' myWS.writeToFile(outputRootFile, True) print ' |----> Workspace created in root file:\n', outputRootFile ''' c1 = TCanvas('c1', 'c1', 10, 10, 750, 500 ) # c1.SetLogy() xframe = myWS.var("massAve").frame() signalPdf.plotOn( xframe ) xframe.Draw() c1.SaveAs('test.png') del c1 ''' ############################################################################################ ######################### write a datacard dataCardName = currentDir + '/Datacards/datacard_' + outputName + '.txt' datacard = open(dataCardName, 'w') datacard.write('imax 1\n') datacard.write('jmax 1\n') datacard.write('kmax *\n') datacard.write('---------------\n') if args.jesUnc or args.jerUnc or args.lumiUnc or args.bkgUnc or args.unc: datacard.write('shapes * * ' + outputRootFile + ' myWS:$PROCESS myWS:$PROCESS__$SYSTEMATIC\n') else: datacard.write("shapes * * " + outputRootFile + " myWS:$PROCESS \n") datacard.write('---------------\n') datacard.write('bin ' + signalSample + '\n') datacard.write('observation -1\n') datacard.write('------------------------------\n') datacard.write('bin ' + signalSample + ' ' + signalSample + '\n') datacard.write('process signal background\n') datacard.write('process 0 1\n') #datacard.write('rate -1 -1\n') datacard.write('rate ' + str(sigAcc) + ' ' + str(bkgAcc) + '\n') datacard.write('------------------------------\n') if args.lumiUnc: datacard.write('lumi lnN %f -\n' % (lumiValue)) if args.puUnc: datacard.write('pu lnN %f -\n' % (puValue)) if args.jesUnc: datacard.write('JES shape 1 -\n') if args.jerUnc: datacard.write('JER shape 1 -\n') #flat parameters --- flat prior #if args.bkgUnc: datacard.write('BkgUnc shape - '+str( round( 1/ (args.bkgUncValue/34.1), 2 ) )+'\n') if args.bkgUnc: datacard.write('BkgUnc shape - 1 \n') #NcombineUnc = ( 1 / TMath.Sqrt( args.bkgUncValue / 100. ) ) - 1 #datacard.write('background_norm gmN '+str(int(round(NcombineUnc)))+' - '+str( round(bkgAcc/NcombineUnc,2) )+'\n') #datacard.write('p1 flatParam\n') datacard.write('BkgStatUnc shape - 1 \n') datacard.close() print ' |----> Datacard created:\n', dataCardName ############################################################################################ ########## Theta if args.theta: print ' |----> Creating Theta file\n', outputFileTheta outFile = TFile(outputFileTheta, 'update') tmpName = 'rpvstopjj' + str(signalMass) hSignal.SetName('massAve__' + tmpName) hSignal.Write() hSigSyst['JESDown'].SetName('massAve__' + tmpName + '__jes__down') hSigSyst['JESDown'].Write() hSigSyst['JESUp'].SetName('massAve__' + tmpName + '__jes__up') hSigSyst['JESUp'].Write() hSigSyst['JERDown'].SetName('massAve__' + tmpName + '__jer__down') hSigSyst['JERDown'].Write() hSigSyst['JERUp'].SetName('massAve__' + tmpName + '__jer__up') hSigSyst['JERUp'].Write() if (signalMass == 100): #or (signalMass == 170): hBkg.SetName('massAve__background') hBkg.Write() hBkgSyst['BkgUncDown'].SetName('massAve__background__unc__down') hBkgSyst['BkgUncDown'].Write() hBkgSyst['BkgUncUp'].SetName('massAve__background__unc__up') hBkgSyst['BkgUncUp'].Write() hData.SetName('massAve__DATA') hData.Write() outFile.Close()
def main(options,args): from ROOT import gSystem, gROOT, gStyle gROOT.SetBatch() gSystem.Load("libRooFitCore") if options.doWebPage: from lip.Tools.rootutils import loadToolsLib, apply_modifs loadToolsLib() from ROOT import TFile, RooFit, RooArgSet, RooDataHist, RooKeysPdf, RooHistPdf, TCanvas, TLegend, TLatex, TArrow, TPaveText, RooAddPdf, RooArgList from ROOT import kWhite, kBlue, kOpenSquare if options.doWebPage: from ROOT import HtmlHelper, HtmlTag, HtmlTable, HtmlPlot rootglobestyle.setTDRStyle() gStyle.SetMarkerSize(1.5) gStyle.SetTitleYOffset(1.5) gStyle.SetPadLeftMargin(0.16) gStyle.SetPadRightMargin(0.05) gStyle.SetPadTopMargin(0.05) gStyle.SetPadBottomMargin(0.13) gStyle.SetLabelFont(42,"XYZ") gStyle.SetLabelOffset(0.007, "XYZ") gStyle.SetLabelSize(0.05,"XYZ") gStyle.SetTitleSize(0.06,"XYZ") gStyle.SetTitleXOffset(0.9) gStyle.SetTitleYOffset(1.24) gStyle.SetTitleFont(42,"XYZ") ## ## Read files ## options.outdir = "%s_m%1.0f" % ( options.outdir, options.mH ) if options.fp: options.outdir += "_fp" ncat=options.ncat cats=options.cats if cats is "": categories =[ "_cat%d" % i for i in range(0,ncat) ] else: categories =[ "_cat%s" % i for i in cats.split(",") ] if options.mva: clables = { "_cat0" : ("MVA > 0.89",""), "_cat1" : ("0.74 #leq MVA","MVA < 0.89"), "_cat2" : ("0.545 #leq MVA","MVA < 0.74"), "_cat3" : ("0.05 #leq MVA","MVA < 0.545"), "_cat4" : ("Di-jet","Tagged"), "_cat5" : ("Di-jet","Tagged"), "_combcat" : ("All Classes","Combined") } else: clables = { "_cat0" : ("max(|#eta|<1.5","min(R_{9})>0.94"), "_cat1" : ("max(|#eta|<1.5","min(R_{9})<0.94"), "_cat2" : ("max(|#eta|>1.5","min(R_{9})>0.94"), "_cat3" : ("max(|#eta|>1.5","min(R_{9})<0.94"), "_cat4" : ("Di-jet","Tagged"), "_cat5" : ("Di-jet","Tagged"), "_combcat" : ("All Classes","Combined") } helper = Helper() fin = TFile.Open(options.infile) helper.files.append(fin) ws = fin.Get("cms_hgg_workspace") mass = ws.var("CMS_hgg_mass") mass.SetTitle("m_{#gamma#gamma}"); mass.setUnit("GeV"); mass.setRange(100.,150.) mass.setBins(100,"plot") mass.setBins(5000) print ws aset = RooArgSet(mass) helper.objs.append( mass ) helper.objs.append( aset ) fitopt = ( RooFit.Minimizer("Minuit2", ""), RooFit.Minos(False), RooFit.SumW2Error(False), RooFit.NumCPU(8) ) if not options.binned and not options.refit: finpdf = TFile.Open(options.infilepdf) helper.files.append(finpdf) wspdf = finpdf.Get("wsig") else: wspdf = ws for c in categories: processes = [ "ggh", "vbf", "wzh" ] if options.fp: processes = [ "vbf", "wzh" ] ### elif clables[c][0] == "Di-jet": ### processes = [ "vbf", "ggh" ] dsname = "sig_mass_m%1.0f%s" % (options.mH,c) print dsname print ws ds = ws.data( "sig_%s_mass_m%1.0f%s" % (processes[0],options.mH,c) ).Clone(dsname) for proc in processes[1:]: ds.append( ws.data( "sig_%s_mass_m%1.0f%s" % (proc,options.mH,c) ) ) helper.dsets.append( ds ) if options.binned: binned_ds = RooDataHist( "binned_%s" % dsname,"binned_%s" % dsname,aset, ds) pdf = RooKeysPdf( "pdf_%s_%s" % (dsname, f), "pdf_%s" % dsname, mass, ds ) plot_pdf = RooHistPdf( "pdf_%s" % dsname, "pdf_%s" % dsname, aset, plot_ds ) helper.add( binned_ds, binned_ds.GetName() ) else: if options.refit: if options.refitall and clables[c][0] != "Di-jet": rpdfs = [] for proc in processes: for ngaus in range(1,4): pp = build_pdf(ws,"%s_%s" % (c,proc),ngaus,ngaus==3 ) pp.fitTo( ws.data( "sig_%s_mass_m%1.0f%s" % (proc,options.mH,c)), RooFit.Strategy(0), *fitopt ) rpdfs.append(pp) pdf = RooAddPdf("hggpdfrel%s" % c, "hggpdfrel%s" % c, RooArgList(*tuple(rpdfs) )) else: if options.refitall and clables[c][0] == "Di-jet": for ngaus in range(1,5): pdf = build_pdf(ws,c,ngaus,ngaus==5) pdf.fitTo(ds, RooFit.Strategy(0), *fitopt ) else: for ngaus in range(1,4): pdf = build_pdf(ws,c,ngaus,ngaus==3) pdf.fitTo(ds, RooFit.Strategy(0), *fitopt ) else: pdfs = (wspdf.pdf( "hggpdfrel%s_%s" % (c, p)) for p in processes ) pdf = RooAddPdf("hggpdfrel%s" % c, "hggpdfrel%s" % c, RooArgList(*pdfs )) helper.add(pdf,pdf.GetName()) plot_pdf = pdf.Clone("pdf_%s" % dsname) plot_ds = RooDataHist( "plot_%s" % dsname,"plot_%s" % dsname, aset, "plot") plot_ds.add( ds ) cdf = pdf.createCdf(aset) hmin, hmax, hm = get_FWHM( mass, pdf, cdf, options.mH-10., options.mH+10. ) wmin, wmax = get_eff_sigma( mass, pdf, cdf, options.mH-10., options.mH+10. ) ### hmin, hmax, hm = get_FWHM( points ) helper.add( plot_ds, plot_ds.GetName() ) helper.add( plot_pdf, plot_pdf.GetName() ) helper.add( (wmin,wmax), "eff_sigma%s" % c ) helper.add( (hmin, hmax, hm), "FWHM%s" % c ) helper.add( ds.sumEntries(), "sumEntries%s" %c ) # signal model integral # data integral for PAS tables data = ws.data( "data_mass%s"%c) helper.add( data.sumEntries("CMS_hgg_mass>=%1.4f && CMS_hgg_mass<=%1.4f"%(options.mH-10.,options.mH+10.)),"data_sumEntries%s"%c) del cdf del pdf dsname = "sig_mass_m%1.0f_combcat" % options.mH print dsname combined_ds = helper.dsets[0].Clone(dsname) for d in helper.dsets[1:]: combined_ds.append(d) if options.binned: binned_ds = RooDataHist( "binned_%s" % dsname,"binned_%s" % dsname,aset, combined_ds) pdf = RooKeysPdf( "pdf_%s" % (dsname), "pdf_%s" % dsname, mass, combined_ds ) plot_pdf = RooHistPdf( "pdf_%s" % dsname, "pdf_%s" % dsname, aset, plot_ds ) helper.add( binned_ds, binned_ds.GetName() ) else: #### pdf = build_pdf(ws,"_combcat") #### pdf.fitTo(combined_ds, RooFit.Strategy(0), *fitopt ) #### plot_pdf = pdf.Clone( "pdf_%s" % dsname ) pdf = RooAddPdf( "pdf_%s" % dsname, "pdf_%s" % dsname, RooArgList( *(helper.histos["hggpdfrel%s" % c] for c in categories) ) ) plot_pdf = pdf cdf = pdf.createCdf(aset) plot_ds = RooDataHist( "plot_%s" % dsname,"plot_%s" % dsname, aset, "plot") plot_ds.add( combined_ds ) wmin, wmax = get_eff_sigma( mass, pdf, cdf, options.mH-10., options.mH+10. ) hmin, hmax, hm = get_FWHM( mass, pdf, cdf, options.mH-10., options.mH+10. ) helper.add( plot_ds, plot_ds.GetName() ) helper.add( plot_pdf, plot_pdf.GetName() ) helper.add( (wmin,wmax), "eff_sigma_combcat" ) helper.add( (hmin, hmax, hm), "FWHM_combcat" ) helper.add( plot_ds.sumEntries(), "sumEntries_combcat" ) mass.setRange("higgsrange",options.mH-25.,options.mH+15.); del cdf del pdf del helper.dsets ### label = TLatex(0.1812081,0.8618881,"#scale[0.8]{#splitline{CMS preliminary}{Simulation}}") label = TLatex(0.7,0.86,"#scale[0.65]{#splitline{CMS preliminary}{Simulation}}") label.SetNDC(1) ## ## Make web page with plots ## if options.doWebPage: hth = HtmlHelper(options.outdir) hth.navbar().cell( HtmlTag("a") ).firstChild().txt("..").set("href","../?C=M;O=D") hth.navbar().cell( HtmlTag("a") ).firstChild().txt("home").set("href","./") tab = hth.body().add( HtmlTable() ) ip = 0 for c in ["_combcat"]+categories: ### for c in categories: if options.doWebPage and ip % 4 == 0: row = tab.row() ip = ip + 1 dsname = "sig_mass_m%1.0f%s" % (options.mH,c) canv = TCanvas(dsname,dsname,600,600) helper.objs.append(canv) ### leg = TLegend(0.4345638,0.6835664,0.9362416,0.9178322) leg = TLegend(0.2,0.96,0.5,0.55) #apply_modifs( leg, [("SetLineColor",kWhite),("SetFillColor",kWhite),("SetFillStyle",0),("SetLineStyle",0)] ) hplotcompint = mass.frame(RooFit.Bins(250),RooFit.Range("higgsrange")) helper.objs.append(hplotcompint) helper.objs.append(leg) plot_ds =helper.histos["plot_%s" % dsname ] plot_pdf =helper.histos["pdf_%s" % dsname ] wmin,wmax = helper.histos["eff_sigma%s" % c ] hmin, hmax, hm = helper.histos["FWHM%s" % c ] print hmin, hmax, hm style = ( RooFit.LineColor(kBlue), RooFit.LineWidth(2), RooFit.FillStyle(0) ) style_seff = ( RooFit.LineWidth(2), RooFit.FillStyle(1001), RooFit.VLines(), RooFit.LineColor(15), ) style_ds = ( RooFit.MarkerStyle(kOpenSquare), ) plot_ds.plotOn(hplotcompint,RooFit.Invisible()) plot_pdf.plotOn(hplotcompint,RooFit.NormRange("higgsrange"),RooFit.Range(wmin,wmax), RooFit.FillColor(19), RooFit.DrawOption("F"), *style_seff) seffleg = hplotcompint.getObject(int(hplotcompint.numItems()-1)) plot_pdf.plotOn(hplotcompint,RooFit.NormRange("higgsrange"),RooFit.Range(wmin,wmax), RooFit.LineColor(15), *style_seff) plot_pdf.plotOn(hplotcompint,RooFit.NormRange("higgsrange"),RooFit.Range("higgsrange"),*style) pdfleg = hplotcompint.getObject(int(hplotcompint.numItems()-1)) plot_ds.plotOn(hplotcompint,*style_ds) pointsleg = hplotcompint.getObject(int(hplotcompint.numItems()-1)) iob = int( hplotcompint.numItems() - 1 ) leg.AddEntry( pointsleg, "Simulation", "pe" ) leg.AddEntry( pdfleg, "Parametric model", "l" ) leg.AddEntry( seffleg, "#sigma_{eff} = %1.2f GeV " % ( 0.5*(wmax-wmin) ), "fl" ) clabel = TLatex(0.74,0.65,"#scale[0.65]{#splitline{%s}{%s}}" % clables[c]) clabel.SetNDC(1) helper.objs.append(clabel) hm = hplotcompint.GetMaximum()*0.5*0.9 ### hm = pdfleg.GetMaximum()*0.5 fwhmarrow = TArrow(hmin,hm,hmax,hm) fwhmarrow.SetArrowSize(0.03) helper.objs.append(fwhmarrow) fwhmlabel = TPaveText(0.20,0.58,0.56,0.48,"brNDC") fwhmlabel.SetFillStyle(0) fwhmlabel.SetLineColor(kWhite) reducedFWHM = (hmax-hmin)/2.3548200 fwhmlabel.AddText("FWHM/2.35 = %1.2f GeV" % reducedFWHM) helper.objs.append(fwhmlabel) hplotcompint.SetTitle(""); hplotcompint.GetXaxis().SetNoExponent(True); hplotcompint.GetXaxis().SetTitle("m_{#gamma#gamma} (GeV)"); hplotcompint.GetXaxis().SetNdivisions(509); ## hplotcompint.GetYaxis().SetTitle("A.U."); ## hplotcompint.GetYaxis().SetRangeUser(0.,hplotcompint.GetMaximum()*1.4); hplotcompint.Draw(); leg.Draw("same") label.Draw("same") clabel.Draw("same") fwhmarrow.Draw("<>") fwhmlabel.Draw("same") plot_ds.sumEntries() if options.doWebPage: hpl = HtmlPlot(canv,False,"",True,True,True) hpl.caption("<i>%s</i>" % canv.GetTitle()) row.cell( hpl ) else: if os.path.isdir(options.outdir) is False: os.mkdir(options.outdir) for ext in "C","png","pdf": canv.SaveAs( os.path.join(options.outdir,"%s.%s" % (canv.GetName(), ext)) ) if "comb" in c: ip = 0 if options.doWebPage: print "Creating pages..." hth.dump() for f in helper.files: f.Close() gROOT.Reset() from pprint import pprint pprint(helper) print 'Summary statistics per event class' print 'Cat\tSignal\t\tData/GeV (in %3.1f+/-10)\tsigEff\tFWHM/2.35'%options.mH sigTotal=0. dataTotal=0. for c in categories: sigVal = helper.histos["sumEntries%s"%c] datVal = helper.histos["data_sumEntries%s"%c] sigTotal+=sigVal dataTotal+=datVal for c in categories: sigVal = helper.histos["sumEntries%s"%c] datVal = helper.histos["data_sumEntries%s"%c] effSig = 0.5*(helper.histos["eff_sigma%s"%c][1]-helper.histos["eff_sigma%s"%c][0]) fwhm = (helper.histos["FWHM%s"%c][1]-helper.histos["FWHM%s"%c][0]) / 2.3548200 print c, '\t%3.1f (%3.1f%%)\t%3.1f (%3.1f%%)\t\t\t%2.2f\t%2.2f'%(sigVal,100.*sigVal/sigTotal,datVal/(10.+10.),100.*datVal/dataTotal,effSig,fwhm) print "Done."
def main(): # usage description usage = "Example: ./scripts/createDatacards.py --inputData inputs/rawhistV7_Run2015D_scoutingPFHT_UNBLINDED_649_838_JEC_HLTplusV7_Mjj_cor_smooth.root --dataHistname mjj_mjjcor_gev --inputSig inputs/ResonanceShapes_gg_13TeV_Scouting_Spring15.root -f gg -o datacards -l 1866 --lumiUnc 0.027 --massrange 1000 1500 50 --runFit --p1 5 --p2 7 --p3 0.4 --massMin 838 --massMax 2037 --fitStrategy 2" # input parameters parser = ArgumentParser( description= 'Script that creates combine datacards and corresponding RooFit workspaces', epilog=usage) parser.add_argument("--inputData", dest="inputData", required=True, help="Input data spectrum", metavar="INPUT_DATA") parser.add_argument("--dataHistname", dest="dataHistname", required=True, help="Data histogram name", metavar="DATA_HISTNAME") parser.add_argument("--inputSig", dest="inputSig", required=True, help="Input signal shapes", metavar="INPUT_SIGNAL") parser.add_argument("-f", "--final_state", dest="final_state", required=True, help="Final state (e.g. qq, qg, gg)", metavar="FINAL_STATE") parser.add_argument("-f2", "--type", dest="atype", required=True, help="Type (e.g. hG, lG, hR, lR)") parser.add_argument( "-o", "--output_path", dest="output_path", required=True, help="Output path where datacards and workspaces will be stored", metavar="OUTPUT_PATH") parser.add_argument( "-l", "--lumi", dest="lumi", required=True, default=1000., type=float, help="Integrated luminosity in pb-1 (default: %(default).1f)", metavar="LUMI") parser.add_argument( "--massMin", dest="massMin", default=500, type=int, help= "Lower bound of the mass range used for fitting (default: %(default)s)", metavar="MASS_MIN") parser.add_argument( "--massMax", dest="massMax", default=1200, type=int, help= "Upper bound of the mass range used for fitting (default: %(default)s)", metavar="MASS_MAX") parser.add_argument( "--p1", dest="p1", default=5.0000e-03, type=float, help="Fit function p1 parameter (default: %(default)e)", metavar="P1") parser.add_argument( "--p2", dest="p2", default=9.1000e+00, type=float, help="Fit function p2 parameter (default: %(default)e)", metavar="P2") parser.add_argument( "--p3", dest="p3", default=5.0000e-01, type=float, help="Fit function p3 parameter (default: %(default)e)", metavar="P3") parser.add_argument( "--lumiUnc", dest="lumiUnc", required=True, type=float, help="Relative uncertainty in the integrated luminosity", metavar="LUMI_UNC") parser.add_argument("--jesUnc", dest="jesUnc", type=float, help="Relative uncertainty in the jet energy scale", metavar="JES_UNC") parser.add_argument( "--jerUnc", dest="jerUnc", type=float, help="Relative uncertainty in the jet energy resolution", metavar="JER_UNC") parser.add_argument( "--sqrtS", dest="sqrtS", default=13000., type=float, help="Collision center-of-mass energy (default: %(default).1f)", metavar="SQRTS") parser.add_argument("--fixP3", dest="fixP3", default=False, action="store_true", help="Fix the fit function p3 parameter") parser.add_argument("--runFit", dest="runFit", default=False, action="store_true", help="Run the fit") parser.add_argument("--fitBonly", dest="fitBonly", default=False, action="store_true", help="Run B-only fit") parser.add_argument("--fixBkg", dest="fixBkg", default=False, action="store_true", help="Fix all background parameters") parser.add_argument("--decoBkg", dest="decoBkg", default=False, action="store_true", help="Decorrelate background parameters") parser.add_argument("--fitStrategy", dest="fitStrategy", type=int, default=1, help="Fit strategy (default: %(default).1f)") parser.add_argument("--debug", dest="debug", default=False, action="store_true", help="Debug printout") parser.add_argument( "--postfix", dest="postfix", default='', help="Postfix for the output file names (default: %(default)s)") parser.add_argument("--pyes", dest="pyes", default=False, action="store_true", help="Make files for plots") parser.add_argument("--jyes", dest="jyes", default=False, action="store_true", help="Make files for JES/JER plots") parser.add_argument( "--pdir", dest="pdir", default='testarea', help="Name a directory for the plots (default: %(default)s)") parser.add_argument("--chi2", dest="chi2", default=False, action="store_true", help="Compute chi squared") parser.add_argument("--widefit", dest="widefit", default=False, action="store_true", help="Fit with wide bin hist") mass_group = parser.add_mutually_exclusive_group(required=True) mass_group.add_argument( "--mass", type=int, nargs='*', default=1000, help= "Mass can be specified as a single value or a whitespace separated list (default: %(default)i)" ) mass_group.add_argument( "--massrange", type=int, nargs=3, help="Define a range of masses to be produced. Format: min max step", metavar=('MIN', 'MAX', 'STEP')) mass_group.add_argument("--masslist", help="List containing mass information") args = parser.parse_args() if args.atype == 'hG': fstr = "bbhGGBB" in2 = 'bcorrbin/binmodh.root' elif args.atype == 'hR': fstr = "bbhRS" in2 = 'bcorrbin/binmodh.root' elif args.atype == 'lG': fstr = "bblGGBB" in2 = 'bcorrbin/binmodl.root' else: fstr = "bblRS" in2 = 'bcorrbin/binmodl.root' # check if the output directory exists if not os.path.isdir(os.path.join(os.getcwd(), args.output_path)): os.mkdir(os.path.join(os.getcwd(), args.output_path)) # mass points for which resonance shapes will be produced masses = [] if args.massrange != None: MIN, MAX, STEP = args.massrange masses = range(MIN, MAX + STEP, STEP) elif args.masslist != None: # A mass list was provided print "Will create mass list according to", args.masslist masslist = __import__(args.masslist.replace(".py", "")) masses = masslist.masses else: masses = args.mass # sort masses masses.sort() # import ROOT stuff from ROOT import gStyle, TFile, TH1F, TH1D, TGraph, kTRUE, kFALSE, TCanvas, TLegend, TPad, TLine from ROOT import RooHist, RooRealVar, RooDataHist, RooArgList, RooArgSet, RooAddPdf, RooFit, RooGenericPdf, RooWorkspace, RooMsgService, RooHistPdf, RooExtendPdf if not args.debug: RooMsgService.instance().setSilentMode(kTRUE) RooMsgService.instance().setStreamStatus(0, kFALSE) RooMsgService.instance().setStreamStatus(1, kFALSE) # input data file inputData = TFile(args.inputData) # input data histogram hData = inputData.Get(args.dataHistname) inData2 = TFile(in2) hData2 = inData2.Get('h_data') # input sig file inputSig = TFile(args.inputSig) sqrtS = args.sqrtS # mass variable mjj = RooRealVar('mjj', 'mjj', float(args.massMin), float(args.massMax)) # integrated luminosity and signal cross section lumi = args.lumi signalCrossSection = 1. # set to 1. so that the limit on r can be interpreted as a limit on the signal cross section for mass in masses: print ">> Creating datacard and workspace for %s resonance with m = %i GeV..." % ( args.final_state, int(mass)) # get signal shape hSig = inputSig.Get("h_" + args.final_state + "_" + str(int(mass))) # normalize signal shape to the expected event yield (works even if input shapes are not normalized to unity) hSig.Scale( signalCrossSection * lumi / hSig.Integral() ) # divide by a number that provides roughly an r value of 1-10 rooSigHist = RooDataHist('rooSigHist', 'rooSigHist', RooArgList(mjj), hSig) print 'Signal acceptance:', (rooSigHist.sumEntries() / hSig.Integral()) signal = RooHistPdf('signal', 'signal', RooArgSet(mjj), rooSigHist) signal_norm = RooRealVar('signal_norm', 'signal_norm', 0, -1e+05, 1e+05) signal_norm2 = RooRealVar('signal_norm2', 'signal_norm2', 0, -1e+05, 1e+05) signal_norm3 = RooRealVar('signal_norm3', 'signal_norm3', 0, -1e+05, 1e+05) signal_norm4 = RooRealVar('signal_norm4', 'signal_norm4', 0, -1e+05, 1e+05) signal_norm5 = RooRealVar('signal_norm5', 'signal_norm5', 0, -1e+05, 1e+05) if args.fitBonly: signal_norm.setConstant() signal_norm2.setConstant() signal_norm3.setConstant() signal_norm4.setConstant() signal_norm5.setConstant() p1 = RooRealVar('p1', 'p1', args.p1, 0., 100.) p2 = RooRealVar('p2', 'p2', args.p2, 0., 60.) p3 = RooRealVar('p3', 'p3', args.p3, -10., 10.) p4 = RooRealVar('p4', 'p4', 5.6, -50., 50.) p5 = RooRealVar('p5', 'p5', 10., -50., 50.) p6 = RooRealVar('p6', 'p6', .016, -50., 50.) p7 = RooRealVar('p7', 'p7', 8., -50., 50.) p8 = RooRealVar('p8', 'p8', .22, -50., 50.) p9 = RooRealVar('p9', 'p9', 14.1, -50., 50.) p10 = RooRealVar('p10', 'p10', 8., -50., 50.) p11 = RooRealVar('p11', 'p11', 4.8, -50., 50.) p12 = RooRealVar('p12', 'p12', 7., -50., 50.) p13 = RooRealVar('p13', 'p13', 7., -50., 50.) p14 = RooRealVar('p14', 'p14', 7., -50., 50.) p15 = RooRealVar('p15', 'p15', 1., -50., 50.) p16 = RooRealVar('p16', 'p16', 9., -50., 50.) p17 = RooRealVar('p17', 'p17', 0.6, -50., 50.) if args.fixP3: p3.setConstant() background = RooGenericPdf( 'background', '(pow(1-@0/%.1f,@1)/pow(@0/%.1f,@2+@3*log(@0/%.1f)))' % (sqrtS, sqrtS, sqrtS), RooArgList(mjj, p1, p2, p3)) dataInt = hData.Integral(hData.GetXaxis().FindBin(float(args.massMin)), hData.GetXaxis().FindBin(float(args.massMax))) background_norm = RooRealVar('background_norm', 'background_norm', dataInt, 0., 1e+08) background2 = RooGenericPdf( 'background2', '(pow(@0/%.1f,-@1)*pow(1-@0/%.1f,@2))' % (sqrtS, sqrtS), RooArgList(mjj, p4, p5)) dataInt2 = hData.Integral( hData.GetXaxis().FindBin(float(args.massMin)), hData.GetXaxis().FindBin(float(args.massMax))) background2_norm = RooRealVar('background2_norm', 'background2_norm', dataInt2, 0., 1e+08) background3 = RooGenericPdf('background3', '(1/pow(@1+@0/%.1f,@2))' % (sqrtS), RooArgList(mjj, p6, p7)) dataInt3 = hData.Integral( hData.GetXaxis().FindBin(float(args.massMin)), hData.GetXaxis().FindBin(float(args.massMax))) background3_norm = RooRealVar('background3_norm', 'background3_norm', dataInt3, 0., 1e+08) background4 = RooGenericPdf( 'background4', '(1/pow(@1+@2*@0/%.1f+pow(@0/%.1f,2),@3))' % (sqrtS, sqrtS), RooArgList(mjj, p8, p9, p10)) dataInt4 = hData.Integral( hData.GetXaxis().FindBin(float(args.massMin)), hData.GetXaxis().FindBin(float(args.massMax))) background4_norm = RooRealVar('background4_norm', 'background4_norm', dataInt4, 0., 1e+08) background5 = RooGenericPdf( 'background5', '(pow(@0/%.1f,-@1)*pow(1-pow(@0/%.1f,1/3),@2))' % (sqrtS, sqrtS), RooArgList(mjj, p11, p12)) dataInt5 = hData.Integral( hData.GetXaxis().FindBin(float(args.massMin)), hData.GetXaxis().FindBin(float(args.massMax))) background5_norm = RooRealVar('background5_norm', 'background5_norm', dataInt5, 0., 1e+08) background6 = RooGenericPdf( 'background6', '(pow(@0/%.1f,2)+@1*@0/%.1f+@2)' % (sqrtS, sqrtS), RooArgList(mjj, p13, p14)) dataInt6 = hData.Integral( hData.GetXaxis().FindBin(float(args.massMin)), hData.GetXaxis().FindBin(float(args.massMax))) background_norm6 = RooRealVar('background_norm6', 'background_norm6', dataInt6, 0., 1e+08) background7 = RooGenericPdf( 'background7', '((-1+@1*@0/%.1f)*pow(@0/%.1f,@2+@3*log(@0/%.1f)))' % (sqrtS, sqrtS, sqrtS), RooArgList(mjj, p15, p16, p17)) dataInt7 = hData.Integral( hData.GetXaxis().FindBin(float(args.massMin)), hData.GetXaxis().FindBin(float(args.massMax))) background_norm7 = RooRealVar('background_norm7', 'background_norm7', dataInt7, 0., 1e+08) #Extend PDFs exts = RooExtendPdf('extsignal', 'Extended Signal Pdf', signal, signal_norm) extb = RooExtendPdf('extbackground', 'Extended Background Pdf', background, background_norm) exts2 = RooExtendPdf('extsignal2', 'Extended Signal Pdf2', signal, signal_norm2) extb2 = RooExtendPdf('extbackground2', 'Extended Background Pdf2', background2, background2_norm) exts3 = RooExtendPdf('extsignal3', 'Extended Signal Pdf3', signal, signal_norm3) extb3 = RooExtendPdf('extbackground3', 'Extended Background Pdf3', background3, background3_norm) exts4 = RooExtendPdf('extsignal4', 'Extended Signal Pdf4', signal, signal_norm4) extb4 = RooExtendPdf('extbackground4', 'Extended Background Pdf4', background4, background4_norm) exts5 = RooExtendPdf('extsignal5', 'Extended Signal Pdf5', signal, signal_norm5) extb5 = RooExtendPdf('extbackground5', 'Extended Background Pdf5', background5, background5_norm) # S+B model model = RooAddPdf("model", "s+b", RooArgList(extb, exts)) model2 = RooAddPdf("model2", "s+b2", RooArgList(extb2, exts2)) model3 = RooAddPdf("model3", "s+b3", RooArgList(extb3, exts3)) model4 = RooAddPdf("model4", "s+b4", RooArgList(extb4, exts4)) model5 = RooAddPdf("model5", "s+b5", RooArgList(extb5, exts5)) #model6 = RooAddPdf("model6","s+b6",RooArgList(background6,signal),RooArgList(background_norm6,signal_norm)) #model7 = RooAddPdf("model7","s+b7",RooArgList(background7,signal),RooArgList(background_norm7,signal_norm)) rooDataHist = RooDataHist('rooDatahist', 'rooDathist', RooArgList(mjj), hData) if args.runFit: mframe = mjj.frame() rooDataHist.plotOn(mframe, ROOT.RooFit.Name("setonedata")) res = model.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Extended(kTRUE), RooFit.Strategy(args.fitStrategy)) model.plotOn(mframe, ROOT.RooFit.Name("model1"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kRed)) res2 = model2.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Extended(kTRUE), RooFit.Strategy(args.fitStrategy)) # model2.plotOn(mframe, ROOT.RooFit.Name("model2"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kOrange)) res3 = model3.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Extended(kTRUE), RooFit.Strategy(args.fitStrategy)) # model3.plotOn(mframe, ROOT.RooFit.Name("model3"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kGreen)) res4 = model4.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Extended(kTRUE), RooFit.Strategy(args.fitStrategy)) # model4.plotOn(mframe, ROOT.RooFit.Name("model4"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kBlue)) res5 = model5.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Extended(kTRUE), RooFit.Strategy(args.fitStrategy)) # model5.plotOn(mframe, ROOT.RooFit.Name("model5"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kViolet)) # res6 = model6.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy)) # model6.plotOn(mframe, ROOT.RooFit.Name("model6"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kPink)) # res7 = model7.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy)) # model7.plotOn(mframe, ROOT.RooFit.Name("model7"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kAzure)) rooDataHist2 = RooDataHist('rooDatahist2', 'rooDathist2', RooArgList(mjj), hData2) # rooDataHist2.plotOn(mframe, ROOT.RooFit.Name("data")) if args.pyes: c = TCanvas("c", "c", 800, 800) mframe.SetAxisRange(300., 1300.) c.SetLogy() # mframe.SetMaximum(10) # mframe.SetMinimum(1) mframe.Draw() fitname = args.pdir + '/5funcfit_m' + str(mass) + fstr + '.pdf' c.SaveAs(fitname) # cpull = TCanvas("cpull","cpull",800,800) # pulls = mframe.pullHist("data","model1") # pulls.Draw("ABX") # pullname = args.pdir+'/pull_m'+str(mass)+fstr+'.pdf' # cpull.SaveAs(pullname) # cpull2 = TCanvas("cpull2","cpull2",800,800) # pulls2 = mframe.pullHist("setonedata","model1") # pulls2.Draw("ABX") # pull2name = args.pdir+'/pull2_m'+str(mass)+fstr+'.pdf' # cpull2.SaveAs(pull2name) if args.widefit: mframew = mjj.frame() rooDataHist2.plotOn(mframew, ROOT.RooFit.Name("data")) res6 = model.fitTo(rooDataHist2, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy)) model.plotOn(mframew, ROOT.RooFit.Name("model1"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kRed)) res7 = model2.fitTo(rooDataHist2, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy)) model2.plotOn(mframew, ROOT.RooFit.Name("model2"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kOrange)) res8 = model3.fitTo(rooDataHist2, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy)) model3.plotOn(mframew, ROOT.RooFit.Name("model3"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kGreen)) res9 = model4.fitTo(rooDataHist2, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy)) model4.plotOn(mframew, ROOT.RooFit.Name("model4"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kBlue)) res10 = model5.fitTo(rooDataHist2, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy)) model5.plotOn(mframew, ROOT.RooFit.Name("model5"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.LineWidth(1), ROOT.RooFit.LineColor(ROOT.EColor.kViolet)) if args.pyes: c = TCanvas("c", "c", 800, 800) mframew.SetAxisRange(300., 1300.) c.SetLogy() # mframew.SetMaximum(10) # mframew.SetMinimum(1) mframew.Draw() fitname = args.pdir + '/5funcfittowide_m' + str( mass) + fstr + '.pdf' c.SaveAs(fitname) cpull = TCanvas("cpull", "cpull", 800, 800) pulls = mframew.pullHist("data", "model1") pulls.Draw("ABX") pullname = args.pdir + '/pullwidefit_m' + str( mass) + fstr + '.pdf' cpull.SaveAs(pullname) if args.chi2: fullInt = model.createIntegral(RooArgSet(mjj)) norm = dataInt / fullInt.getVal() chi1 = 0. fullInt2 = model2.createIntegral(RooArgSet(mjj)) norm2 = dataInt2 / fullInt2.getVal() chi2 = 0. fullInt3 = model3.createIntegral(RooArgSet(mjj)) norm3 = dataInt3 / fullInt3.getVal() chi3 = 0. fullInt4 = model4.createIntegral(RooArgSet(mjj)) norm4 = dataInt4 / fullInt4.getVal() chi4 = 0. fullInt5 = model5.createIntegral(RooArgSet(mjj)) norm5 = dataInt5 / fullInt5.getVal() chi5 = 0. for i in range(args.massMin, args.massMax): new = 0 new2 = 0 new3 = 0 new4 = 0 new5 = 0 height = hData.GetBinContent(i) xLow = hData.GetXaxis().GetBinLowEdge(i) xUp = hData.GetXaxis().GetBinLowEdge(i + 1) obs = height * (xUp - xLow) mjj.setRange("intrange", xLow, xUp) integ = model.createIntegral( RooArgSet(mjj), ROOT.RooFit.NormSet(RooArgSet(mjj)), ROOT.RooFit.Range("intrange")) exp = integ.getVal() * norm new = pow(exp - obs, 2) / exp chi1 = chi1 + new integ2 = model2.createIntegral( RooArgSet(mjj), ROOT.RooFit.NormSet(RooArgSet(mjj)), ROOT.RooFit.Range("intrange")) exp2 = integ2.getVal() * norm2 new2 = pow(exp2 - obs, 2) / exp2 chi2 = chi2 + new2 integ3 = model3.createIntegral( RooArgSet(mjj), ROOT.RooFit.NormSet(RooArgSet(mjj)), ROOT.RooFit.Range("intrange")) exp3 = integ3.getVal() * norm3 new3 = pow(exp3 - obs, 2) / exp3 chi3 = chi3 + new3 integ4 = model4.createIntegral( RooArgSet(mjj), ROOT.RooFit.NormSet(RooArgSet(mjj)), ROOT.RooFit.Range("intrange")) exp4 = integ4.getVal() * norm4 if exp4 != 0: new4 = pow(exp4 - obs, 2) / exp4 else: new4 = 0 chi4 = chi4 + new4 integ5 = model5.createIntegral( RooArgSet(mjj), ROOT.RooFit.NormSet(RooArgSet(mjj)), ROOT.RooFit.Range("intrange")) exp5 = integ5.getVal() * norm5 new5 = pow(exp5 - obs, 2) / exp5 chi5 = chi5 + new5 print "chi1 %d " % (chi1) print "chi2 %d " % (chi2) print "chi3 %d " % (chi3) print "chi4 %d " % (chi4) print "chi5 %d " % (chi5) if not args.decoBkg: print " " res.Print() res2.Print() res3.Print() res4.Print() res5.Print() # res6.Print() # res7.Print() # decorrelated background parameters for Bayesian limits if args.decoBkg: signal_norm.setConstant() res = model.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(args.fitStrategy)) res.Print() ## temp workspace for the PDF diagonalizer w_tmp = RooWorkspace("w_tmp") deco = PdfDiagonalizer("deco", w_tmp, res) # here diagonalizing only the shape parameters since the overall normalization is already decorrelated background_deco = deco.diagonalize(background) print "##################### workspace for decorrelation" w_tmp.Print("v") print "##################### original parameters" background.getParameters(rooDataHist).Print("v") print "##################### decorrelated parameters" # needed if want to evaluate limits without background systematics if args.fixBkg: w_tmp.var("deco_eig1").setConstant() w_tmp.var("deco_eig2").setConstant() if not args.fixP3: w_tmp.var("deco_eig3").setConstant() background_deco.getParameters(rooDataHist).Print("v") print "##################### original pdf" background.Print() print "##################### decorrelated pdf" background_deco.Print() # release signal normalization signal_norm.setConstant(kFALSE) # set the background normalization range to +/- 5 sigma bkg_val = background_norm.getVal() bkg_error = background_norm.getError() background_norm.setMin(bkg_val - 5 * bkg_error) background_norm.setMax(bkg_val + 5 * bkg_error) background_norm.Print() # change background PDF names background.SetName("background_old") background_deco.SetName("background") # needed if want to evaluate limits without background systematics if args.fixBkg: background_norm.setConstant() p1.setConstant() p2.setConstant() p3.setConstant() # ----------------------------------------- # dictionaries holding systematic variations of the signal shape hSig_Syst = {} hSig_Syst_DataHist = {} sigCDF = TGraph(hSig.GetNbinsX() + 1) # JES and JER uncertainties if args.jesUnc != None or args.jerUnc != None: sigCDF.SetPoint(0, 0., 0.) integral = 0. for i in range(1, hSig.GetNbinsX() + 1): x = hSig.GetXaxis().GetBinLowEdge(i + 1) integral = integral + hSig.GetBinContent(i) sigCDF.SetPoint(i, x, integral) if args.jesUnc != None: hSig_Syst['JESUp'] = copy.deepcopy(hSig) hSig_Syst['JESDown'] = copy.deepcopy(hSig) if args.jerUnc != None: hSig_Syst['JERUp'] = copy.deepcopy(hSig) hSig_Syst['JERDown'] = copy.deepcopy(hSig) # reset signal histograms for key in hSig_Syst.keys(): hSig_Syst[key].Reset() hSig_Syst[key].SetName(hSig_Syst[key].GetName() + '_' + key) # produce JES signal shapes if args.jesUnc != None: for i in range(1, hSig.GetNbinsX() + 1): xLow = hSig.GetXaxis().GetBinLowEdge(i) xUp = hSig.GetXaxis().GetBinLowEdge(i + 1) jes = 1. - args.jesUnc xLowPrime = jes * xLow xUpPrime = jes * xUp hSig_Syst['JESUp'].SetBinContent( i, sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime)) jes = 1. + args.jesUnc xLowPrime = jes * xLow xUpPrime = jes * xUp hSig_Syst['JESDown'].SetBinContent( i, sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime)) hSig_Syst_DataHist['JESUp'] = RooDataHist('hSig_JESUp', 'hSig_JESUp', RooArgList(mjj), hSig_Syst['JESUp']) hSig_Syst_DataHist['JESDown'] = RooDataHist( 'hSig_JESDown', 'hSig_JESDown', RooArgList(mjj), hSig_Syst['JESDown']) if args.jyes: c2 = TCanvas("c2", "c2", 800, 800) mframe2 = mjj.frame(ROOT.RooFit.Title("JES One Sigma Shifts")) mframe2.SetAxisRange(args.massMin, args.massMax) hSig_Syst_DataHist['JESUp'].plotOn( mframe2, ROOT.RooFit.Name("JESUP"), ROOT.RooFit.DrawOption("L"), ROOT.RooFit.DataError(2), ROOT.RooFit.LineStyle(1), ROOT.RooFit.MarkerColor(ROOT.EColor.kRed), ROOT.RooFit.LineColor(ROOT.EColor.kRed)) hSig_Syst_DataHist['JESDown'].plotOn( mframe2, ROOT.RooFit.Name("JESDOWN"), ROOT.RooFit.DrawOption("L"), ROOT.RooFit.DataError(2), ROOT.RooFit.LineStyle(1), ROOT.RooFit.MarkerColor(ROOT.EColor.kBlue), ROOT.RooFit.LineColor(ROOT.EColor.kBlue)) rooSigHist.plotOn(mframe2, ROOT.RooFit.DataError(2), ROOT.RooFit.Name("SIG"), ROOT.RooFit.DrawOption("L"), ROOT.RooFit.LineStyle(1), ROOT.RooFit.MarkerColor(ROOT.EColor.kGreen), ROOT.RooFit.LineColor(ROOT.EColor.kGreen)) mframe2.Draw() mframe2.GetXaxis().SetTitle("Dijet Mass (GeV)") leg = TLegend(0.7, 0.8, 0.9, 0.9) leg.SetFillColor(0) leg.AddEntry(mframe2.findObject("SIG"), "Signal Model", "l") leg.AddEntry(mframe2.findObject("JESUP"), "+1 Sigma", "l") leg.AddEntry(mframe2.findObject("JESDOWN"), "-1 Sigma", "l") leg.Draw() jesname = args.pdir + '/jes_m' + str(mass) + fstr + '.pdf' c2.SaveAs(jesname) # produce JER signal shapes if args.jesUnc != None: for i in range(1, hSig.GetNbinsX() + 1): xLow = hSig.GetXaxis().GetBinLowEdge(i) xUp = hSig.GetXaxis().GetBinLowEdge(i + 1) jer = 1. - args.jerUnc xLowPrime = jer * (xLow - float(mass)) + float(mass) xUpPrime = jer * (xUp - float(mass)) + float(mass) hSig_Syst['JERUp'].SetBinContent( i, sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime)) jer = 1. + args.jerUnc xLowPrime = jer * (xLow - float(mass)) + float(mass) xUpPrime = jer * (xUp - float(mass)) + float(mass) hSig_Syst['JERDown'].SetBinContent( i, sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime)) hSig_Syst_DataHist['JERUp'] = RooDataHist('hSig_JERUp', 'hSig_JERUp', RooArgList(mjj), hSig_Syst['JERUp']) hSig_Syst_DataHist['JERDown'] = RooDataHist( 'hSig_JERDown', 'hSig_JERDown', RooArgList(mjj), hSig_Syst['JERDown']) if args.jyes: c3 = TCanvas("c3", "c3", 800, 800) mframe3 = mjj.frame(ROOT.RooFit.Title("JER One Sigma Shifts")) mframe3.SetAxisRange(args.massMin, args.massMax) hSig_Syst_DataHist['JERUp'].plotOn( mframe3, ROOT.RooFit.Name("JERUP"), ROOT.RooFit.DrawOption("L"), ROOT.RooFit.DataError(2), ROOT.RooFit.LineStyle(1), ROOT.RooFit.MarkerColor(ROOT.EColor.kRed), ROOT.RooFit.LineColor(ROOT.EColor.kRed)) hSig_Syst_DataHist['JERDown'].plotOn( mframe3, ROOT.RooFit.Name("JERDOWN"), ROOT.RooFit.DrawOption("L"), ROOT.RooFit.DataError(2), ROOT.RooFit.LineStyle(1), ROOT.RooFit.MarkerColor(ROOT.EColor.kBlue), ROOT.RooFit.LineColor(ROOT.EColor.kBlue)) rooSigHist.plotOn(mframe3, ROOT.RooFit.DrawOption("L"), ROOT.RooFit.Name("SIG"), ROOT.RooFit.DataError(2), ROOT.RooFit.LineStyle(1), ROOT.RooFit.MarkerColor(ROOT.EColor.kGreen), ROOT.RooFit.LineColor(ROOT.EColor.kGreen)) mframe3.Draw() mframe3.GetXaxis().SetTitle("Dijet Mass (GeV)") leg = TLegend(0.7, 0.8, 0.9, 0.9) leg.SetFillColor(0) leg.AddEntry(mframe3.findObject("SIG"), "Signal Model", "l") leg.AddEntry(mframe3.findObject("JERUP"), "+1 Sigma", "l") leg.AddEntry(mframe3.findObject("JERDOWN"), "-1 Sigma", "l") leg.Draw() jername = args.pdir + '/jer_m' + str(mass) + fstr + '.pdf' c3.SaveAs(jername) # ----------------------------------------- # create a datacard and corresponding workspace postfix = (('_' + args.postfix) if args.postfix != '' else '') dcName = 'datacard_' + args.final_state + '_m' + str( mass) + postfix + '.txt' wsName = 'workspace_' + args.final_state + '_m' + str( mass) + postfix + '.root' w = RooWorkspace('w', 'workspace') getattr(w, 'import')(rooSigHist, RooFit.Rename("signal")) if args.jesUnc != None: getattr(w, 'import')(hSig_Syst_DataHist['JESUp'], RooFit.Rename("signal__JESUp")) getattr(w, 'import')(hSig_Syst_DataHist['JESDown'], RooFit.Rename("signal__JESDown")) if args.jerUnc != None: getattr(w, 'import')(hSig_Syst_DataHist['JERUp'], RooFit.Rename("signal__JERUp")) getattr(w, 'import')(hSig_Syst_DataHist['JERDown'], RooFit.Rename("signal__JERDown")) if args.decoBkg: getattr(w, 'import')(background_deco, ROOT.RooCmdArg()) else: getattr(w, 'import')(background, ROOT.RooCmdArg(), RooFit.Rename("background")) getattr(w, 'import')(background2, ROOT.RooCmdArg(), RooFit.Rename("background2")) getattr(w, 'import')(background3, ROOT.RooCmdArg(), RooFit.Rename("background3")) getattr(w, 'import')(background4, ROOT.RooCmdArg(), RooFit.Rename("background4")) getattr(w, 'import')(background5, ROOT.RooCmdArg(), RooFit.Rename("background5")) getattr(w, 'import')(background_norm, ROOT.RooCmdArg(), RooFit.Rename("background_norm")) getattr(w, 'import')(background2_norm, ROOT.RooCmdArg(), RooFit.Rename("background2_norm")) getattr(w, 'import')(background3_norm, ROOT.RooCmdArg(), RooFit.Rename("background3_norm")) getattr(w, 'import')(background4_norm, ROOT.RooCmdArg(), RooFit.Rename("background4_norm")) getattr(w, 'import')(background5_norm, ROOT.RooCmdArg(), RooFit.Rename("background5_norm")) getattr(w, 'import')(res) getattr(w, 'import')(res2) getattr(w, 'import')(res3) getattr(w, 'import')(res4) getattr(w, 'import')(res5) getattr(w, 'import')(background_norm, ROOT.RooCmdArg()) getattr(w, 'import')(signal_norm, ROOT.RooCmdArg()) getattr(w, 'import')(rooDataHist, RooFit.Rename("data_obs")) w.Print() w.writeToFile(os.path.join(args.output_path, wsName)) beffUnc = 0.3 boffUnc = 0.06 datacard = open(os.path.join(args.output_path, dcName), 'w') datacard.write('imax 1\n') datacard.write('jmax 1\n') datacard.write('kmax *\n') datacard.write('---------------\n') if args.jesUnc != None or args.jerUnc != None: datacard.write('shapes * * ' + wsName + ' w:$PROCESS w:$PROCESS__$SYSTEMATIC\n') else: datacard.write('shapes * * ' + wsName + ' w:$PROCESS\n') datacard.write('---------------\n') datacard.write('bin 1\n') datacard.write('observation -1\n') datacard.write('------------------------------\n') datacard.write('bin 1 1\n') datacard.write('process signal background\n') datacard.write('process 0 1\n') datacard.write('rate -1 1\n') datacard.write('------------------------------\n') datacard.write('lumi lnN %f -\n' % (1. + args.lumiUnc)) datacard.write('beff lnN %f -\n' % (1. + beffUnc)) datacard.write('boff lnN %f -\n' % (1. + boffUnc)) datacard.write('bkg lnN - 1.03\n') if args.jesUnc != None: datacard.write('JES shape 1 -\n') if args.jerUnc != None: datacard.write('JER shape 1 -\n') # flat parameters --- flat prior datacard.write('background_norm flatParam\n') if args.decoBkg: datacard.write('deco_eig1 flatParam\n') datacard.write('deco_eig2 flatParam\n') if not args.fixP3: datacard.write('deco_eig3 flatParam\n') else: datacard.write('p1 flatParam\n') datacard.write('p2 flatParam\n') if not args.fixP3: datacard.write('p3 flatParam\n') datacard.close() print '>> Datacards and workspaces created and stored in %s/' % ( os.path.join(os.getcwd(), args.output_path))
def main(): global beamEnergy # Parse all command line arguments using the argparse module. parser = argparse.ArgumentParser( description='PyRoot analysis demostrating the us of a DST.') parser.add_argument("dst_file", help="ROOT DST file to process") parser.add_argument("-o", "--output", help="Name of output pdf file") parser.add_argument("-m", "--mc", help="is MonteCarlo") parser.add_argument("-p", "--pulser", help="is Pulser") parser.add_argument("-e", "--energy", help="beam energy") args = parser.parse_args() # If an output file name was not specified, set a default name and warn # the user if args.output: output_file = args.output else: output_file = "analysis_output.root" print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to " print output_file print "[ HPS ANALYSIS ]: Output file is " + output_file isMC = False if args.mc: print "[ HPS ANALYSIS ]: Setting to run as MC" isMC = True isPulser = False if args.pulser: print "[ HPS ANALYSIS ]: Setting to run from a pulser file" isPulser = True if args.energy: print 'Setting beam energy to ' + args.energy beamEnergy = float(args.energy) myhist.setEnergyScales(beamEnergy) ################################# # Event Selection ################################ #clean up event first #### nominal selection nTrkMax = 10 nTrkMin = 2 nPosMax = 3 ###### two tracks (e+/e-) exactly # nTrkMax=2 # nTrkMin=2 # nPosMax=1 ###### more than 1 electron # nTrkMax=10 # nTrkMin=3 # nPosMax=1 ################### #v0 cuts v0Chi2 = 10 #ESum -- full region v0PzMax = 1.2 * beamEnergy v0PzMin = 0.55 * beamEnergy #ESum -- Radiative region # v0PzMax=1.2 # v0PzMin=0.80 v0PyMax = 0.2 #absolute value v0PxMax = 0.2 #absolute value v0VzMax = 25.0 # mm from target v0VyMax = 1.0 # mm from target v0VxMax = 2.0 # mm from target # track quality cuts trkChi2 = 10 beamCut = 0.8 * beamEnergy minPCut = 0.05 trkPyMax = 0.2 trkPxMax = 0.2 # slopeCut=0.03 slopeCut = 0.0 trkDeltaT = 4 #ns cluDeltaT = 2 #ns cluTrkDeltaT = 4 #ns ############## # ESum slices; upper limits nSlicesESum = 5 esumMin = 0.55 esumMax = 1.2 sliceSizeESum = 0.1 #100MeV starting at esumMin ############## trackKiller = False tkThreshold = 0.5 #GeV, below this start killing tracks tkThreshEff = 1.0 tkLowPoint = 0.20 tkLowPointEff = 0.40 # tkSlope=2.6 # tkIntercept=-0.04 #calculate tkSlope and Intercept tkSlope = (tkThreshEff - tkLowPointEff) / (tkThreshold - tkLowPoint) tkIntercept = tkThreshEff - tkSlope * tkThreshold ############## requireECalMatch = True requireECalFiducial = False requireECalSuperFiducial = False useGBL = True # Open the ROOT file # root_file = ROOT.TFile(str(args.dst_file)) # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all # other colletions # tree = root_file.Get("HPS_Event") #use a TChain print "[ HPS ANALYSIS ]: Reading in root chain from " + args.dst_file tree = ROOT.TChain("HPS_Event") tree.Add(str(args.dst_file) + "*") # Create an HpsEvent object in order to read the TClonesArray # collections hps_event = HpsEvent() b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event)) #--- Analysis ---# #----------------# #counters nEvents = 0 nPassBasicCuts = 0 nPassV0Cuts = 0 nPassTrkCuts = 0 nPassNCand = 0 nPassECalMatch = 0 nFakeTri = 0 if 1 == 0: extraElectronProb = 0.0 dataNele = 170.0 btNele = 1.4 hf = ROOT.TFile( "OutputHistograms/Data/hps_005772_pass6_useGBL_ECalMatch_SuperFiducialCut.root" ) hfMC = ROOT.TFile( "OutputHistograms/MC/beam-tri_HPS-EngRun2015-Nominal-v4-4_pass6_useGBL_ECalMatch_SuperFiducialCut.root" ) pele = ROOT.RooRealVar("pele", "pele", 0, 1) peleHist = hf.Get("raweleMom") peleMCHist = hfMC.Get("raweleMom") peleHist.Scale(1 / dataNele) peleMCHist.Scale(1 / btNele) peleHist.Add( peleMCHist, -1.0 ) #subtract the MC from the data to get the distribution of extra tracks...this is cheating! for i in xrange(0, peleHist.GetNbinsX()): print "Electron Momentum bin i = " + str(peleHist.GetBinContent(i)) if peleHist.GetBinContent(i) < 0: peleHist.SetBinContent(i, 0) peleHist.Print("V") peleDH = RooDataHist("peleDH", "peleDH", ROOT.RooArgList(pele), peleHist) peleDH.Print("V") extraElectronPdf = RooHistPdf("extraElectronPdf", "extraElectronPdf", ROOT.RooArgSet(pele), peleDH) print 'pdf is made...printing info' extraElectronPdf.Print("V") # if isMC and random.random()<extraElectronProb : #add an extra electron based on electron momentum print 'generating events' newElePData = extraElectronPdf.generate(ROOT.RooArgSet(pele), 1000000.0, True, False) newElePData.Print("V") seedCnt = 0 # Loop over all events in the file for entry in xrange(0, tree.GetEntries()): # Print the event number every 500 events if (entry + 1) % 10000 == 0: print "Event " + str(entry + 1) tree.GetEntry(entry) if not hps_event.isPair1Trigger() and not isMC and not isPulser: continue nEvents += 1 addFakeEle = False if 1 == 0: if isMC and random.random() < extraElectronProb: #add an extra electron based on electron momentum addFakeEle = True newEleP = newElePData.get(seedCnt).find("pele").getVal() seedCnt = seedCnt + 1 # print 'Inserting an electron with momentum = '+str(newEleP) # newEleCluster=hps_event.addEcalCluster(); # newEleTrack=hps_event.addTrack(); # print 'numbe of HpsParticles before = '+str(hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE)) # newEle=hps_event.addParticle(HpsParticle.FINAL_STATE_PARTICLE) # print 'numbe of HpsParticles after = '+str(hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE)) newEle = HpsParticle() newEle.setCharge(-1) newEle.setPDG(11) newEle.setEnergy(newEleP) sign = 1 if random.random() < 0.5: sign = -1 newEleMom = [ math.sin(0.03) * newEleP, sign * math.sin(0.04) * newEleP, math.cos(0.04) * newEleP ] newEle.setMomentum(np.array(newEleMom)) #fake track info newEleTrack = SvtTrack() newEleTrack.setTrackParameters(0.0, 0.03, 0.0001, sign * 0.04, 0.0) newEleTrack.setTrackTime(40.0) newEleTrack.setParticle(newEle) newEleTrack.setChi2(3.0) newEleTrack.setPositionAtEcal( np.array([300.0, sign * 50.0, 1350.0])) #fake cluster info newEleCluster = EcalCluster() newEleCluster.setEnergy(newEleP) foobar = [300.0, sign * 50.0, 1350.0] newEleCluster.setPosition(np.array(foobar, dtype='float32')) newEle.addTrack(newEleTrack) newEle.addCluster(newEleCluster) # print 'fake electron cluster x ' + str(newEle.getClusters().First().getPosition()[0]) # Loop over all tracks in the event npositrons = 0 n_tracks = 0 for track_n in xrange(0, hps_event.getNumberOfTracks()): track = hps_event.getTrack(track_n) if track is None: continue # if useGBL and track.getParticle().getType()<32 : continue # if not useGBL and track.getParticle().getType()>31 : continue if trkMatchAndFiducial( track.getParticle(), requireECalSuperFiducial) and trkMomentum( track, minPCut, beamCut ): # count only matched tracks in defined fiducial region n_tracks += 1 if track.getCharge() > 0: npositrons += 1 myhist.rawposMom.Fill(pMag(track.getMomentum())) else: myhist.raweleMom.Fill(pMag(track.getMomentum())) # findWABPair(track.getParticle(),hps_event) if addFakeEle: myhist.raweleMom.Fill(newEle.getEnergy()) n_tracks = n_tracks + 1 # print "nTracks = "+str(n_tracks)+"; nPositrons = "+str(npositrons) # if n_tracks/2.0>nTrkMax : continue #do this very dumb thing (divide by 2 to un-double count GBL tracks) # if n_tracks/2.0<2: continue myhist.nTrk.Fill(n_tracks) myhist.nPos.Fill(npositrons) myhist.nEle.Fill(n_tracks - npositrons) myhist.nClust.Fill(hps_event.getNumberOfEcalClusters()) if n_tracks > nTrkMax: continue if n_tracks < nTrkMin: continue if npositrons < 1 or npositrons > nPosMax: continue nPassBasicCuts += 1 # print "passed basic cuts" candidateList = [] bestCandidate = -99 nCandidate = 0 # loop over all v0 candidates... for uc_index in xrange( 0, hps_event.getNumberOfParticles(HpsParticle.UC_V0_CANDIDATE)): particle = hps_event.getParticle(HpsParticle.UC_V0_CANDIDATE, uc_index) if useGBL and particle.getType() < 32: continue if not useGBL and particle.getType() > 31: continue # print "found one..." vchi2 = particle.getVertexFitChi2() vposition = particle.getVertexPosition() vmomentum = particle.getMomentum() if vchi2 > v0Chi2: continue # use the measured sum of momentum # if vmomentum[2]>v0PzMax : continue # if vmomentum[2]<v0PzMin : continue #recon'ed vertex position cuts if abs(vposition[0]) > v0VxMax: continue if abs(vposition[1]) > v0VyMax: continue # if abs(vposition[2])>v0VzMax :continue # Only look at particles that have two daugther particles... daughter_particles = particle.getParticles() if daughter_particles.GetSize() != 2: continue # Only look at particles that are composed of e+e- pairs if daughter_particles.At(0).getCharge() * daughter_particles.At( 1).getCharge() > 0: continue # print "Passed daughter number cuts" electron = daughter_particles.At(0) positron = daughter_particles.At(1) if daughter_particles.At(0).getCharge() > 0: electron = daughter_particles.At(1) positron = daughter_particles.At(0) pEle = electron.getMomentum() pPos = positron.getMomentum() v0Sum = pMag(pSum(pEle, pPos)) #total momentum sum cuts if v0Sum > v0PzMax: continue if v0Sum < v0PzMin: continue nPassV0Cuts += 1 # print "Passed v0 cuts" ############# tracking cuts #momentum cuts...get rid of very soft or very hard tracks if pMag(pEle) > beamCut or pMag(pPos) > beamCut: continue if pMag(pEle) < minPCut or pMag(pPos) < minPCut: continue #top+bottom requirement if pEle[1] * pPos[1] > 0: continue # print 'looking at tracks now' # print len(electron.getTracks()) if len(electron.getTracks()) == 0 or len( positron.getTracks()) == 0: continue eleTrk = electron.getTracks().At(0) posTrk = positron.getTracks().At(0) if eleTrk is None or posTrk is None: continue # eleTrk.Print("v") #track timing if eleTrk.getTrackTime() - posTrk.getTrackTime() > trkDeltaT: continue #track slope (if any cut) if abs(eleTrk.getTanLambda()) < slopeCut or abs( posTrk.getTanLambda()) < slopeCut: continue # print 'satisfied timing cuts...' ############## # track killer part if isMC and trackKiller: if pMag(pEle) < tkThreshold: #electron tkEff = tkSlope * pMag(pEle) + tkIntercept if random.random() > tkEff: continue elif random.random( ) > tkThreshEff: #allow for a flat killer above threshold continue if pMag(pPos) < tkThreshold: # positron tkEff = tkSlope * pMag(pPos) + tkIntercept if random.random() > tkEff: continue elif random.random( ) > tkThreshEff: #allow for a flat killer above threshold continue # end of track killer ############## nPassTrkCuts += 1 ############## # ECAL matching and timing cuts...also fiducial region cuts... if requireECalMatch: if positron.getClusters().GetEntries() == 0: continue if electron.getClusters().GetEntries() == 0: continue posCluster = positron.getClusters().First() eleCluster = electron.getClusters().First() if eleCluster.getClusterTime() - posCluster.getClusterTime( ) > cluDeltaT: continue if eleTrk.getTrackTime() - eleCluster.getClusterTime( ) + 43.5 > cluTrkDeltaT: continue if posTrk.getTrackTime() - posCluster.getClusterTime( ) + 43.5 > cluTrkDeltaT: continue if requireECalFiducial: #ANTI-fiducial cut # if myhist.inFiducialRegion(posCluster.getPosition()[0],posCluster.getPosition()[1]) : # continue # if myhist.inFiducialRegion(eleCluster.getPosition()[0],eleCluster.getPosition()[1]) : # continue #Fiducial cut if not myhist.inFiducialRegion( posCluster.getPosition()[0], posCluster.getPosition()[1]): continue if not myhist.inFiducialRegion( eleCluster.getPosition()[0], eleCluster.getPosition()[1]): continue if requireECalSuperFiducial: if not myhist.inSuperFiducialRegion( posCluster.getPosition()[0], posCluster.getPosition()[1]): continue if not myhist.inSuperFiducialRegion( eleCluster.getPosition()[0], eleCluster.getPosition()[1]): continue nPassECalMatch += 1 ############## #Passed the cuts..append the candidate index findWABPair(electron, hps_event) candidateList.append(uc_index) numCands = len(candidateList) if addFakeEle: for track_n in xrange(0, hps_event.getNumberOfTracks()): track = hps_event.getTrack(track_n) if track is None: continue if trkMatchAndFiducial(track.getParticle()) and trkMomentum( track, minPCut, beamCut ) and track.getCharge > 0 and newEle.getMomentum( )[1] * track.getMomentum( )[1] < 0: # get positron in fudicial region; make sure it's in opposite quadrant myhist.eSum.Fill(newEle.getEnergy() + pMag(track.getMomentum())) numCands += 1 if len(candidateList) == 0: # print 'made a new trident event' nFakeTri += 1 myhist.nCand.Fill(numCands) ######################### # found some candidates...lets fill plots... ######################### for index in range(0, len(candidateList)): particle = hps_event.getParticle(HpsParticle.TC_V0_CANDIDATE, candidateList[index]) myhist.fillCandidateHistograms(particle) myhist.nTrkCand.Fill(n_tracks) myhist.nPosCand.Fill(npositrons) myhist.nEleCand.Fill(n_tracks - npositrons) myhist.nClustCand.Fill(hps_event.getNumberOfEcalClusters()) # if(nPassTrkCuts>0): myhist.saveHistograms(output_file) print "******************************************************************************************" print "Number of Events:\t\t", nEvents, "\t\t\t", float( nEvents) / nEvents, "\t\t\t", float(nEvents) / nEvents print "N(particle) Cuts:\t\t", nPassBasicCuts, "\t\t\t", float( nPassBasicCuts) / nEvents, "\t\t\t", float(nPassBasicCuts) / nEvents print "V0 Vertex Cuts:\t\t", nPassV0Cuts, "\t\t\t", float( nPassV0Cuts) / nPassBasicCuts, "\t\t\t", float(nPassV0Cuts) / nEvents print "Tracking Cuts:\t\t", nPassTrkCuts, "\t\t\t", float( nPassTrkCuts) / nPassV0Cuts, "\t\t\t", float(nPassTrkCuts) / nEvents print "ECal Match Cuts:\t\t", nPassECalMatch, "\t\t\t", float( nPassECalMatch) / nPassTrkCuts, "\t\t\t", float( nPassECalMatch) / nEvents print "Number of Fake Events Added: \t\t", nFakeTri, "\t\t\t", float( nFakeTri) / nPassECalMatch
def get_fitted_normalisation_from_ROOT(channel, input_files, variable, met_type, b_tag_bin): results = {} initial_values = {} templates = {} for variable_bin in variable_bins_ROOT[variable]: histograms = get_histograms(channel, input_files, variable=variable, met_type=met_type, variable_bin=variable_bin, b_tag_bin=b_tag_bin, rebin=measurement_config.rebin) # create signal histograms h_eta_signal = histograms['TTJet'] + histograms['SingleTop'] N_ttbar_before_fit = histograms['TTJet'].Integral() N_SingleTop_before_fit = histograms['SingleTop'].Integral() N_vjets_before_fit = histograms['V+Jets'].Integral() N_qcd_before_fit = histograms['QCD'].Integral() N_signal_before_fit = N_ttbar_before_fit + N_SingleTop_before_fit N_ttbar_error_before_fit = sum(histograms['TTJet'].errors()) N_SingleTop_error_before_fit = sum(histograms['SingleTop'].errors()) N_vjets_error_before_fit = sum(histograms['V+Jets'].errors()) N_QCD_error_before_fit = sum(histograms['QCD'].errors()) if (N_SingleTop_before_fit != 0): TTJet_SingleTop_ratio = N_ttbar_before_fit / N_SingleTop_before_fit else: print 'Bin ', variable_bin, ': ttbar/singleTop ratio undefined for %s channel! Setting to 0.' % channel TTJet_SingleTop_ratio = 0 leptonAbsEta = RooRealVar("leptonAbsEta", "leptonAbsEta", 0., 2.4) # this has to move to dps.utils.Fitting.py vars = RooArgList() vars.add(leptonAbsEta) vars_set = RooArgSet() vars_set.add(leptonAbsEta) n_event_obs = histograms['data'].Integral() lowerBound = 0. upperBound = n_event_obs + 10 * sqrt(n_event_obs) n_init = n_event_obs / 2. data = RooDataHist("data", "dataset with leptonAbsEta", vars, histograms['data']) rh_vj = RooDataHist("rh_vj", "vj", vars, histograms['V+Jets']) rh_qcd = RooDataHist("rh_qcd", "qcd", vars, histograms['QCD']) rh_signal = RooDataHist("rh_signal", "signal", vars, h_eta_signal) pdf_vj = RooHistPdf("pdf_vj", "V+Jets pdf", vars_set, rh_vj, 0) pdf_qcd = RooHistPdf("pdf_qcd", "QCD pdf ", vars_set, rh_qcd, 0) pdf_signal = RooHistPdf("pdf_signal", "single top pdf", vars_set, rh_signal, 0) # RooRealVar(const char *name, const char *title, Double_t value, Double_t minValue, Double_t maxValue, const char *unit) : nSignal = RooRealVar("nSignal", "number of single top + ttbar events", N_signal_before_fit, lowerBound, upperBound, "event") nvj = RooRealVar("nvj", "number of V+Jets bgnd events", N_vjets_before_fit, lowerBound, upperBound, "event") nqcd = RooRealVar("nqcd", "number of QCD bgnd events", N_QCD_error_before_fit, lowerBound, upperBound, "event") model = RooAddPdf("model", "sig+vj+qcd", RooArgList(pdf_signal, pdf_vj, pdf_qcd), RooArgList(nSignal, nvj, nqcd)) vj_constraint = RooGaussian("nvj_constraint", "nvj_constraint", nvj, RooFit.RooConst(N_vjets_before_fit), RooFit.RooConst(0.5 * N_vjets_before_fit)) qcd_constraint = RooGaussian("nqcd_constraint", "nqcd_constraint", nqcd, RooFit.RooConst(N_qcd_before_fit), RooFit.RooConst(2 * N_qcd_before_fit)) model_with_constraints = RooProdPdf( "model_with_constraints", "model with gaussian constraints", RooArgSet(model, vj_constraint, qcd_constraint), RooLinkedList()) model_with_constraints.fitTo(data, RooFit.Minimizer( "Minuit2", "Migrad")) #WARNING: number of cores changes the results!!! # nll = model.createNLL(data, RooFit.NumCPU(2)) # RooMinuit(nll).migrad() # frame1 = nSignal.frame(RooFit.Bins(100), RooFit.Range(lowerBound, n_event_obs), RooFit.Title("LL and profileLL in nSignal")) # nll.plotOn(frame1, RooFit.ShiftToZero()) # frame2 = nvj.frame(RooFit.Bins(100), RooFit.Range(lowerBound, n_event_obs), RooFit.Title("LL and profileLL in nvj")) # nll.plotOn(frame2, RooFit.ShiftToZero()) # frame3 = nqcd.frame(RooFit.Bins(100), RooFit.Range(lowerBound, n_event_obs), RooFit.Title("LL and profileLL in nqcd")) # nll.plotOn(frame3, RooFit.ShiftToZero()) # # pll_nSignal = nll.createProfile(nSignal) # pll_nSignal.plotOn(frame1, RooFit.LineColor(2)) # frame1.SetMinimum(0) # frame1.SetMaximum(3) # # pll_nvj = nll.createProfile(nvj) # pll_nvj.plotOn(frame2, RooFit.LineColor(2)) # frame2.SetMinimum(0) # frame2.SetMaximum(3) # # pll_nqcd = nll.createProfile(nqcd) # pll_nqcd.plotOn(frame3, RooFit.LineColor(2)) # frame3.SetMinimum(0) # frame3.SetMaximum(3) # c = TCanvas("profilell","profilell",1200, 400) # c.Divide(3) # c.cd(1) # frame1.Draw() # c.cd(2) # frame2.Draw() # c.cd(3) # frame3.Draw() # c.SaveAs('profileLL.png') # model.fitTo(data, RooFit.Minimizer("Minuit2", "Migrad"), RooFit.NumCPU(1))#WARNING: number of cores changes the results!!! fit_results = {} fit_results['signal'] = (nSignal.getVal(), nSignal.getError()) fit_results['QCD'] = ufloat(nqcd.getVal(), nqcd.getError()) fit_results['V+Jets'] = ufloat(nvj.getVal(), nvj.getError()) N_ttbar, N_SingleTop = decombine_result(fit_results['signal'], TTJet_SingleTop_ratio) fit_results['signal'] = ufloat(nSignal.getVal(), nSignal.getError()) fit_results['TTJet'] = ufloat(N_ttbar) fit_results['SingleTop'] = ufloat(N_SingleTop) if results == {}: # empty for sample in fit_results.keys(): results[sample] = [fit_results[sample]] else: for sample in fit_results.keys(): results[sample].append(fit_results[sample]) return results, None, None
mmgMassFunc = w.factory('''FormulaVar::mmgMassFunc( "((mmgMass - mmgMode) / mmgScale + mmgMode) - fPho*phoScale/100.", {mmgMass, mmgMode[91.2,70,110], mmgScale[1.,0.1,5], fPho, phoScale} )''') mmgMode = w.var('mmgMode') mmgScale = w.var('mmgScale') ## Get the nominal model for translation, use rho=2 model = RooKeysPdf('model', 'model', mmgMass, mmgData, RooKeysPdf.NoMirror, 2) ## Sample nominal model to binned data, no Poisson fluctuation modelHist = model.createHistogram('mmgMass', 10000) modelDH = RooDataHist('modelDH', 'modelDH', RooArgList(mmgMass), modelHist) ## Use the sampled model to build a transformed model, interpolation order=2 tmodel = RooHistPdf('tmodel', 'tmodel', RooArgList(mmgMassFunc), RooArgList(mmgMass), modelDH, 2) ## Find the mode of the tmodel. mmgMode.setVal(modelHist.GetBinCenter(modelHist.GetMaximumBin())) mmgMode.setConstant(True) fPho.setConstant(True) ## Fit the photon scale phoScale.setConstant(False) mmgScale.setConstant(True) ## Make plots canvases.next('nominal') mmgFrame = mmgMass.frame(Range(60,120)) mmgData.plotOn(mmgFrame)
DTF_D0sPi_M.setMin(2000) varset_small = RooArgSet("varset_small") varset_small.add(LOG_D0_IPCHI2_OWNPV) varset_small.add(Dst_DTF_D0_CTAU) varset_small.add(DTF_D0sPi_M) #Create histogram for time bin 0 dataset_RS_0 = wsp.data("dataset_RS") dataset_RS_0.SetName("dataset_RS_0") print "dataset_RS_0 extraction took "+str(datetime.now()-start)+" \n" start = datetime.now() hist_RS_0 = RooDataHist("hist_RS_0","hist_RS_0", RooArgSet(LOG_D0_IPCHI2_OWNPV), dataset_RS_0) print "RooDataHist creation took "+str(datetime.now()-start)+" \n" start = datetime.now() shape_RS_0 = RooHistPdf("shape_RS_0", "shape_RS_0", RooArgSet(LOG_D0_IPCHI2_OWNPV), hist_RS_0) print "RooHistPdf creation took "+str(datetime.now()-start)+" \n" h_0 = hist_RS_0.createHistogram("LOG_D0_IPCHI2_OWNPV", 100) #Fage function used to fit signal distribution #Fix asymmetry paramters from 0 bin, leave mean and width float. fage_mu = RooRealVar("fage_mu", "fage_mu", 0.5, 0., 1.) fage_sigma = RooRealVar("fage_sigma", "fage_sigma", 2.0, 0.5, 5.) fage_epsilon = RooRealVar("fage_epsilon", "fage_epsilon", 0., -1., 1.) fage_rhol = RooRealVar("fage_rhol", "fage_rhol", 1., 0.1, 10) fage_rhor = RooRealVar("fage_rhor", "fage_rhor", 1., 0.1, 10) s_fage = ROOT.fage("s_fage", "s_fage", LOG_D0_IPCHI2_OWNPV, fage_mu, fage_sigma, fage_epsilon, fage_rhol, fage_rhor) fit_hists_0 = s_fage.fitTo(hist_RS_0,RooFit.SumW2Error(True),RooFit.Save()) fage_epsilon.setConstant(True) fage_rhol.setConstant(True) fage_rhor.setConstant(True)
w.var('gm').setVal(-3.) w.var('gs').setVal(2) data2 = g.generate(ArgSet(x), 10000) w.var('gm').setVal(0.) w.var('gs').setVal(1.) ## 3. Use data 1 to build Keys PDF k1(x|s1,m1) k = KeysPdf('k', 'k', x, data1, KeysPdf.NoMirror, 2) ## 4. Use k to build HistPDF with _transformed_ x variable t = (x-m)/s ## h1((x-hm)/hs|m1,s1) t = w.factory('FormulaVar::t("(x - hm) / hs", {x, hm[0,-5,5], hs[1,0.1,3]})') hist = k.createHistogram('x', 10000) dh = DataHist('dh', 'dh', ArgList(x), hist) h = HistPdf('h', 'h', ArgList(t), ArgList(x), dh, 2) ## 5. Plot results f1 = x.frame() f1.SetTitle('Training Data') data1.plotOn(f1) g.plotOn(f1) k.plotOn(f1, LineColor(kRed), LineStyle(kDashed)) h.plotOn(f1, LineColor(kBlack), LineStyle(kDashed)) canvases.next('Training_Data') f1.Draw() ## 6. Fit h1 to data2 to simulate a "measurement" of m2, s2. h.fitTo(data2) f2 = x.frame()
def getMistagBinBounds(config, mistag, mistagdistrib): """ suggest a binning for turning per-event mistag into mistag categories This routine takes a mistag observable and a PDF or data set, and suggests a number of mistag category boundaries which have approximately equal statistics in each category. config -- config dictionary mistag -- mistag observable (eta) mistagdistrib -- a PDF or a RooDataSet returns a (python) list of mistag category bin bounds relevant configuration dictionary keys: 'NMistagCategories': number of mistag categories for which to suggest a set of bin bounds """ mistag.setBins(1000, 'MistagBinBounds') from ROOT import RooArgSet, RooHistPdf, RooDataHist if (mistagdistrib.InheritsFrom('RooAbsData') and not mistagdistrib.InheritsFrom('RooDataHist')): # ok, unbinned data set, get only tagged events, and form a binned clone argset = RooArgSet(mistag) mistagdistrib = mistagdistrib.reduce( RooFit.SelectVars(argset), RooFit.cut('0 != qt')) ROOT.SetOwnership(mistagdistrib, True) dhist = RooDataHist( '%s_binned' % mistagdistrib.GetName(), '%s_binned' % mistagdistrib.GetName(), mistagdistrib.get(), 'MistagBinBounds') dhist.add(mistagdistrib) mistagdistrib = dhist if mistagdistrib.InheritsFrom('RooAbsData'): # convert a binned dataset to a RooHistPdf dhist = mistagdistrib mistagdistrib = RooHistPdf('%s_pdf' % dhist.GetName(), '%s_pdf' % dhist.GetName(), RooArgSet(mistag), dhist) if (mistagdistrib.InheritsFrom('RooAbsPdf')): # use createCdf to obtain the CDF cdfroofit = mistagdistrib.createCdf( RooArgSet(mistag), RooArgSet(mistag)) ROOT.SetOwnership(cdfroofit, True) def cdf(x): oldval = mistag.getVal() mistag.setVal(x) retVal = cdfroofit.getVal() mistag.setVal(oldval) return retVal if (mistagdistrib.InheritsFrom('RooHistPdf') and (abs(cdf(mistag.getMin())) > 1e-9 or abs(cdf(mistag.getMax()) - 1.) > 1e-9)): # createCdf does not work properly for RooHistPdf in older ROOT # versions because RooHistPdf does not support integrals over # subranges, so we have to fake this functionality until it's # supported by RooFit upstream # # capture histogram bin boundaries and contents print 'WARNING: Your version of RooFit still has buggy analytical ' \ 'integrals for RooHistPdf - activating workaround.' binboundlist = mistagdistrib.binBoundaries( mistag, mistag.getMin(), mistag.getMax()) ROOT.SetOwnership(binboundlist, True) binbounds = [ v for v in binboundlist ] del binboundlist bincontents = [ ] oldval = mistag.getVal() for i in xrange(0, len(binbounds) - 1): mistag.setVal(0.5 * (binbounds[i] + binbounds[i + 1])) bincontents.append(mistagdistrib.getValV(RooArgSet(mistag))) mistag.setVal(oldval) # build CDF from histogram def cdf(x): s = 0. for i in xrange(0, len(binbounds) - 1): if x < binbounds[i]: break elif x >= binbounds[i + 1]: s += bincontents[i] else: s += (bincontents[i] * (x - binbounds[i]) / (binbounds[i + 1] - binbounds[i])) break return s # find x for which f(x) = y by bisection def mybisect(y, f, lo, hi): initdx = abs(hi - lo) flo, fhi = f(lo) - y, f(hi) - y if 0. == flo: return lo elif 0. == fhi: return hi mid = .5 * (lo + hi) while (abs(hi - lo) > 1e-15 and abs(hi - lo) / initdx > 1e-15): fmid = f(mid) - y if 0. == fmid: break elif flo * fmid < 0.: hi, fhi = mid, fmid elif fmid * fhi < 0.: lo, flo = mid, fmid else: raise ValueError('no sign change in f(x) between %g and %g' % (lo, hi)) mid = .5 * (lo + hi) return mid # find binning with roughly same stats by inverting the CDF by bisection lo, hi, binsum = mistag.getMin(), mistag.getMax(), cdf(mistag.getMax()) retVal = [ lo ] for i in xrange(1, config['NMistagCategories']): retVal.append(mybisect(binsum * float(i) / float(config['NMistagCategories']), cdf, lo, hi)) retVal.append(hi) print 'INFO: suggested mistag category bounds: %s' % str(retVal) return retVal
args.signal_model, int(mass)) # get signal shape hSig = signal_shapes_file.Get("h_" + args.signal_model + "_" + str(int(mass))) # normalize signal shape to the expected event yield (works even if input shapes are not normalized to unity) hSig.Scale( signalCrossSection * lumi / hSig.Integral() ) # divide by a number that provides roughly an r value of 1-10 print "[debug] hSig.Integral() = " + str(hSig.Integral()) print "[debug] hSig.GetMean() = " + str(hSig.GetMean()) print "[debug] hSig.GetRMS() = " + str(hSig.GetRMS()) rooSigHist = RooDataHist('rooSigHist', 'rooSigHist', RooArgList(mjj), hSig) rooSigHist.Print() signal = RooHistPdf('signal', 'signal', RooArgSet(mjj), rooSigHist) signal.Print() signal_norm = RooRealVar('signal_norm', 'signal_norm', 0, -1e+05, 1e+05) if args.fitBonly: signal_norm.setConstant() signal_norm.Print() p1 = RooRealVar('p1', 'p1', args.p1, 0., 100.) p2 = RooRealVar('p2', 'p2', args.p2, 0., 60.) p3 = RooRealVar('p3', 'p3', args.p3, -10., 10.) if args.fixP3: p3.setConstant() background = RooGenericPdf( 'background', '(pow(1-@0/%.1f,@1)/pow(@0/%.1f,@2+@3*log(@0/%.1f)))' % (sqrtS, sqrtS, sqrtS), RooArgList(mjj, p1, p2, p3))
nqcd = RooRealVar("nqcd", "number of qcd events", n_qcd, n_qcd, n_qcd) #k2nqcd = RooFormulaVar("k2nqcd","number of qcd events"," ",RooArgList(k2,nqcd)) data = RooDataHist("data", "data set with (x)", RooArgList(x), h_data_m3HistS) ttbar = RooDataHist("ttbar", "data set with (x)", RooArgList(x), h_ttbar_m3HistS) background = RooDataHist("background", "data set with (x)", RooArgList(x), h_background_m3Hist) qcd = RooDataHist("qcd", "data set with (x)", RooArgList(x), h_qcd_data_m3HistS) # RooHistPdf::RooHistPdf(const char* name, const char* title, const RooArgSet& vars, const RooDataHist& dhist, int intOrder = 0) => #print "ttbar type: "+str(type(ttbar)) #print "rooArglist(x):"+str(type(RooArgList(x))) ttbarpdf = RooHistPdf("ttbarpdf", "ttbarpdf", RooArgList(x), RooArgList(x), ttbar) backgroundpdf = RooHistPdf("backgroundpdf", "backgroundpdf", RooArgList(x), RooArgList(x), background) qcdpdf = RooHistPdf("qcdpdf", "qcdpdf", RooArgList(x), RooArgList(x), qcd) #ttbarpdf = RooHistPdf(ttbar,"ttbarpdf") #backgroundpdf = RooHistPdf(background,"backgroundpdf") model = RooAddPdf("model", "model", RooArgList(ttbarpdf, backgroundpdf), RooArgList(k1)) model2 = RooAddPdf("model2", "model2", RooArgList(model), RooArgList(k2nmc)) model3 = RooAddPdf("model3", "model3", RooArgList(model2, qcdpdf), RooArgList(k2nmc, nqcd)) #model3 = RooAddPdf("model3", "model3",RooArgList( model, qcdpdf), RooArgList(k2nmc,k2nqcd)) model3.fitTo(data)
def morph(hist1, hist2, mass1, mass2, targetMass, debug = False): from ROOT import gROOT, RooRealVar, RooIntegralMorph,\ kRed,kBlue,kViolet, RooDataHist, RooArgSet,\ RooArgList, RooHistPdf, RooAbsReal, RooFit import re if mass1<mass2: histLow = hist1 massLow = mass1 histHigh = hist2 massHigh = mass2 else: histLow = hist2 massLow = mass2 histHigh = hist1 massHigh = mass1 x = RooRealVar("x", "x", histLow.GetXaxis().GetXmin(), histLow.GetXaxis().GetXmax()) mAlpha = 1.0 - float(targetMass-massLow)/float(massHigh-massLow) print 'alpha:',mAlpha, newIntegral = histLow.Integral() + \ (targetMass - massLow) * \ (histHigh.Integral()-histLow.Integral()) / \ (massHigh-massLow) print 'low integral:', histLow.Integral(), \ 'high integral:', histHigh.Integral(), \ 'new integral:', newIntegral newHistLow = RooDataHist("sigHistLow_hist", "sigHistLow_hist", RooArgList(x), histLow); sigHistLow = RooHistPdf("sigHistLow", "sigHistLow", RooArgList(x), RooArgList(x), newHistLow); newHistHigh = RooDataHist("sigHistHigh_hist", "sigHistHigh_hist", RooArgList(x), histHigh); sigHistHigh = RooHistPdf("sigHistHigh", "sigHistHigh", RooArgList(x), RooArgList(x), newHistHigh); #x.Print("v") x.setBins( histLow.GetNbinsX(), "cache") alpha_morph = RooRealVar("alpha_morph", "#alpha_{morph}", mAlpha, 0., 1.) alpha_morph.setBins(10,"cache") ; sigModel = RooIntegralMorph("sigModel", "sigModel", sigHistLow, sigHistHigh, x, alpha_morph) if (debug): from ROOT import gPad, RooFit frame = x.frame() sigHistLow.plotOn(frame, RooFit.LineColor(kRed+1), RooFit.LineStyle(2)) sigHistHigh.plotOn(frame, RooFit.LineColor(kBlue+1), RooFit.LineStyle(2)) sigModel.plotOn(frame, RooFit.LineColor(kViolet+1), RooFit.LineStyle(9)) frame.Draw() gPad.Update() gPad.WaitPrimitive() morphHist = sigModel.createHistogram(re.sub(r'\d+', '%i' % targetMass, hist1.GetName()), x, RooFit.Binning(histLow.GetNbinsX())) morphHist.Scale(newIntegral/morphHist.Integral()) morphHist.SetName(re.sub(r'\d+', '%i' % targetMass, hist1.GetName())) # if debug: # morphHist.Print() return morphHist
## mmgMass.setRange(mmgMass.getMin() - mmgMassRangeMean, ## mmgMass.getMax() - mmgMassRangeMean) phoEResFuncOfMMGMassShifted = w.factory( """FormulaVar::phoEResFuncOfMMGMassShifted( "(mmgMassShifted - phoMean)/phoWidth + ({mcscale})", {{mmgMassShifted, phoMean, phoWidth}} )""".format( mcscale=phoEScaleMC ) ) # phoEResFuncOfMMGMass = w.factory('FormulaVar::phoEResFuncOfMMGMass2("mmgMass ", {mmgMass})') ## Plug in the mass smering mean and width into the smearing shape phoSmear = RooHistPdf( "phoSmear", "phoSmear", RooArgList(phoEResFuncOfMMGMassShifted), RooArgList(phoERes), phoEResDataHist, 2 ) ## TODO: use RooCustomizer to transform phoEResShape ## Define the transform such that the phoEResShape is always evaluated ## inside of it's boundaries. cust = RooCustomizer(phoEResShape, "transformed") cust.replaceArg(phoERes, phoEResFuncOfMMGMassShifted) phoSmear2 = cust.build() w.Import(phoSmear) ## Apply photon smearing to the theory mmgMassShifted.setRange(-30, 30) mmgMassShifted.setBins(10000, "fft") theoryXphoSmear = w.factory("FCONV::theoryXphoSmear(mmgMassShifted, phoSmear, theory)") ## mmgMassPhoGenEFunc = w.factory('FormulaVar::mmgMassPhoGenEFunc("mmgMass", {mmgMass})')
def fit(self): fit_variable = RooRealVar("fit_variable", "fit_variable", self.fit_boundaries[0], self.fit_boundaries[1]) fit_variable.setBins(self.histograms[self.data_label].nbins()) variables = RooArgList() variables.add(fit_variable) variable_set = RooArgSet() variable_set.add(fit_variable) roofit_histograms = {} roofit_pdfs = {} roofit_variables = {} N_min = 0. N_max = self.normalisation[self.data_label] * 2. pdf_arglist = RooArgList() variable_arglist = RooArgList() roofit_histograms[self.data_label] = RooDataHist( self.data_label, self.data_label, variables, self.histograms[self.data_label]) for sample in self.samples: roofit_histogram = RooDataHist(sample, sample, variables, self.histograms[sample]) roofit_histograms[sample] = roofit_histogram roofit_pdf = RooHistPdf('pdf' + sample, 'pdf' + sample, variable_set, roofit_histogram) roofit_pdfs[sample] = roofit_pdf roofit_variable = RooRealVar(sample, sample + " events", self.normalisation[sample], N_min, N_max) roofit_variables[sample] = roofit_variable pdf_arglist.add(roofit_pdf) variable_arglist.add(roofit_variable) model = RooAddPdf('model', 'sum of all known', pdf_arglist, variable_arglist) use_model = model if self.constraints: arg_set = RooArgSet(model) constraints = self.get_fit_normalisation_constraints( model, roofit_variables) for constraint in constraints: arg_set.add(constraint) model_with_constraints = RooProdPdf( "model_with_constraints", "model with gaussian constraints", arg_set, RooLinkedList()) use_model = model_with_constraints if self.method == 'TMinuit': #WARNING: number of cores changes the results!!! self.saved_result = use_model.fitTo( roofit_histograms[self.data_label], RooFit.Minimizer("Minuit2", "Migrad"), RooFit.NumCPU(1), RooFit.Extended(), RooFit.Save(), ) results = {} for sample in self.samples: results[sample] = (roofit_variables[sample].getVal(), roofit_variables[sample].getError()) self.results = results
## Shift the mass range to be symmetric around zero ## mmgMassRangeMean = 0.5 * (mmgMass.getMin() + mmgMass.getMax()) ## mmgMass.setRange(mmgMass.getMin() - mmgMassRangeMean, ## mmgMass.getMax() - mmgMassRangeMean) phoEResFuncOfMMGMassShifted = w.factory( '''FormulaVar::phoEResFuncOfMMGMassShifted( "(mmgMassShifted - phoMean)/phoWidth + ({mcscale})", {{mmgMassShifted, phoMean, phoWidth}} )'''.format(mcscale = phoEScaleMC)) #phoEResFuncOfMMGMass = w.factory('FormulaVar::phoEResFuncOfMMGMass2("mmgMass ", {mmgMass})') ## Plug in the mass smering mean and width into the smearing shape phoSmear = RooHistPdf('phoSmear', 'phoSmear', RooArgList(phoEResFuncOfMMGMassShifted), RooArgList(phoERes), phoEResDataHist, 2) w.Import(phoSmear) ## Apply photon smearing to the theory mmgMassShifted.setRange(-30, 30) mmgMassShifted.setBins(10000, 'fft') theoryXphoSmear = w.factory('FCONV::theoryXphoSmear(mmgMassShifted, phoSmear, theory)') ## mmgMassPhoGenEFunc = w.factory('FormulaVar::mmgMassPhoGenEFunc("mmgMass", {mmgMass})') ## theoryXphoSmear = RooFFTConvPdf('theoryXphoSmear', 'theoryXphoSmear', ## mmgMassPhoGenEFunc, mmgMassPhoGenE, theory, phoSmear) ## Fit Smeared theory to data #theoryXphoSmear.fitTo(mmgData, Range(70,110))
def change_dataset_to_histpdf(workspace,x,dataset): datahist = dataset.binnedClone(dataset.GetName()+"_binnedClone",dataset.GetName()+"_binnedClone") histpdf = RooHistPdf(dataset.GetName()+"_histpdf",dataset.GetName()+"_histpdf",RooArgSet(x),datahist) getattr(workspace,'import')(histpdf)
def shapeCards( process, isData, datahistosFile, histosFile, signalHistosFile, signalSample, hist, signalMass, minMass, maxMass, jesValue, jerValue, lumiUnc, outputName ): """function to run Roofit and save workspace for RooStats""" warnings.filterwarnings( action='ignore', category=RuntimeWarning, message='.*class stack<RooAbsArg\*,deque<RooAbsArg\*> >' ) hSignal = signalHistosFile.Get(hist+'_'+signalSample) hSignal.Rebin(10) htmpSignal = hSignal.Clone() #htmpSignal.Scale(100) signalXS = search(dictXS, 'RPVStopStopToJets_UDD312_M-'+str(signalMass) ) #hSignal.Scale( lumi*signalXS / hSignal.Integral()) massAve = RooRealVar( 'massAve', 'massAve', minMass, maxMass ) rooSigHist = RooDataHist( 'rooSigHist', 'rooSigHist', RooArgList(massAve), hSignal ) rooSigHist.Print() signal = RooHistPdf('signal','signal',RooArgSet(massAve),rooSigHist) signal.Print() signal_norm = RooRealVar('signal_norm','signal_norm',0,-1e+04,1e+04) #if args.fitBonly: signal_norm.setConstant() signal_norm.Print() hBkg = datahistosFile.Get('massAve_prunedMassAsymVsdeltaEtaDijet_DATA_ABCDProj') #hBkg = histosFile.Get(hist+'_QCDPtAll_BCD') bkgAcc = round(hBkg.Integral( hBkg.GetXaxis().FindBin( minMass ), hBkg.GetXaxis().FindBin( maxMass ))) #hBkg.Scale(1/hBkg.Integral()) hPseudo = hBkg.Clone() hPseudo.Reset() #background_norm = RooRealVar('background_norm','background_norm',bkgAcc,0.,1e+07) background_norm = RooRealVar('background_norm','background_norm',1.,0.,1e+07) background_norm.Print() if 'template' in process: rooBkgHist = RooDataHist( 'rooBkgHist', 'rooBkgHist', RooArgList(massAve), hBkg ) rooBkgHist.Print() background = RooHistPdf('background','background',RooArgSet(massAve),rooBkgHist) background.Print() else: p1 = RooRealVar('p1','p1', 1 ,0.,100.) p2 = RooRealVar('p2','p2', 1 ,0.,60.) p3 = RooRealVar('p3','p3', 1 , -10.,10.) background = RooGenericPdf('background','(pow(1-@0/%.1f,@1)/pow(@0/%.1f,@2+@3*log(@0/%.1f)))'%(1300,1300,1300),RooArgList(massAve,p1,p2,p3)) background.Print() ### S+B model if not isData: newNumEvents = random.randint( bkgAcc-round(TMath.Sqrt(bkgAcc)), bkgAcc+round(TMath.Sqrt(bkgAcc)) ) print 'Events in MC:', bkgAcc, ', in PseudoExperiment:', newNumEvents hPseudo.FillRandom( hBkg, newNumEvents ) #hPseudo.Scale(1/hPseudo.Integral()) #hData = histosFile.Get('massAve_prunedMassAsymVsdeltaEtaDijet_ABCDProj') hData = datahistosFile.Get('massAve_prunedMassAsymVsdeltaEtaDijet_DATA_ABCDProj') #hData = histosFile.Get(hist+'_QCDPtAll_A') #hData.Add(htmpSignal) #hData.Scale(1/hData.Integral()) rooDataHist = RooDataHist('rooDatahist','rooDatahist',RooArgList(massAve), hData if isData else hPseudo ) rooDataHist.Print() #model = RooAddPdf("model","s+b",RooArgList(background,signal),RooArgList(background_norm,signal_norm)) #res = model.fitTo(rooDataHist, RooFit.Save(kTRUE), RooFit.Strategy(0)) #res.Print() ############# JES and JER uncertainties hSigSyst = {} hSigSystDataHist = {} signalCDF = TGraph(hSignal.GetNbinsX()+1) # JES and JER uncertainties if args.jesUnc or args.jerUnc: signalCDF.SetPoint(0,0.,0.) integral = 0. for i in range(1, hSignal.GetNbinsX()+1): x = hSignal.GetXaxis().GetBinLowEdge(i+1) integral = integral + hSignal.GetBinContent(i) signalCDF.SetPoint(i,x,integral) if args.jesUnc: print ' |---> Adding JES' hSigSyst['JESUp'] = hSignal.Clone() hSigSyst['JESDown'] = hSignal.Clone() if args.jerUnc: print ' |---> Adding JER' hSigSyst['JERUp'] = hSignal.Clone() hSigSyst['JERDown'] = hSignal.Clone() # reset signal histograms for key in hSigSyst: hSigSyst[key].Reset() hSigSyst[key].SetName(hSigSyst[key].GetName() + '_' + key) # produce JES signal shapes if args.jesUnc: for q in range(1, hSignal.GetNbinsX()+1): xLow = hSignal.GetXaxis().GetBinLowEdge(q) xUp = hSignal.GetXaxis().GetBinLowEdge(q+1) jes = 1. - jesValue xLowPrime = jes*xLow xUpPrime = jes*xUp hSigSyst['JESUp'].SetBinContent(q, signalCDF.Eval(xUpPrime) - signalCDF.Eval(xLowPrime)) jes = 1. + jesValue xLowPrime = jes*xLow xUpPrime = jes*xUp hSigSyst['JESDown'].SetBinContent(q, signalCDF.Eval(xUpPrime) - signalCDF.Eval(xLowPrime)) hSigSystDataHist['JESUp'] = RooDataHist('hSignalJESUp','hSignalJESUp',RooArgList(massAve),hSigSyst['JESUp']) hSigSystDataHist['JESDown'] = RooDataHist('hSignalJESDown','hSignalJESDown',RooArgList(massAve),hSigSyst['JESDown']) # produce JER signal shapes if args.jerUnc: for i in range(1, hSignal.GetNbinsX()+1): xLow = hSignal.GetXaxis().GetBinLowEdge(i) xUp = hSignal.GetXaxis().GetBinLowEdge(i+1) jer = 1. - jerValue xLowPrime = jer*(xLow-float(signalMass))+float(signalMass) xUpPrime = jer*(xUp-float(signalMass))+float(signalMass) hSigSyst['JERUp'].SetBinContent(i, signalCDF.Eval(xUpPrime) - signalCDF.Eval(xLowPrime)) jer = 1. + jerValue xLowPrime = jer*(xLow-float(signalMass))+float(signalMass) xUpPrime = jer*(xUp-float(signalMass))+float(signalMass) hSigSyst['JERDown'].SetBinContent(i, signalCDF.Eval(xUpPrime) - signalCDF.Eval(xLowPrime)) hSigSystDataHist['JERUp'] = RooDataHist('hSignalJERUp','hSignalJERUp',RooArgList(massAve),hSigSyst['JERUp']) hSigSystDataHist['JERDown'] = RooDataHist('hSignalJERDown','hSignalJERDown',RooArgList(massAve),hSigSyst['JERDown']) myWS = RooWorkspace("myWS") getattr(myWS,'import')(rooSigHist,RooFit.Rename("signal")) getattr(myWS,'import')(rooBkgHist,RooFit.Rename("background")) #getattr(myWS,'import')(signal_norm) getattr(myWS,'import')(background_norm) if args.jesUnc: getattr(myWS,'import')(hSigSystDataHist['JESUp'],RooFit.Rename("signal__JESUp")) getattr(myWS,'import')(hSigSystDataHist['JESDown'],RooFit.Rename("signal__JESDown")) if args.jerUnc: getattr(myWS,'import')(hSigSystDataHist['JERUp'],RooFit.Rename("signal__JERUp")) getattr(myWS,'import')(hSigSystDataHist['JERDown'],RooFit.Rename("signal__JERDown")) getattr(myWS,'import')(rooDataHist,RooFit.Rename("data_obs")) myWS.Print() outputRootFile = currentDir+'/Rootfiles/workspace_'+outputName+'.root' myWS.writeToFile(outputRootFile, True) print ' |----> Workspace created in root file:\n', outputRootFile # ----------------------------------------- # write a datacard dataCardName = currentDir+'/Datacards/datacard_'+outputName+'.txt' datacard = open( dataCardName ,'w') datacard.write('imax 1\n') datacard.write('jmax 1\n') datacard.write('kmax *\n') datacard.write('---------------\n') if args.jesUnc or args.jerUnc or args.lumiUnc or args.normUnc or args.unc: datacard.write('shapes * * '+outputRootFile+' myWS:$PROCESS myWS:$PROCESS__$SYSTEMATIC\n') else: datacard.write("shapes * * "+outputRootFile+" myWS:$PROCESS \n") datacard.write('---------------\n') datacard.write('bin 1\n') datacard.write('observation -1\n') datacard.write('------------------------------\n') datacard.write('bin 1 1\n') datacard.write('process signal background\n') datacard.write('process 0 1\n') datacard.write('rate -1 -1\n') datacard.write('------------------------------\n') if args.lumiUnc: datacard.write('lumi lnN %f -\n'%(lumiUnc)) if args.jesUnc: datacard.write('JES shape 1 -\n') if args.jerUnc: datacard.write('JER shape 1 -\n') #flat parameters --- flat prior if args.normUnc: datacard.write('background_norm flatParam\n') #datacard.write('p1 flatParam\n') datacard.close() print ' |----> Datacard created:\n', dataCardName
def main(): # Parse all command line arguments using the argparse module. parser = argparse.ArgumentParser(description='PyRoot analysis demostrating the us of a DST.') parser.add_argument("dst_file", help="ROOT DST file to process") parser.add_argument("-o", "--output", help="Name of output pdf file") parser.add_argument("-m", "--mc", help="is MonteCarlo") parser.add_argument("-p", "--pulser", help="is Pulser") args = parser.parse_args() # If an output file name was not specified, set a default name and warn # the user if args.output: output_file = args.output else: output_file = "analysis_output.root" print "[ HPS ANALYSIS ]: An output file name was not specified. Setting the name to " print output_file print "[ HPS ANALYSIS ]: Output file is "+output_file isMC=False if args.mc: print "[ HPS ANALYSIS ]: Setting to run as MC" isMC=True isPulser=False if args.pulser: print "[ HPS ANALYSIS ]: Setting to run from a pulser file" isPulser=True ################################# # Event Selection ################################ #clean up event first #### nominal selection nTrkMax=10 nTrkMin=2 nPosMax=3 ###### two tracks (e+/e-) exactly # nTrkMax=2 # nTrkMin=2 # nPosMax=1 ###### more than 1 electron # nTrkMax=10 # nTrkMin=3 # nPosMax=1 ################### #v0 cuts v0Chi2=10 #ESum -- full region v0PzMax=1.2 v0PzMin=0.55 #ESum -- Radiative region # v0PzMax=1.2 # v0PzMin=0.80 v0PyMax=0.2 #absolute value v0PxMax=0.2 #absolute value v0VzMax=25.0# mm from target v0VyMax=1.0# mm from target v0VxMax=2.0# mm from target # track quality cuts trkChi2=10 beamCut=0.8 minPCut=0.05 trkPyMax=0.2 trkPxMax=0.2 # slopeCut=0.03 slopeCut=0.0 trkDeltaT=4#ns cluDeltaT=2#ns cluTrkDeltaT=4#ns ############## # ESum slices; upper limits nSlicesESum=5 esumMin=0.55 esumMax=1.2 sliceSizeESum=0.1 #100MeV starting at esumMin ############## trackKiller=False tkThreshold=0.5 #GeV, below this start killing tracks tkThreshEff=1.0 tkLowPoint=0.20 tkLowPointEff=0.40 # tkSlope=2.6 # tkIntercept=-0.04 #calculate tkSlope and Intercept tkSlope=(tkThreshEff-tkLowPointEff)/(tkThreshold-tkLowPoint) tkIntercept=tkThreshEff-tkSlope*tkThreshold ############## requireECalMatch = True requireECalFiducial = False requireECalSuperFiducial = True useGBL=True # Open the ROOT file # root_file = ROOT.TFile(str(args.dst_file)) # Get the TTree "HPS_EVENT" containing the HpsEvent branch and all # other colletions # tree = root_file.Get("HPS_Event") #use a TChain print "[ HPS ANALYSIS ]: Reading in root chain from "+args.dst_file tree=ROOT.TChain("HPS_Event") tree.Add(str(args.dst_file)+"*") # Create an HpsEvent object in order to read the TClonesArray # collections hps_event = HpsEvent() b_hps_event = tree.SetBranchAddress("Event", ROOT.AddressOf(hps_event)) #--- Analysis ---# #----------------# #counters nEvents=0; nPassBasicCuts=0; nPassV0Cuts=0; nPassTrkCuts=0; nPassNCand=0 nPassECalMatch=0; nFakeTri=0 if 1==0 : extraElectronProb=0.0 dataNele=170.0; btNele=1.4; hf=ROOT.TFile("OutputHistograms/Data/hps_005772_pass6_useGBL_ECalMatch_SuperFiducialCut.root") hfMC=ROOT.TFile("OutputHistograms/MC/beam-tri_HPS-EngRun2015-Nominal-v4-4_pass6_useGBL_ECalMatch_SuperFiducialCut.root") pele=ROOT.RooRealVar("pele","pele",0,1) peleHist=hf.Get("raweleMom") peleMCHist=hfMC.Get("raweleMom") peleHist.Scale(1/dataNele) peleMCHist.Scale(1/btNele) peleHist.Add(peleMCHist,-1.0) #subtract the MC from the data to get the distribution of extra tracks...this is cheating! for i in xrange(0,peleHist.GetNbinsX()) : print "Electron Momentum bin i = " +str( peleHist.GetBinContent(i) ) if peleHist.GetBinContent(i) <0 : peleHist.SetBinContent(i,0) peleHist.Print("V") peleDH=RooDataHist("peleDH","peleDH",ROOT.RooArgList(pele),peleHist) peleDH.Print("V") extraElectronPdf=RooHistPdf("extraElectronPdf","extraElectronPdf",ROOT.RooArgSet(pele),peleDH) print 'pdf is made...printing info' extraElectronPdf.Print("V") # if isMC and random.random()<extraElectronProb : #add an extra electron based on electron momentum print 'generating events' newElePData=extraElectronPdf.generate(ROOT.RooArgSet(pele),1000000.0,True, False) newElePData.Print("V") seedCnt=0 # Loop over all events in the file for entry in xrange(0, tree.GetEntries()) : # Print the event number every 500 events if (entry+1)%10000 == 0 : print "Event " + str(entry+1) tree.GetEntry(entry) if not hps_event.isPair1Trigger() and not isMC and not isPulser: continue nEvents+=1 addFakeEle=False if 1==0 : if isMC and random.random()<extraElectronProb : #add an extra electron based on electron momentum addFakeEle=True newEleP=newElePData.get(seedCnt).find("pele").getVal() seedCnt=seedCnt+1 # print 'Inserting an electron with momentum = '+str(newEleP) # newEleCluster=hps_event.addEcalCluster(); # newEleTrack=hps_event.addTrack(); # print 'numbe of HpsParticles before = '+str(hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE)) # newEle=hps_event.addParticle(HpsParticle.FINAL_STATE_PARTICLE) # print 'numbe of HpsParticles after = '+str(hps_event.getNumberOfParticles(HpsParticle.FINAL_STATE_PARTICLE)) newEle=HpsParticle() newEle.setCharge(-1) newEle.setPDG(11) newEle.setEnergy(newEleP) sign=1 if random.random()<0.5 : sign=-1 newEleMom=[math.sin(0.03)*newEleP,sign*math.sin(0.04)*newEleP,math.cos(0.04)*newEleP] newEle.setMomentum(np.array(newEleMom)) #fake track info newEleTrack=SvtTrack() newEleTrack.setTrackParameters(0.0,0.03,0.0001,sign*0.04,0.0) newEleTrack.setTrackTime(40.0) newEleTrack.setParticle(newEle) newEleTrack.setChi2(3.0) newEleTrack.setPositionAtEcal(np.array([300.0,sign*50.0,1350.0])) #fake cluster info newEleCluster=EcalCluster() newEleCluster.setEnergy(newEleP) foobar=[300.0,sign*50.0,1350.0] newEleCluster.setPosition(np.array(foobar,dtype='float32')) newEle.addTrack(newEleTrack) newEle.addCluster(newEleCluster) # print 'fake electron cluster x ' + str(newEle.getClusters().First().getPosition()[0]) # Loop over all tracks in the event npositrons=0 n_tracks=0 for track_n in xrange(0, hps_event.getNumberOfTracks()) : track = hps_event.getTrack(track_n) if track is None : continue # if useGBL and track.getParticle().getType()<32 : continue # if not useGBL and track.getParticle().getType()>31 : continue if trkMatchAndFiducial(track.getParticle()) and trkMomentum(track,minPCut,beamCut): # count only matched tracks in defined fiducial region n_tracks+=1 if track.getCharge()>0 : npositrons+=1 myhist.rawposMom.Fill(pMag(track.getMomentum())) else : myhist.raweleMom.Fill(pMag(track.getMomentum())) # findWABPair(track.getParticle(),hps_event) if addFakeEle : myhist.raweleMom.Fill(newEle.getEnergy()) n_tracks=n_tracks+1 # print "nTracks = "+str(n_tracks)+"; nPositrons = "+str(npositrons) # if n_tracks/2.0>nTrkMax : continue #do this very dumb thing (divide by 2 to un-double count GBL tracks) # if n_tracks/2.0<2: continue myhist.nTrk.Fill(n_tracks); myhist.nPos.Fill(npositrons); myhist.nEle.Fill(n_tracks-npositrons); myhist.nClust.Fill(hps_event.getNumberOfEcalClusters()) if n_tracks>nTrkMax : continue if n_tracks<nTrkMin: continue if npositrons<1 or npositrons>nPosMax : continue nPassBasicCuts+=1 # print "passed basic cuts" candidateList=[] bestCandidate=-99 nCandidate=0 # loop over all v0 candidates... for uc_index in xrange(0, hps_event.getNumberOfParticles(HpsParticle.UC_V0_CANDIDATE)): particle = hps_event.getParticle(HpsParticle.UC_V0_CANDIDATE, uc_index) if useGBL and particle.getType()<32 : continue if not useGBL and particle.getType()>31 : continue # print "found one..." vchi2=particle.getVertexFitChi2(); vposition=particle.getVertexPosition(); vmomentum=particle.getMomentum(); if vchi2>v0Chi2 : continue # use the measured sum of momentum # if vmomentum[2]>v0PzMax : continue # if vmomentum[2]<v0PzMin : continue #recon'ed vertex position cuts if abs(vposition[0])>v0VxMax : continue if abs(vposition[1])>v0VyMax :continue # if abs(vposition[2])>v0VzMax :continue # Only look at particles that have two daugther particles... daughter_particles = particle.getParticles() if daughter_particles.GetSize() != 2 : continue # Only look at particles that are composed of e+e- pairs if daughter_particles.At(0).getCharge()*daughter_particles.At(1).getCharge() > 0 : continue # print "Passed daughter number cuts" electron = daughter_particles.At(0) positron = daughter_particles.At(1) if daughter_particles.At(0).getCharge()>0: electron = daughter_particles.At(1) positron = daughter_particles.At(0) pEle=electron.getMomentum() pPos=positron.getMomentum() v0Sum=pMag(pSum(pEle,pPos)) #total momentum sum cuts if v0Sum>v0PzMax : continue if v0Sum<v0PzMin : continue nPassV0Cuts+=1 print "Passed v0 cuts" ############# tracking cuts #momentum cuts...get rid of very soft or very hard tracks if pMag(pEle)>beamCut or pMag(pPos)>beamCut : continue if pMag(pEle)<minPCut or pMag(pPos)<minPCut : continue #top+bottom requirement if pEle[1]*pPos[1]>0 : continue print 'looking at tracks now' print len(electron.getTracks()) if len(electron.getTracks()) == 0 or len(positron.getTracks()) == 0: continue eleTrk=electron.getTracks().At(0) posTrk=positron.getTracks().At(0) if eleTrk is None or posTrk is None : continue eleTrk.Print("v") #track timing if eleTrk.getTrackTime() - posTrk.getTrackTime()> trkDeltaT : continue #track slope (if any cut) if abs(eleTrk.getTanLambda())<slopeCut or abs(posTrk.getTanLambda())<slopeCut : continue print 'satisfied timing cuts...' ############## # track killer part if isMC and trackKiller : if pMag(pEle) <tkThreshold : #electron tkEff=tkSlope*pMag(pEle)+tkIntercept if random.random()>tkEff : continue elif random.random()>tkThreshEff : #allow for a flat killer above threshold continue if pMag(pPos) <tkThreshold : # positron tkEff=tkSlope*pMag(pPos)+tkIntercept if random.random()>tkEff : continue elif random.random()>tkThreshEff : #allow for a flat killer above threshold continue # end of track killer ############## nPassTrkCuts+=1 ############## # ECAL matching and timing cuts...also fiducial region cuts... if requireECalMatch: if positron.getClusters().GetEntries() == 0 : continue if electron.getClusters().GetEntries() == 0 : continue posCluster=positron.getClusters().First() eleCluster=electron.getClusters().First() if eleCluster.getClusterTime()- posCluster.getClusterTime() > cluDeltaT: continue if eleTrk.getTrackTime() - eleCluster.getClusterTime()+43.5 > cluTrkDeltaT : continue if posTrk.getTrackTime() - posCluster.getClusterTime()+43.5 > cluTrkDeltaT : continue if requireECalFiducial: #ANTI-fiducial cut # if myhist.inFiducialRegion(posCluster.getPosition()[0],posCluster.getPosition()[1]) : # continue # if myhist.inFiducialRegion(eleCluster.getPosition()[0],eleCluster.getPosition()[1]) : # continue #Fiducial cut if not myhist.inFiducialRegion(posCluster.getPosition()[0],posCluster.getPosition()[1]) : continue if not myhist.inFiducialRegion(eleCluster.getPosition()[0],eleCluster.getPosition()[1]) : continue if requireECalSuperFiducial : if not myhist.inSuperFiducialRegion(posCluster.getPosition()[0],posCluster.getPosition()[1]) : continue if not myhist.inSuperFiducialRegion(eleCluster.getPosition()[0],eleCluster.getPosition()[1]) : continue nPassECalMatch+=1 ############## #Passed the cuts..append the candidate index findWABPair(electron,hps_event) candidateList.append(uc_index) numCands=len(candidateList) if addFakeEle : for track_n in xrange(0, hps_event.getNumberOfTracks()) : track = hps_event.getTrack(track_n) if track is None : continue if trkMatchAndFiducial(track.getParticle()) and trkMomentum(track,minPCut,beamCut) and track.getCharge>0 and newEle.getMomentum()[1]*track.getMomentum()[1]<0: # get positron in fudicial region; make sure it's in opposite quadrant myhist.eSum.Fill(newEle.getEnergy()+pMag(track.getMomentum())) numCands+=1 if len(candidateList) == 0 : print 'made a new trident event' nFakeTri+=1 myhist.nCand.Fill(numCands) ######################### # found some candidates...lets fill plots... ######################### for index in range(0,len(candidateList)) : particle = hps_event.getParticle(HpsParticle.TC_V0_CANDIDATE, candidateList[index]) myhist.fillCandidateHistograms(particle) myhist.nTrkCand.Fill(n_tracks); myhist.nPosCand.Fill(npositrons); myhist.nEleCand.Fill(n_tracks-npositrons); myhist.nClustCand.Fill(hps_event.getNumberOfEcalClusters()) # if(nPassTrkCuts>0): myhist.saveHistograms(output_file) print "******************************************************************************************" print "Number of Events:\t\t",nEvents,"\t\t\t",float(nEvents)/nEvents,"\t\t\t",float(nEvents)/nEvents print "N(particle) Cuts:\t\t",nPassBasicCuts,"\t\t\t",float(nPassBasicCuts)/nEvents,"\t\t\t",float(nPassBasicCuts)/nEvents print "V0 Vertex Cuts:\t\t",nPassV0Cuts,"\t\t\t",float(nPassV0Cuts)/nPassBasicCuts,"\t\t\t",float(nPassV0Cuts)/nEvents print "Tracking Cuts:\t\t",nPassTrkCuts,"\t\t\t",float(nPassTrkCuts)/nPassV0Cuts,"\t\t\t",float(nPassTrkCuts)/nEvents print "ECal Match Cuts:\t\t",nPassECalMatch,"\t\t\t",float(nPassECalMatch)/nPassTrkCuts,"\t\t\t",float(nPassECalMatch)/nEvents print "Number of Fake Events Added: \t\t",nFakeTri,"\t\t\t",float(nFakeTri)/nPassECalMatch
def morph(hist1, hist2, mass1, mass2, targetMass, debug=False): from ROOT import gROOT, RooRealVar, RooIntegralMorph,\ kRed,kBlue,kViolet, RooDataHist, RooArgSet,\ RooArgList, RooHistPdf, RooAbsReal, RooFit import re if mass1 < mass2: histLow = hist1 massLow = mass1 histHigh = hist2 massHigh = mass2 else: histLow = hist2 massLow = mass2 histHigh = hist1 massHigh = mass1 x = RooRealVar("x", "x", histLow.GetXaxis().GetXmin(), histLow.GetXaxis().GetXmax()) mAlpha = 1.0 - float(targetMass - massLow) / float(massHigh - massLow) print 'alpha:', mAlpha, newIntegral = histLow.Integral() + \ (targetMass - massLow) * \ (histHigh.Integral()-histLow.Integral()) / \ (massHigh-massLow) print 'low integral:', histLow.Integral(), \ 'high integral:', histHigh.Integral(), \ 'new integral:', newIntegral newHistLow = RooDataHist("sigHistLow_hist", "sigHistLow_hist", RooArgList(x), histLow) sigHistLow = RooHistPdf("sigHistLow", "sigHistLow", RooArgList(x), RooArgList(x), newHistLow) newHistHigh = RooDataHist("sigHistHigh_hist", "sigHistHigh_hist", RooArgList(x), histHigh) sigHistHigh = RooHistPdf("sigHistHigh", "sigHistHigh", RooArgList(x), RooArgList(x), newHistHigh) #x.Print("v") x.setBins(histLow.GetNbinsX(), "cache") alpha_morph = RooRealVar("alpha_morph", "#alpha_{morph}", mAlpha, 0., 1.) alpha_morph.setBins(10, "cache") sigModel = RooIntegralMorph("sigModel", "sigModel", sigHistLow, sigHistHigh, x, alpha_morph) if (debug): from ROOT import gPad, RooFit frame = x.frame() sigHistLow.plotOn(frame, RooFit.LineColor(kRed + 1), RooFit.LineStyle(2)) sigHistHigh.plotOn(frame, RooFit.LineColor(kBlue + 1), RooFit.LineStyle(2)) sigModel.plotOn(frame, RooFit.LineColor(kViolet + 1), RooFit.LineStyle(9)) frame.Draw() gPad.Update() gPad.WaitPrimitive() morphHist = sigModel.createHistogram( re.sub(r'\d+', '%i' % targetMass, hist1.GetName()), x, RooFit.Binning(histLow.GetNbinsX())) morphHist.Scale(newIntegral / morphHist.Integral()) morphHist.SetName(re.sub(r'\d+', '%i' % targetMass, hist1.GetName())) # if debug: # morphHist.Print() return morphHist
frame.Draw() parsSig = signal.getParameters(roohistSig) parsSig.setAttribAll('Constant', True) if histpdfSig: # ----------------------------------------- # hist pdf signal canSname = 'can_Mjj' + str(mass) canS = TCanvas(canSname, canSname, 900, 600) gPad.SetLogy() roohistSig = RooDataHist('roohist', 'roohist', RooArgList(x), hSig) roohistSig.Print() signal = RooHistPdf('signal', 'signal', RooArgSet(x), roohistSig) signal.Print() frame = x.frame() roohistSig.plotOn(frame, RooFit.Binning(166)) signal.plotOn(frame, RooFit.Binning(166), RooFit.LineColor(ROOT.kRed), RooFit.LineWidth(2), RooFit.LineStyle(ROOT.kDashed)) #frame.GetXaxis().SetRangeUser(1118,6099) frame.GetXaxis().SetRangeUser(minX_mass, maxX_mass) frame.GetXaxis().SetTitle('m_{jj} (GeV)') frame.Draw() # parsSig = signal.getParameters(roohistSig) # parsSig.setAttribAll('Constant', True) if fitDat:
def main(options, args): from ROOT import gSystem, gROOT, gStyle gROOT.SetBatch() gSystem.Load("libRooFitCore") if options.doWebPage: from lip.Tools.rootutils import loadToolsLib, apply_modifs loadToolsLib() from ROOT import TFile, RooFit, RooArgSet, RooDataHist, RooKeysPdf, RooHistPdf, TCanvas, TLegend, TLatex, TArrow, TPaveText, RooAddPdf, RooArgList from ROOT import kWhite, kBlue, kOpenSquare if options.doWebPage: from ROOT import HtmlHelper, HtmlTag, HtmlTable, HtmlPlot rootglobestyle.setTDRStyle() gStyle.SetMarkerSize(1.5) gStyle.SetTitleYOffset(1.5) gStyle.SetPadLeftMargin(0.16) gStyle.SetPadRightMargin(0.05) gStyle.SetPadTopMargin(0.05) gStyle.SetPadBottomMargin(0.13) gStyle.SetLabelFont(42, "XYZ") gStyle.SetLabelOffset(0.007, "XYZ") gStyle.SetLabelSize(0.05, "XYZ") gStyle.SetTitleSize(0.06, "XYZ") gStyle.SetTitleXOffset(0.9) gStyle.SetTitleYOffset(1.24) gStyle.SetTitleFont(42, "XYZ") ## ## Read files ## options.outdir = "%s_m%1.0f" % (options.outdir, options.mH) if options.fp: options.outdir += "_fp" ncat = options.ncat cats = options.cats if cats is "": categories = ["_cat%d" % i for i in range(0, ncat)] else: categories = ["_cat%s" % i for i in cats.split(",")] if options.mva: clables = { "_cat0": ("MVA > 0.89", ""), "_cat1": ("0.74 #leq MVA", "MVA < 0.89"), "_cat2": ("0.545 #leq MVA", "MVA < 0.74"), "_cat3": ("0.05 #leq MVA", "MVA < 0.545"), "_cat4": ("Di-jet", "Tagged"), "_cat5": ("Di-jet", "Tagged"), "_combcat": ("All Classes", "Combined") } else: clables = { "_cat0": ("max(|#eta|<1.5", "min(R_{9})>0.94"), "_cat1": ("max(|#eta|<1.5", "min(R_{9})<0.94"), "_cat2": ("max(|#eta|>1.5", "min(R_{9})>0.94"), "_cat3": ("max(|#eta|>1.5", "min(R_{9})<0.94"), "_cat4": ("Di-jet", "Tagged"), "_cat5": ("Di-jet", "Tagged"), "_combcat": ("All Classes", "Combined") } helper = Helper() fin = TFile.Open(options.infile) helper.files.append(fin) ws = fin.Get("cms_hgg_workspace") mass = ws.var("CMS_hgg_mass") mass.SetTitle("m_{#gamma#gamma}") mass.setUnit("GeV") mass.setRange(100., 150.) mass.setBins(100, "plot") mass.setBins(5000) print ws aset = RooArgSet(mass) helper.objs.append(mass) helper.objs.append(aset) fitopt = (RooFit.Minimizer("Minuit2", ""), RooFit.Minos(False), RooFit.SumW2Error(False), RooFit.NumCPU(8)) if not options.binned and not options.refit: finpdf = TFile.Open(options.infilepdf) helper.files.append(finpdf) wspdf = finpdf.Get("wsig") else: wspdf = ws for c in categories: processes = ["ggh", "vbf", "wzh"] if options.fp: processes = ["vbf", "wzh"] ### elif clables[c][0] == "Di-jet": ### processes = [ "vbf", "ggh" ] dsname = "sig_mass_m%1.0f%s" % (options.mH, c) print dsname print ws ds = ws.data("sig_%s_mass_m%1.0f%s" % (processes[0], options.mH, c)).Clone(dsname) for proc in processes[1:]: ds.append(ws.data("sig_%s_mass_m%1.0f%s" % (proc, options.mH, c))) helper.dsets.append(ds) if options.binned: binned_ds = RooDataHist("binned_%s" % dsname, "binned_%s" % dsname, aset, ds) pdf = RooKeysPdf("pdf_%s_%s" % (dsname, f), "pdf_%s" % dsname, mass, ds) plot_pdf = RooHistPdf("pdf_%s" % dsname, "pdf_%s" % dsname, aset, plot_ds) helper.add(binned_ds, binned_ds.GetName()) else: if options.refit: if options.refitall and clables[c][0] != "Di-jet": rpdfs = [] for proc in processes: for ngaus in range(1, 4): pp = build_pdf(ws, "%s_%s" % (c, proc), ngaus, ngaus == 3) pp.fitTo( ws.data("sig_%s_mass_m%1.0f%s" % (proc, options.mH, c)), RooFit.Strategy(0), *fitopt) rpdfs.append(pp) pdf = RooAddPdf("hggpdfrel%s" % c, "hggpdfrel%s" % c, RooArgList(*tuple(rpdfs))) else: if options.refitall and clables[c][0] == "Di-jet": for ngaus in range(1, 5): pdf = build_pdf(ws, c, ngaus, ngaus == 5) pdf.fitTo(ds, RooFit.Strategy(0), *fitopt) else: for ngaus in range(1, 4): pdf = build_pdf(ws, c, ngaus, ngaus == 3) pdf.fitTo(ds, RooFit.Strategy(0), *fitopt) else: pdfs = (wspdf.pdf("hggpdfrel%s_%s" % (c, p)) for p in processes) pdf = RooAddPdf("hggpdfrel%s" % c, "hggpdfrel%s" % c, RooArgList(*pdfs)) helper.add(pdf, pdf.GetName()) plot_pdf = pdf.Clone("pdf_%s" % dsname) plot_ds = RooDataHist("plot_%s" % dsname, "plot_%s" % dsname, aset, "plot") plot_ds.add(ds) cdf = pdf.createCdf(aset) hmin, hmax, hm = get_FWHM(mass, pdf, cdf, options.mH - 10., options.mH + 10.) wmin, wmax = get_eff_sigma(mass, pdf, cdf, options.mH - 10., options.mH + 10.) ### hmin, hmax, hm = get_FWHM( points ) helper.add(plot_ds, plot_ds.GetName()) helper.add(plot_pdf, plot_pdf.GetName()) helper.add((wmin, wmax), "eff_sigma%s" % c) helper.add((hmin, hmax, hm), "FWHM%s" % c) helper.add(ds.sumEntries(), "sumEntries%s" % c) # signal model integral # data integral for PAS tables data = ws.data("data_mass%s" % c) helper.add( data.sumEntries("CMS_hgg_mass>=%1.4f && CMS_hgg_mass<=%1.4f" % (options.mH - 10., options.mH + 10.)), "data_sumEntries%s" % c) del cdf del pdf dsname = "sig_mass_m%1.0f_combcat" % options.mH print dsname combined_ds = helper.dsets[0].Clone(dsname) for d in helper.dsets[1:]: combined_ds.append(d) if options.binned: binned_ds = RooDataHist("binned_%s" % dsname, "binned_%s" % dsname, aset, combined_ds) pdf = RooKeysPdf("pdf_%s" % (dsname), "pdf_%s" % dsname, mass, combined_ds) plot_pdf = RooHistPdf("pdf_%s" % dsname, "pdf_%s" % dsname, aset, plot_ds) helper.add(binned_ds, binned_ds.GetName()) else: #### pdf = build_pdf(ws,"_combcat") #### pdf.fitTo(combined_ds, RooFit.Strategy(0), *fitopt ) #### plot_pdf = pdf.Clone( "pdf_%s" % dsname ) pdf = RooAddPdf( "pdf_%s" % dsname, "pdf_%s" % dsname, RooArgList(*(helper.histos["hggpdfrel%s" % c] for c in categories))) plot_pdf = pdf cdf = pdf.createCdf(aset) plot_ds = RooDataHist("plot_%s" % dsname, "plot_%s" % dsname, aset, "plot") plot_ds.add(combined_ds) wmin, wmax = get_eff_sigma(mass, pdf, cdf, options.mH - 10., options.mH + 10.) hmin, hmax, hm = get_FWHM(mass, pdf, cdf, options.mH - 10., options.mH + 10.) helper.add(plot_ds, plot_ds.GetName()) helper.add(plot_pdf, plot_pdf.GetName()) helper.add((wmin, wmax), "eff_sigma_combcat") helper.add((hmin, hmax, hm), "FWHM_combcat") helper.add(plot_ds.sumEntries(), "sumEntries_combcat") mass.setRange("higgsrange", options.mH - 25., options.mH + 15.) del cdf del pdf del helper.dsets ### label = TLatex(0.1812081,0.8618881,"#scale[0.8]{#splitline{CMS preliminary}{Simulation}}") label = TLatex(0.7, 0.86, "#scale[0.65]{#splitline{CMS preliminary}{Simulation}}") label.SetNDC(1) ## ## Make web page with plots ## if options.doWebPage: hth = HtmlHelper(options.outdir) hth.navbar().cell(HtmlTag("a")).firstChild().txt("..").set( "href", "../?C=M;O=D") hth.navbar().cell(HtmlTag("a")).firstChild().txt("home").set( "href", "./") tab = hth.body().add(HtmlTable()) ip = 0 for c in ["_combcat"] + categories: ### for c in categories: if options.doWebPage and ip % 4 == 0: row = tab.row() ip = ip + 1 dsname = "sig_mass_m%1.0f%s" % (options.mH, c) canv = TCanvas(dsname, dsname, 600, 600) helper.objs.append(canv) ### leg = TLegend(0.4345638,0.6835664,0.9362416,0.9178322) leg = TLegend(0.2, 0.96, 0.5, 0.55) #apply_modifs( leg, [("SetLineColor",kWhite),("SetFillColor",kWhite),("SetFillStyle",0),("SetLineStyle",0)] ) hplotcompint = mass.frame(RooFit.Bins(250), RooFit.Range("higgsrange")) helper.objs.append(hplotcompint) helper.objs.append(leg) plot_ds = helper.histos["plot_%s" % dsname] plot_pdf = helper.histos["pdf_%s" % dsname] wmin, wmax = helper.histos["eff_sigma%s" % c] hmin, hmax, hm = helper.histos["FWHM%s" % c] print hmin, hmax, hm style = (RooFit.LineColor(kBlue), RooFit.LineWidth(2), RooFit.FillStyle(0)) style_seff = ( RooFit.LineWidth(2), RooFit.FillStyle(1001), RooFit.VLines(), RooFit.LineColor(15), ) style_ds = (RooFit.MarkerStyle(kOpenSquare), ) plot_ds.plotOn(hplotcompint, RooFit.Invisible()) plot_pdf.plotOn(hplotcompint, RooFit.NormRange("higgsrange"), RooFit.Range(wmin, wmax), RooFit.FillColor(19), RooFit.DrawOption("F"), *style_seff) seffleg = hplotcompint.getObject(int(hplotcompint.numItems() - 1)) plot_pdf.plotOn(hplotcompint, RooFit.NormRange("higgsrange"), RooFit.Range(wmin, wmax), RooFit.LineColor(15), *style_seff) plot_pdf.plotOn(hplotcompint, RooFit.NormRange("higgsrange"), RooFit.Range("higgsrange"), *style) pdfleg = hplotcompint.getObject(int(hplotcompint.numItems() - 1)) plot_ds.plotOn(hplotcompint, *style_ds) pointsleg = hplotcompint.getObject(int(hplotcompint.numItems() - 1)) iob = int(hplotcompint.numItems() - 1) leg.AddEntry(pointsleg, "Simulation", "pe") leg.AddEntry(pdfleg, "Parametric model", "l") leg.AddEntry(seffleg, "#sigma_{eff} = %1.2f GeV " % (0.5 * (wmax - wmin)), "fl") clabel = TLatex(0.74, 0.65, "#scale[0.65]{#splitline{%s}{%s}}" % clables[c]) clabel.SetNDC(1) helper.objs.append(clabel) hm = hplotcompint.GetMaximum() * 0.5 * 0.9 ### hm = pdfleg.GetMaximum()*0.5 fwhmarrow = TArrow(hmin, hm, hmax, hm) fwhmarrow.SetArrowSize(0.03) helper.objs.append(fwhmarrow) fwhmlabel = TPaveText(0.20, 0.58, 0.56, 0.48, "brNDC") fwhmlabel.SetFillStyle(0) fwhmlabel.SetLineColor(kWhite) reducedFWHM = (hmax - hmin) / 2.3548200 fwhmlabel.AddText("FWHM/2.35 = %1.2f GeV" % reducedFWHM) helper.objs.append(fwhmlabel) hplotcompint.SetTitle("") hplotcompint.GetXaxis().SetNoExponent(True) hplotcompint.GetXaxis().SetTitle("m_{#gamma#gamma} (GeV)") hplotcompint.GetXaxis().SetNdivisions(509) ## hplotcompint.GetYaxis().SetTitle("A.U."); ## hplotcompint.GetYaxis().SetRangeUser(0.,hplotcompint.GetMaximum()*1.4); hplotcompint.Draw() leg.Draw("same") label.Draw("same") clabel.Draw("same") fwhmarrow.Draw("<>") fwhmlabel.Draw("same") plot_ds.sumEntries() if options.doWebPage: hpl = HtmlPlot(canv, False, "", True, True, True) hpl.caption("<i>%s</i>" % canv.GetTitle()) row.cell(hpl) else: if os.path.isdir(options.outdir) is False: os.mkdir(options.outdir) for ext in "C", "png", "pdf": canv.SaveAs( os.path.join(options.outdir, "%s.%s" % (canv.GetName(), ext))) if "comb" in c: ip = 0 if options.doWebPage: print "Creating pages..." hth.dump() for f in helper.files: f.Close() gROOT.Reset() from pprint import pprint pprint(helper) print 'Summary statistics per event class' print 'Cat\tSignal\t\tData/GeV (in %3.1f+/-10)\tsigEff\tFWHM/2.35' % options.mH sigTotal = 0. dataTotal = 0. for c in categories: sigVal = helper.histos["sumEntries%s" % c] datVal = helper.histos["data_sumEntries%s" % c] sigTotal += sigVal dataTotal += datVal for c in categories: sigVal = helper.histos["sumEntries%s" % c] datVal = helper.histos["data_sumEntries%s" % c] effSig = 0.5 * (helper.histos["eff_sigma%s" % c][1] - helper.histos["eff_sigma%s" % c][0]) fwhm = (helper.histos["FWHM%s" % c][1] - helper.histos["FWHM%s" % c][0]) / 2.3548200 print c, '\t%3.1f (%3.1f%%)\t%3.1f (%3.1f%%)\t\t\t%2.2f\t%2.2f' % ( sigVal, 100. * sigVal / sigTotal, datVal / (10. + 10.), 100. * datVal / dataTotal, effSig, fwhm) print "Done."
#eff_p4= acceptanceFile.Get("l1_p4").GetFunction("pol4").Eval(mass) eff_p4 = 0 exppol4.SetParameters(eff_p0, eff_p1, eff_p2, eff_p3, eff_p4) exppol4.Draw() exppol4.GetYaxis().SetRangeUser(0, 2) fitfunc.SetParameters(1.0, mean, sigma, breakz, length) bkgHist.Reset() for binnum in xrange(1, nbins_histpdf + 1): bkgHist.SetBinContent( binnum, fitfunc.Eval(bkgHist.GetXaxis().GetBinCenter(binnum))) # bkgHist.Draw() bkgDataHist = RooDataHist("bkgDataHist_{0}".format(i), "bkgDataHist_{0}".format(i), RooArgList(w.set("obs_1d")), bkgHist) bkgPdf = RooHistPdf("bkgPdf_{0}".format(i), "bkgPdf_{0}".format(i), w.set("obs_1d"), bkgDataHist) getattr(w, 'import')(bkgPdf, RooFit.Silence()) #w.factory("Exponential::bkg_{0}(uncVZ,{0})".format(i,-1.0/length)) #w.factory("EXPR::gaussExp_{0}('exp( ((@0-{1})<{3})*(-0.5*(@0-{1})^2/{2}^2) + ((@0-{1})>={3})*(-0.5*{3}^2/{2}^2-(@0-{1}-{3})/{4}))',uncVZ)".format(i,mean,sigma,breakz,length)) c.Clear() c.SetLogy() vtxZRefitUnc.setRange("fitRange", tailcut, 50) frame = vtxZRefitUnc.frame() frame.SetAxisRange(tailcut, 50) frame.SetTitle(name) frame.GetXaxis().SetTitle("Vertex Z [mm]") dataPastCut2.plotOn(frame) thispdf = w.pdf("bkgPdf_{0}".format(i)) fitresult = thispdf.fitTo(dataPastCut2, RooFit.Range("fitRange"),
def main(): # usage description usage = "Example: ./scripts/createDatacards.py --inputData inputs/rawhistV7_Run2015D_scoutingPFHT_UNBLINDED_649_838_JEC_HLTplusV7_Mjj_cor_smooth.root --dataHistname mjj_mjjcor_gev --inputSig inputs/ResonanceShapes_gg_13TeV_Scouting_Spring15.root -f gg -o datacards -l 1866 --lumiUnc 0.027 --massrange 1000 1500 50 --runFit --p1 5 --p2 7 --p3 0.4 --massMin 838 --massMax 2037 --fitStrategy 2" # input parameters parser = ArgumentParser( description= 'Script that creates combine datacards and corresponding RooFit workspaces', epilog=usage) parser.add_argument("analysis", type=str, help="Analysis name") parser.add_argument("model", type=str, help="Model (Hbb, RSG)") #parser.add_argument("--inputData", dest="inputData", required=True, # help="Input data spectrum", # metavar="INPUT_DATA") parser.add_argument("--dataHistname", dest="dataHistname", type=str, default="h_data", help="Data histogram name", metavar="DATA_HISTNAME") #parser.add_argument("--inputSig", dest="inputSig", required=True, # help="Input signal shapes", # metavar="INPUT_SIGNAL") parser.add_argument("-f", "--final_state", dest="final_state", default="qq", help="Final state (e.g. qq, qg, gg)", metavar="FINAL_STATE") parser.add_argument("--fit_functions", dest="fit_functions", default="f1,f2,f3,f4,f5", help="List of fit functions") #parser.add_argument("-f2", "--type", dest="atype", required=True, help="Type (e.g. hG, lG, hR, lR)") parser.add_argument( "-o", "--output_path", dest="output_path", help= "Output path where datacards and workspaces will be stored. If not specified, this is derived from limit_configuration.", metavar="OUTPUT_PATH") parser.add_argument("--correctTrigger", dest="correctTrigger", action='store_true', help="Include trigger correction in PDF") parser.add_argument( "-l", "--lumi", dest="lumi", default=19700., type=float, help="Integrated luminosity in pb-1 (default: %(default).1f)", metavar="LUMI") parser.add_argument( "--massMin", dest="massMin", default=500, type=int, help= "Lower bound of the mass range used for fitting (default: %(default)s)", metavar="MASS_MIN") parser.add_argument( "--massMax", dest="massMax", default=1200, type=int, help= "Upper bound of the mass range used for fitting (default: %(default)s)", metavar="MASS_MAX") parser.add_argument( "--fitSignal", action="store_true", help= "Use signal fitted shapes (CB+Voigtian) instead of histogram templates" ) #parser.add_argument("--lumiUnc", dest="lumiUnc", # required=True, type=float, # help="Relative uncertainty in the integrated luminosity", # metavar="LUMI_UNC") #parser.add_argument("--jesUnc", dest="jesUnc", # type=float, # help="Relative uncertainty in the jet energy scale", # metavar="JES_UNC") #parser.add_argument("--jerUnc", dest="jerUnc", # type=float, # help="Relative uncertainty in the jet energy resolution", # metavar="JER_UNC") parser.add_argument( "--sqrtS", dest="sqrtS", default=8000., type=float, help="Collision center-of-mass energy (default: %(default).1f)", metavar="SQRTS") parser.add_argument("--fixP3", dest="fixP3", default=False, action="store_true", help="Fix the fit function p3 parameter") parser.add_argument("--runFit", dest="runFit", default=False, action="store_true", help="Run the fit") parser.add_argument("--fitBonly", dest="fitBonly", default=False, action="store_true", help="Run B-only fit") parser.add_argument("--fixBkg", dest="fixBkg", default=False, action="store_true", help="Fix all background parameters") parser.add_argument("--decoBkg", dest="decoBkg", default=False, action="store_true", help="Decorrelate background parameters") parser.add_argument("--fitStrategy", dest="fitStrategy", type=int, default=1, help="Fit strategy (default: %(default).1f)") parser.add_argument("--debug", dest="debug", default=False, action="store_true", help="Debug printout") parser.add_argument( "--postfix", dest="postfix", default='', help="Postfix for the output file names (default: %(default)s)") parser.add_argument("--pyes", dest="pyes", default=False, action="store_true", help="Make files for plots") parser.add_argument("--jyes", dest="jyes", default=False, action="store_true", help="Make files for JES/JER plots") parser.add_argument( "--pdir", dest="pdir", default='testarea', help="Name a directory for the plots (default: %(default)s)") parser.add_argument("--chi2", dest="chi2", default=False, action="store_true", help="Compute chi squared") parser.add_argument("--widefit", dest="widefit", default=False, action="store_true", help="Fit with wide bin hist") mass_group = parser.add_mutually_exclusive_group(required=True) mass_group.add_argument( "--mass", type=int, nargs='*', default=1000, help= "Mass can be specified as a single value or a whitespace separated list (default: %(default)i)" ) mass_group.add_argument( "--massrange", type=int, nargs=3, help="Define a range of masses to be produced. Format: min max step", metavar=('MIN', 'MAX', 'STEP')) mass_group.add_argument("--masslist", help="List containing mass information") args = parser.parse_args() fit_functions = args.fit_functions.split(",") # mass points for which resonance shapes will be produced masses = [] if args.fitBonly: masses.append(750) else: if args.massrange != None: MIN, MAX, STEP = args.massrange masses = range(MIN, MAX + STEP, STEP) elif args.masslist != None: # A mass list was provided print "Will create mass list according to", args.masslist masslist = __import__(args.masslist.replace(".py", "")) masses = masslist.masses else: masses = args.mass # sort masses masses.sort() # import ROOT stuff from ROOT import gStyle, TFile, TH1F, TH1D, TGraph, kTRUE, kFALSE, TCanvas, TLegend, TPad, TLine from ROOT import RooHist, RooRealVar, RooDataHist, RooArgList, RooArgSet, RooAddPdf, RooProdPdf, RooEffProd, RooFit, RooGenericPdf, RooWorkspace, RooMsgService, RooHistPdf, RooExtendPdf if not args.debug: RooMsgService.instance().setSilentMode(kTRUE) RooMsgService.instance().setStreamStatus(0, kFALSE) RooMsgService.instance().setStreamStatus(1, kFALSE) # input data file #inputData = TFile(limit_config.get_data_input(args.analysis)) # input data histogram #hData = inputData.Get(args.dataHistname) #hData.SetDirectory(0) data_file = TFile( analysis_config.get_b_histogram_filename(args.analysis, "BJetPlusX_2012")) hData = data_file.Get("BHistograms/h_pfjet_mjj") hData.SetDirectory(0) # input sig file if not args.fitSignal: print "[create_datacards] INFO : Opening resonance shapes file at " + limit_config.get_resonance_shapes( args.analysis, args.model) inputSig = TFile( limit_config.get_resonance_shapes(args.analysis, args.model), "READ") sqrtS = args.sqrtS # mass variable mjj = RooRealVar('mjj', 'mjj', float(args.massMin), float(args.massMax)) # integrated luminosity and signal cross section lumi = args.lumi signalCrossSection = 1. # set to 1. so that the limit on r can be interpreted as a limit on the signal cross section if args.correctTrigger: trigger_efficiency_pdf = trigger_efficiency.get_pdf(args.analysis, mjj) trigger_efficiency_formula = trigger_efficiency.get_formula( args.analysis, mjj) else: trigger_efficiency_pdf = trigger_efficiency.get_trivial_pdf(mjj) trigger_efficiency_formula = trigger_efficiency.get_trivial_formula( mjj) for mass in masses: print ">> Creating datacard and workspace for %s resonance with m = %i GeV..." % ( args.final_state, int(mass)) rooDataHist = RooDataHist('rooDatahist', 'rooDathist', RooArgList(mjj), hData) if not args.fitSignal: hSig = inputSig.Get("h_" + args.final_state + "_" + str(int(mass))) if not hSig: raise Exception("Couldn't find histogram " + "h_" + args.final_state + "_" + str(int(mass)) + " in file " + limit_config.get_resonance_shapes( args.analysis, args.model)) # normalize signal shape to the expected event yield (works even if input shapes are not normalized to unity) hSig.Scale( signalCrossSection * lumi / hSig.Integral() ) # divide by a number that provides roughly an r value of 1-10 rooSigHist = RooDataHist('rooSigHist', 'rooSigHist', RooArgList(mjj), hSig) print 'Signal acceptance:', (rooSigHist.sumEntries() / hSig.Integral()) # If using fitted signal shapes, load the signal PDF if args.fitSignal: print "[create_datacards] Loading fitted signal PDFs from " + analysis_config.get_signal_fit_file( args.analysis, args.model, mass, "bukin", interpolated=(not mass in analysis_config.simulation.simulated_masses)) f_signal_pdfs = TFile( analysis_config.get_signal_fit_file( args.analysis, args.model, mass, "bukin", interpolated=( not mass in analysis_config.simulation.simulated_masses)), "READ") w_signal = f_signal_pdfs.Get("w_signal") input_parameters = signal_fits.get_parameters( w_signal.pdf("signal")) # Make a new PDF with nuisance parameters signal_pdf_notrig, signal_vars = signal_fits.make_signal_pdf_systematic( "bukin", mjj, mass=mass) signal_pdf_name = signal_pdf_notrig.GetName() signal_pdf_notrig.SetName(signal_pdf_name + "_notrig") #signal_pdf = RooProdPdf(signal_pdf_name, signal_pdf_name, signal_pdf_notrig, trigger_efficiency_pdf) signal_pdf = RooEffProd(signal_pdf_name, signal_pdf_name, signal_pdf_notrig, trigger_efficiency_formula) # Copy input parameter values signal_vars["xp_0"].setVal(input_parameters["xp"][0]) signal_vars["xp_0"].setError(input_parameters["xp"][1]) signal_vars["xp_0"].setConstant() signal_vars["sigp_0"].setVal(input_parameters["sigp"][0]) signal_vars["sigp_0"].setError(input_parameters["sigp"][1]) signal_vars["sigp_0"].setConstant() signal_vars["xi_0"].setVal(input_parameters["xi"][0]) signal_vars["xi_0"].setError(input_parameters["xi"][1]) signal_vars["xi_0"].setConstant() signal_vars["rho1_0"].setVal(input_parameters["rho1"][0]) signal_vars["rho1_0"].setError(input_parameters["rho1"][1]) signal_vars["rho1_0"].setConstant() signal_vars["rho2_0"].setVal(input_parameters["rho2"][0]) signal_vars["rho2_0"].setError(input_parameters["rho2"][1]) signal_vars["rho2_0"].setConstant() f_signal_pdfs.Close() signal_parameters = {} signal_pdfs_notrig = {} signal_pdfs = {} signal_norms = {} background_pdfs = {} background_pdfs_notrig = {} background_parameters = {} background_norms = {} signal_epdfs = {} background_epdfs = {} models = {} fit_results = {} for fit_function in fit_functions: print "[create_datacards] INFO : On fit function {}".format( fit_function) if args.fitSignal: # Make a copy of the signal PDF, so that each fitTo call uses its own copy. # The copy should have all variables set constant. #signal_pdfs[fit_function], signal_parameters[fit_function] = signal_fits.copy_signal_pdf("bukin", signal_pdf, mjj, tag=fit_function, include_systematics=True) signal_pdfs_notrig[fit_function] = ROOT.RooBukinPdf( signal_pdf_notrig, signal_pdf_notrig.GetName() + "_" + fit_function) signal_pdfs[fit_function] = RooEffProd( signal_pdf.GetName() + "_" + fit_function, signal_pdf.GetName() + "_" + fit_function, signal_pdfs_notrig[fit_function], trigger_efficiency_formula) #signal_pdfs[fit_function] = RooProdPdf(signal_pdf.GetName() + "_" + fit_function, signal_pdf.GetName() + "_" + fit_function, signal_pdfs_notrig[fit_function], trigger_efficiency_pdf) iterator = signal_pdfs_notrig[fit_function].getVariables( ).createIterator() this_parameter = iterator.Next() while this_parameter: this_parameter.setConstant() this_parameter = iterator.Next() else: signal_pdfs[fit_function] = RooHistPdf( 'signal_' + fit_function, 'signal_' + fit_function, RooArgSet(mjj), rooSigHist) signal_norms[fit_function] = RooRealVar( 'signal_norm_' + fit_function, 'signal_norm_' + fit_function, 0., 0., 1e+05) if args.fitBonly: signal_norms[fit_function].setConstant() background_pdfs_notrig[fit_function], background_parameters[ fit_function] = make_background_pdf(fit_function, mjj, collision_energy=8000.) background_pdf_name = background_pdfs_notrig[fit_function].GetName( ) background_pdfs_notrig[fit_function].SetName(background_pdf_name + "_notrig") background_pdfs[fit_function] = RooEffProd( background_pdf_name, background_pdf_name, background_pdfs_notrig[fit_function], trigger_efficiency_formula) #background_pdfs[fit_function] = RooProdPdf(background_pdf_name, background_pdf_name, background_pdfs_notrig[fit_function], trigger_efficiency_pdf) #background_pdfs[fit_function] = background_pdfs_notrig[fit_function] #background_pdfs[fit_function].SetName(background_pdf_name) # Initial values if "trigbbh" in args.analysis: if fit_function == "f3": background_parameters[fit_function]["p1"].setVal(55.) background_parameters[fit_function]["p1"].setMin(20.) background_parameters[fit_function]["p2"].setVal(8.) elif fit_function == "f4": background_parameters[fit_function]["p1"].setVal(28.) background_parameters[fit_function]["p2"].setVal(-22.) background_parameters[fit_function]["p3"].setVal(10.) elif "trigbbl" in args.analysis: if fit_function == "f3": background_parameters[fit_function]["p1"].setVal(82.) background_parameters[fit_function]["p1"].setMin(60.) background_parameters[fit_function]["p2"].setVal(8.) elif fit_function == "f4": background_parameters[fit_function]["p1"].setVal(41.) background_parameters[fit_function]["p2"].setVal(-45.) background_parameters[fit_function]["p3"].setVal(10.) data_integral = hData.Integral( hData.GetXaxis().FindBin(float(args.massMin)), hData.GetXaxis().FindBin(float(args.massMax))) background_norms[fit_function] = RooRealVar( 'background_' + fit_function + '_norm', 'background_' + fit_function + '_norm', data_integral, 0., 1.e8) signal_epdfs[fit_function] = RooExtendPdf( 'esignal_' + fit_function, 'esignal_' + fit_function, signal_pdfs[fit_function], signal_norms[fit_function]) background_epdfs[fit_function] = RooExtendPdf( 'ebackground_' + fit_function, 'ebackground_' + fit_function, background_pdfs[fit_function], background_norms[fit_function]) models[fit_function] = RooAddPdf( 'model_' + fit_function, 's+b', RooArgList(background_epdfs[fit_function], signal_epdfs[fit_function])) if args.runFit: print "[create_datacards] INFO : Starting fit with function {}".format( fit_function) fit_results[fit_function] = models[fit_function].fitTo( rooDataHist, RooFit.Save(kTRUE), RooFit.Extended(kTRUE), RooFit.Strategy(args.fitStrategy), RooFit.Verbose(0)) print "[create_datacards] INFO : Done with fit {}. Printing results.".format( fit_function) fit_results[fit_function].Print() print "[create_datacards] DEBUG : End args.runFit if block." # needed if want to evaluate limits without background systematics if args.fixBkg: background_norms[fit_function].setConstant() for par_name, par in background_parameters[ fit_function].iteritems(): par.setConstant() # ----------------------------------------- #signal_pdfs_syst = {} # JES and JER uncertainties if args.fitSignal: print "[create_datacards] INFO : Getting signal PDFs from " + analysis_config.get_signal_fit_file( args.analysis, args.model, mass, "bukin", interpolated=(not mass in analysis_config.simulation.simulated_masses)) f_signal_pdfs = TFile( analysis_config.get_signal_fit_file( args.analysis, args.model, mass, "bukin", interpolated=( not mass in analysis_config.simulation.simulated_masses))) w_signal = f_signal_pdfs.Get("w_signal") if "jes" in systematics: xp_central = signal_vars["xp_0"].getVal() #print w_signal.pdf("signal__JESUp") #print signal_fits.get_parameters(w_signal.pdf("signal__JESUp")) xp_up = signal_fits.get_parameters( w_signal.pdf("signal__JESUp"))["xpJESUp"][0] xp_down = signal_fits.get_parameters( w_signal.pdf("signal__JESDown"))["xpJESDown"][0] signal_vars["dxp"].setVal( max(abs(xp_up - xp_central), abs(xp_down - xp_central))) if signal_vars["dxp"].getVal() > 2 * mass * 0.1: print "[create_datacards] WARNING : Large dxp value. dxp = {}, xp_down = {}, xp_central = {}, xp_up = {}".format( signal_vars["dxp"].getVal(), xp_down, xp_central, xp_up) signal_vars["alpha_jes"].setVal(0.) signal_vars["alpha_jes"].setConstant(False) else: signal_vars["dxp"].setVal(0.) signal_vars["alpha_jes"].setVal(0.) signal_vars["alpha_jes"].setConstant() signal_vars["dxp"].setError(0.) signal_vars["dxp"].setConstant() if "jer" in systematics: sigp_central = signal_vars["sigp_0"].getVal() sigp_up = signal_fits.get_parameters( w_signal.pdf("signal__JERUp"))["sigpJERUp"][0] sigp_down = signal_fits.get_parameters( w_signal.pdf("signal__JERDown"))["sigpJERDown"][0] signal_vars["dsigp"].setVal( max(abs(sigp_up - sigp_central), abs(sigp_down - sigp_central))) signal_vars["alpha_jer"].setVal(0.) signal_vars["alpha_jer"].setConstant(False) else: signal_vars["dsigp"].setVal(0.) signal_vars["alpha_jer"].setVal(0.) signal_vars["alpha_jer"].setConstant() signal_vars["dsigp"].setError(0.) signal_vars["dsigp"].setConstant() #for variation in ["JERUp", "JERDown"]: # signal_pdfs_syst[variation] = w_signal.pdf("signal__" + variation) #for variation, pdf in signal_pdfs_syst.iteritems(): # signal_parameters = pdf.getVariables() # iter = signal_parameters.createIterator() # var = iter.Next() # while var: # var.setConstant() # var = iter.Next() f_signal_pdfs.Close() else: # dictionaries holding systematic variations of the signal shape hSig_Syst = {} hSig_Syst_DataHist = {} sigCDF = TGraph(hSig.GetNbinsX() + 1) if "jes" in systematics or "jer" in systematics: sigCDF.SetPoint(0, 0., 0.) integral = 0. for i in range(1, hSig.GetNbinsX() + 1): x = hSig.GetXaxis().GetBinLowEdge(i + 1) integral = integral + hSig.GetBinContent(i) sigCDF.SetPoint(i, x, integral) if "jes" in systematics: hSig_Syst['JESUp'] = copy.deepcopy(hSig) hSig_Syst['JESDown'] = copy.deepcopy(hSig) if "jer" in systematics: hSig_Syst['JERUp'] = copy.deepcopy(hSig) hSig_Syst['JERDown'] = copy.deepcopy(hSig) # reset signal histograms for key in hSig_Syst.keys(): hSig_Syst[key].Reset() hSig_Syst[key].SetName(hSig_Syst[key].GetName() + '_' + key) # produce JES signal shapes if "jes" in systematics: for i in range(1, hSig.GetNbinsX() + 1): xLow = hSig.GetXaxis().GetBinLowEdge(i) xUp = hSig.GetXaxis().GetBinLowEdge(i + 1) jes = 1. - systematics["jes"] xLowPrime = jes * xLow xUpPrime = jes * xUp hSig_Syst['JESUp'].SetBinContent( i, sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime)) jes = 1. + systematics["jes"] xLowPrime = jes * xLow xUpPrime = jes * xUp hSig_Syst['JESDown'].SetBinContent( i, sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime)) hSig_Syst_DataHist['JESUp'] = RooDataHist( 'hSig_JESUp', 'hSig_JESUp', RooArgList(mjj), hSig_Syst['JESUp']) hSig_Syst_DataHist['JESDown'] = RooDataHist( 'hSig_JESDown', 'hSig_JESDown', RooArgList(mjj), hSig_Syst['JESDown']) # produce JER signal shapes if "jer" in systematics: for i in range(1, hSig.GetNbinsX() + 1): xLow = hSig.GetXaxis().GetBinLowEdge(i) xUp = hSig.GetXaxis().GetBinLowEdge(i + 1) jer = 1. - systematics["jer"] xLowPrime = jer * (xLow - float(mass)) + float(mass) xUpPrime = jer * (xUp - float(mass)) + float(mass) hSig_Syst['JERUp'].SetBinContent( i, sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime)) jer = 1. + systematics["jer"] xLowPrime = jer * (xLow - float(mass)) + float(mass) xUpPrime = jer * (xUp - float(mass)) + float(mass) hSig_Syst['JERDown'].SetBinContent( i, sigCDF.Eval(xUpPrime) - sigCDF.Eval(xLowPrime)) hSig_Syst_DataHist['JERUp'] = RooDataHist( 'hSig_JERUp', 'hSig_JERUp', RooArgList(mjj), hSig_Syst['JERUp']) hSig_Syst_DataHist['JERDown'] = RooDataHist( 'hSig_JERDown', 'hSig_JERDown', RooArgList(mjj), hSig_Syst['JERDown']) # ----------------------------------------- # create a datacard and corresponding workspace postfix = (('_' + args.postfix) if args.postfix != '' else '') wsName = 'workspace_' + args.final_state + '_m' + str( mass) + postfix + '.root' w = RooWorkspace('w', 'workspace') if args.fitSignal: signal_pdf.SetName("signal") getattr(w, 'import')(signal_pdf, RooFit.Rename("signal")) # Create a norm variable "signal_norm" which normalizes the PDF to unity. norm = args.lumi #signal_norm = ROOT.RooRealVar("signal_norm", "signal_norm", 1. / norm, 0.1 / norm, 10. / norm) #if args.analysis == "trigbbh_CSVTM" and mass >= 1100: signal_norm = ROOT.RooRealVar("signal_norm", "signal_norm", norm / 100., norm / 100. / 10., norm * 10.) #else: # signal_norm = ROOT.RooRealVar("signal_norm", "signal_norm", norm, norm / 10., norm * 10.) print "[create_datacards] INFO : Set signal norm to {}".format( signal_norm.getVal()) signal_norm.setConstant() getattr(w, 'import')(signal_norm, ROOT.RooCmdArg()) #if "jes" in systematics: # getattr(w,'import')(signal_pdfs_syst['JESUp'],RooFit.Rename("signal__JESUp")) # getattr(w,'import')(signal_pdfs_syst['JESDown'],RooFit.Rename("signal__JESDown")) #if "jer" in systematics: # getattr(w,'import')(signal_pdfs_syst['JERUp'],RooFit.Rename("signal__JERUp")) # getattr(w,'import')(signal_pdfs_syst['JERDown'],RooFit.Rename("signal__JERDown")) else: getattr(w, 'import')(rooSigHist, RooFit.Rename("signal")) if "jes" in systematics: getattr(w, 'import')(hSig_Syst_DataHist['JESUp'], RooFit.Rename("signal__JESUp")) getattr(w, 'import')(hSig_Syst_DataHist['JESDown'], RooFit.Rename("signal__JESDown")) if "jer" in systematics: getattr(w, 'import')(hSig_Syst_DataHist['JERUp'], RooFit.Rename("signal__JERUp")) getattr(w, 'import')(hSig_Syst_DataHist['JERDown'], RooFit.Rename("signal__JERDown")) if args.decoBkg: getattr(w, 'import')(background_deco, ROOT.RooCmdArg()) else: for fit_function in fit_functions: print "Importing background PDF" print background_pdfs[fit_function] background_pdfs[fit_function].Print() getattr(w, 'import')(background_pdfs[fit_function], ROOT.RooCmdArg(), RooFit.Rename("background_" + fit_function), RooFit.RecycleConflictNodes()) w.pdf("background_" + fit_function).Print() getattr(w, 'import')(background_norms[fit_function], ROOT.RooCmdArg(), RooFit.Rename("background_" + fit_function + "_norm")) getattr(w, 'import')(fit_results[fit_function]) getattr(w, 'import')(signal_norms[fit_function], ROOT.RooCmdArg()) if args.fitBonly: getattr(w, 'import')(models[fit_function], ROOT.RooCmdArg(), RooFit.RecycleConflictNodes()) getattr(w, 'import')(rooDataHist, RooFit.Rename("data_obs")) w.Print() print "Starting save" if args.output_path: if not os.path.isdir(os.path.join(os.getcwd(), args.output_path)): os.mkdir(os.path.join(os.getcwd(), args.output_path)) print "[create_datacards] INFO : Writing workspace to file {}".format( os.path.join(args.output_path, wsName)) w.writeToFile(os.path.join(args.output_path, wsName)) else: print "[create_datacards] INFO : Writing workspace to file {}".format( limit_config.get_workspace_filename( args.analysis, args.model, mass, fitBonly=args.fitBonly, fitSignal=args.fitSignal, correctTrigger=args.correctTrigger)) w.writeToFile( limit_config.get_workspace_filename( args.analysis, args.model, mass, fitBonly=args.fitBonly, fitSignal=args.fitSignal, correctTrigger=args.correctTrigger)) # Clean up for name, obj in signal_norms.iteritems(): if obj: obj.IsA().Destructor(obj) for name, obj in background_pdfs.iteritems(): if obj: obj.IsA().Destructor(obj) for name, obj in background_pdfs_notrig.iteritems(): if obj: obj.IsA().Destructor(obj) for name, obj in background_norms.iteritems(): if obj: obj.IsA().Destructor(obj) for name, obj in signal_pdfs.iteritems(): if obj: obj.IsA().Destructor(obj) for name, obj in signal_pdfs_notrig.iteritems(): if obj: obj.IsA().Destructor(obj) for name, obj in signal_epdfs.iteritems(): if obj: obj.IsA().Destructor(obj) for name, obj in background_epdfs.iteritems(): if obj: obj.IsA().Destructor(obj) for name, obj in fit_results.iteritems(): if obj: obj.IsA().Destructor(obj) for name, dict_l2 in background_parameters.iteritems(): for name2, obj in dict_l2.iteritems(): if obj: obj.IsA().Destructor(obj) for name, obj in models.iteritems(): if obj: obj.IsA().Destructor(obj) rooDataHist.IsA().Destructor(rooDataHist) w.IsA().Destructor(w) # Make datacards only if S+B fitted if not args.fitBonly: beffUnc = 0.3 boffUnc = 0.06 for fit_function in fit_functions: if args.output_path: dcName = 'datacard_' + args.final_state + '_m' + str( mass) + postfix + '_' + fit_function + '.txt' print "[create_datacards] INFO : Writing datacard to file {}".format( os.path.join(args.output_path, dcName)) datacard = open(os.path.join(args.output_path, dcName), 'w') else: print "[create_datacards] INFO : Writing datacard to file {}".format( limit_config.get_datacard_filename( args.analysis, args.model, mass, fit_function, fitSignal=args.fitSignal, correctTrigger=args.correctTrigger)) datacard = open( limit_config.get_datacard_filename( args.analysis, args.model, mass, fit_function, fitSignal=args.fitSignal, correctTrigger=args.correctTrigger), 'w') datacard.write('imax 1\n') datacard.write('jmax 1\n') datacard.write('kmax *\n') datacard.write('---------------\n') if ("jes" in systematics or "jer" in systematics) and not args.fitSignal: if args.output_path: datacard.write('shapes * * ' + wsName + ' w:$PROCESS w:$PROCESS__$SYSTEMATIC\n') else: datacard.write('shapes * * ' + os.path.basename( limit_config.get_workspace_filename( args.analysis, args.model, mass, fitSignal=args.fitSignal, correctTrigger=args.correctTrigger)) + ' w:$PROCESS w:$PROCESS__$SYSTEMATIC\n') else: if args.output_path: datacard.write('shapes * * ' + wsName + ' w:$PROCESS\n') else: datacard.write('shapes * * ' + os.path.basename( limit_config.get_workspace_filename( args.analysis, args.model, mass, fitSignal=args.fitSignal, correctTrigger=args.correctTrigger)) + ' w:$PROCESS\n') datacard.write('---------------\n') datacard.write('bin 1\n') datacard.write('observation -1\n') datacard.write('------------------------------\n') datacard.write('bin 1 1\n') datacard.write('process signal background_' + fit_function + '\n') datacard.write('process 0 1\n') if args.fitSignal: datacard.write('rate 1 1\n') else: datacard.write('rate -1 1\n') datacard.write('------------------------------\n') datacard.write('lumi lnN %f -\n' % (1. + systematics["luminosity"])) datacard.write('beff lnN %f -\n' % (1. + beffUnc)) datacard.write('boff lnN %f -\n' % (1. + boffUnc)) #datacard.write('bkg lnN - 1.03\n') if args.fitSignal: if "jes" in systematics: datacard.write("alpha_jes param 0.0 1.0\n") if "jer" in systematics: datacard.write("alpha_jer param 0.0 1.0\n") else: if "jes" in systematics: datacard.write('JES shape 1 -\n') if "jer" in systematics: datacard.write('JER shape 1 -\n') # flat parameters --- flat prior datacard.write('background_' + fit_function + '_norm flatParam\n') if args.decoBkg: datacard.write('deco_eig1 flatParam\n') datacard.write('deco_eig2 flatParam\n') else: for par_name, par in background_parameters[ fit_function].iteritems(): datacard.write(fit_function + "_" + par_name + ' flatParam\n') datacard.close() print "[create_datacards] INFO : Done with this datacard" #print '>> Datacards and workspaces created and stored in %s/'%( os.path.join(os.getcwd(),args.output_path) ) print "All done."