def _draw(self): passed = self.sim_dir.Get(self.passed_name) total = self.sim_dir.Get(self.total_name) if not TEfficiency.CheckConsistency(passed, total): return None eff = TEfficiency(passed, total) self.hist = eff.CreateHistogram()
def fillAcceptance(self): ''' This is to calculate the acceptance of the sample ''' if debug: print('Info in Sample.fillAcceptance()') #f = TFile.Open(self.infileName) #t = f.Get(self.treeName) #if not t: # raise RuntimeError( 'ERROR: no tree in file %s' % self.infileName) chain = TChain(self.treeName) for fn in self.infileNames: chain.Add(fn) self.effnum = ROOT.TH1F( 'effnum', 'effnum', 1, 0, 13000 ) #dict([(k, ROOT.TH1F('effnum_%s' % k, 'effnum_%s' % k, 1, 0, 1)) for k in self.settings]) self.effden = ROOT.TH1F('effden', 'effden', 1, 0, 13000) if doInclusive: cutsnum = '(l0_pt>{mp} && abs(l0_eta)<1.5'.format(mp=muTrigPt) else: cutsnum = '(l0_pt>{mp} && abs(l0_eta)<1.5 && k_pt>1 && abs(k_eta)<2.5 && pi_pt>1 && abs(pi_eta)<2.5'.format( mp=muTrigPt) if doSkipDispl: cutsnum += '' else: cutsnum += '&& Lxy < 1000' if doSkipHNLptEta: cutsnum += '' else: cutsnum += '&& l1_pt>3 && abs(l1_eta)<2.5 && pi1_pt>0.8 && abs(pi1_eta)<2.5' cutsnum += ')' cutsden = '(l0_pt>{mp} && abs(l0_eta)<1.5)'.format(mp=muTrigPt) chain.Draw('hnl_pt>>effnum', cutsnum + '*' + self.evt_w, 'goff') chain.Draw('hnl_pt>>effden', cutsden + '*' + self.evt_w, 'goff') if TEfficiency.CheckConsistency(self.effnum, self.effden): peff = TEfficiency(self.effnum, self.effden) self.acc = peff.GetEfficiency(1) self.acc_errup = peff.GetEfficiencyErrorUp(1) self.acc_errdn = peff.GetEfficiencyErrorLow(1) # for debugging purposes self.num = self.effnum.GetEntries() if self.num == 0: print('**** 0 entries for mass={}'.format(self.mass)) self.den = self.effden.GetEntries()
def makeEfficiency(passed, total, title, lineColor): if TEfficiency.CheckConsistency(passed, total): efficiency = TEfficiency(passed, total) #title = std::regex_replace(title, std::regex("\\muCandGenEtaMuons"), "tagging efficiency"); efficiency.SetTitle(title) efficiency.SetStatisticOption(6) #TEfficiency.EStatOption.kBUniform efficiency.SetPosteriorMode() efficiency.SetLineColor(lineColor) return efficiency else: print( "makeEfficiency TEfficiency::CheckConsistency(*ptGenPtTTMuonNom, *ptGenPtTTMuonDenom) failed" ) exit(1)
def fillFilterEff(self, dostamp=True): ''' To retrieve and save the filter efficiency - from the minigentree TODO: retrieve the cross-section => for that you would need to run without separate jobs ''' if debug: print('Info in Sample.fillFilterEff()') efffnum = ROOT.TH1F('efffnum', 'efffnum', 1, 0, 13000) efffden = ROOT.TH1F('efffden', 'efffden', 1, 0, 13000) chain = TChain(self.treeName) for fn in self.infileNames: chain.Add(fn) efffnum.SetBinContent(1, chain.GetEntries()) efffnum.SetBinError(1, ROOT.TMath.Sqrt(chain.GetEntries())) # denominator = number of events that were run in the first place # access storage element... #self.ngenevts_succ_afterfilter=0 self.njobs_succ = 0 path = '/pnfs/psi.ch/cms/trivcat/store/user/{u}/BHNLsGen/{pl}/mass{m}_ctau{ctau}/step1*root'.format( u=os.environ['USER'], pl=self.label, m=self.mass, ctau=self.ctau) for fname in glob(path): if debug: print 'fname=', fname f = TFile.Open(fname) if f.GetListOfKeys().Contains('Events'): self.njobs_succ += 1 #njobs_succ = len(glob(path)) self.ngenevts_succ = float(self.ngenevts) / float(self.njobs) * float( self.njobs_succ) efffden.SetBinContent(1, self.ngenevts_succ) efffden.SetBinError(1, ROOT.TMath.Sqrt(self.ngenevts_succ)) if TEfficiency.CheckConsistency(efffnum, efffden): geneff = TEfficiency(efffnum, efffden) self.effFilter = geneff.GetEfficiency(1) self.effFilter_errup = geneff.GetEfficiencyErrorUp(1) self.effFilter_errdn = geneff.GetEfficiencyErrorLow(1) # stamp basic info about filter eff if dostamp: print('mass={m}GeV, VV={vv:.1e}, nTot={nt}, nSucc={ns}, nSuccAfterFilter={nsf}, effFilter={ef:.3f}%, errup={eu:.3f}%, errdn={ed:.3f}% '.format( \ m=self.mass,vv=self.vv,nt=self.ngenevts,ns=self.ngenevts_succ,nsf=efffnum.GetBinContent(1),ef=self.effFilter*100,eu=self.effFilter_errup*100,ed=self.effFilter_errdn*100))
eff_QMisID_name = (histname + "_Efficiency_" + append_str).replace("Fake","QMisID") eff_fake_scaled_name = (histname + "_Efficiency_" + append_str).replace("Fake","ScaledFake") hist_eff_QMisID.SetName(eff_QMisID_name) hist_eff_fake_scaled.SetName(eff_fake_scaled_name) hists[eff_QMisID_name] = hist_eff_QMisID hists[eff_fake_scaled_name] = hist_eff_fake_scaled # ********************************************************************************************************************************* # 2. # The TEfficiency class handles the special cases not covered by TH1::Divide # t_efficiency = None if TEfficiency.CheckConsistency(hist_pass, hist_tot,"w"): t_efficiency = TEfficiency(hist_pass, hist_tot) t_efficiency.SetName(histname + "_TEfficiency_" + append_str) t_efficiency.SetConfidenceLevel(0.683) # Use TEfficiency, with the frequentist Clopper-Pearson confidence interval at XX% CL (set before) # (this handles the eff = 0, 1 case) # # DOES NOT SEEM TO WORK FOR WEIGHTED HISTOGRAMS --> IT REDUCES TO THE NORMAL APPROX # #t_efficiency.SetStatisticOption(TEfficiency.kFCP) # # Use TEfficiency, with the Bayesian uniform prior at XX% CL (set before) # (This is the same as the TGraphAsymmErrors below) #
def makeEoverEtrueAnalysis(inputfile, det, et, iseeding, igathering, nevts, outputdir): print '*******************************************' print 'Starting analysis for det={}, Et={}, seed thrs={}, gather thrs={}'.format( det, et, iseeding, igathering) print 'inputfile={}'.format(inputfile) print '*******************************************' result = EoverEtrueAnalysisResult() if not os.path.isfile(inputfile): return False, result ################### # READ ################## histoname = 'h_PFclusters_genMatched_{det}_eOverEtrue_{Et}'.format(det=det, Et=et) inputdir = 'ecalnoisestudy' subdir = 'EtBinnedQuantities' f = TFile(inputfile, 'READ') histo = f.Get('{}/{}/{}'.format(inputdir, subdir, histoname)) if not histo: return False, result histo.SetMarkerStyle(20) histo.GetXaxis().SetTitle( 'E_{{PFcluster}} / E_{{True}} (GeV)'.format(det=det)) histo.GetYaxis().SetTitle('Entries') histo.GetXaxis().SetRangeUser(0, 2) if det == 'EB': histo.GetYaxis().SetRangeUser(0, 500) else: histo.GetYaxis().SetRangeUser(0, 150) histo.Rebin(2) #histo.GetYaxis().SetRangeUser(0., 1600) #if 'EE' in det: # histo.GetYaxis().SetRangeUser(0., 600) # better to avoid setting the range, since the mean calculation changes #histo.GetXaxis().SetRangeUser(xrange[0], xrange[1]) ################### # FIT ################## #f1 = TF1('f1','crystalball',0.4, 2.) #f1.SetParameters(200, 1, 0.05, 3, 2) # my guess: constant (normalization)=integral, mean = 1, sigma = 0.1, alpha (quanto lontano dal picco si innesta la coda) = 0.7, N = 0.5 (lunghezza della coda(?) #f1.SetLineColor(kRed) f1 = TF1('f1', 'gaus', 0.4, 2.) f1.SetParameter(0, 200) f1.SetParameter(1, histo.GetMean()) f1.SetParameter(2, histo.GetRMS()) # do one first fit on the full range fitresult = histo.Fit(f1, 'RM') # L for loglikelihood , mean = f1.GetParameter(1) sigma = f1.GetParameter(2) f1.SetParameter(1, mean) f1.SetParameter(2, sigma) f1.SetRange(mean - 3 * sigma, mean + 3 * sigma) fitresult = histo.Fit(f1, 'SRM') c = TCanvas() histo.Draw('PE') #fitresult = histo.Fit(f1, 'RS') f1.Draw('same') # save later #fo.cd() #fitresult.Write() #fo.Close() # Get the fitted function parameters and write them to txt file #fit_params = [ ('Param {}'.format(i),'{:.2f}'.format(f1.GetParameter(i)), '{:.2f}'.format(f1.GetParError(i)) ) for i in range(0,5)] #ffitout = open(det + '_' + fitoutfile , 'a') #ffitout.write('\n\nFit results for seeding={} gathering={} subdet={}:\n'.format(iseeding, igathering, det)) #ffitout.write('\nChi2/Ndf=' + str(f1.GetChisquare()) + '/' + str(f1.GetNDF()) + '\n') #par_string = '\n'.join("%s: val=%s err=%s" % tup for tup in fit_params) #ffitout.write(par_string) ################### # Efficiency ################## hpass = TH1F('hpass', 'hpass', 1, 0., 1.) #Npass = histo.GetEntries() # compute efficiency only in +-3 sigma fitted peak Npass = histo.Integral(6, histo.FindLastBinAbove(0.)) # 0.2 cut in EoverEtrue for i in range(0, int(Npass)): hpass.Fill(0.5) #htot = f.Get('{}/{}/{}'.format(inputdir,'general', 'h_genP_pt_{d}'.format(d=det))) htot = TH1F('htot', 'htot', 1, 0., 1.) histoname = 'h_genP_{det}_nEvts_{Et}'.format(det=det, Et=et) h_genP = f.Get('{}/{}/{}'.format(inputdir, subdir, histoname)) Ntot = h_genP.GetEntries() for i in range(0, int(Ntot)): htot.Fill(0.5) print 'eff calculated from npass {} over ntot {}'.format( hpass.GetEntries(), htot.GetEntries()) if TEfficiency.CheckConsistency(hpass, htot): pEff = TEfficiency(hpass, htot) # default stat option is clopper pearson eff = pEff.GetEfficiency(1) erru = pEff.GetEfficiencyErrorUp(1) errd = pEff.GetEfficiencyErrorLow(1) else: eff = 1.0 erru = 1.0 errd = 1.0 eff_label = '{:.4f}+/-{:.4f}'.format(eff, erru) # erru and errd are the same #fout = open(det + '_' + outfile, 'a') #fout.write('Total efficiency for seeding={} gathering={}: {} \n'.format(iseeding,igathering,eff_label)) #fout.close() eff_label = 'N_{{reco}}/N_{{gen}}={}'.format(eff_label) defaultLabels([eff_label], x=0.62, y=0.65, spacing=0.04, size=0.06, dx=0.12) sample_label = '#gamma#gamma, no tracker' et_label = 'Et=({},{})GeV'.format(et.split('_')[0], et.split('_')[1]) det_label = 'Region={}'.format(det) defaultLabels([sample_label, et_label, det_label], x=0.25, y=0.85, spacing=0.04, size=0.06, dx=0.12) ################### # RESULTS ################## c.SaveAs('{o}/EoverEtrue_{det}_Et{et}_seed{s}_gather{g}.pdf'.format( o=outputdir, det=det, s=iseeding, g=igathering, et=et)) c.SaveAs('{o}/EoverEtrue_{det}_Et{et}_seed{s}_gather{g}.png'.format( o=outputdir, det=det, s=iseeding, g=igathering, et=et)) return True, EoverEtrueAnalysisResult(det=det, et=et, eff=eff, erreff=erru, mean=f1.GetParameter(1), errmean=f1.GetParError(1), sigma=f1.GetParameter(2), errsigma=f1.GetParError(2), rms=histo.GetRMS(), errrms=histo.GetRMSError(), iseeding=iseeding, igathering=igathering)
def makeEoverEtrueAnalysis(inputfile, eta, et, iseeding, igathering, nevts, outputdir, doCBfit=False): gROOT.SetBatch(True) gROOT.ProcessLine('.L /work/mratti/CMS_style/tdrstyleGraph.C') gROOT.ProcessLine('setTDRStyle()') print '*******************************************' print 'Starting analysis for Eta={}, Et={}, seed thrs={}, gather thrs={}'.format( eta, et, iseeding, igathering) print 'inputfile={}'.format(inputfile) print '*******************************************' result = EoverEtrueAnalysisResult() if not os.path.isfile(inputfile): print 'ERROR: did not find inputfile', inputfile return False, result ################### # READ ################## #histoname = 'h_PFclusters_genMatched_eOverEtrue_Eta{eta}_Et{et}'.format(eta=eta, et=et) #histoname = 'h_superClusters_genMatched_eOverEtrue_Eta{eta}_Et{et}'.format(eta=eta, et=et) histonameFull = histoname + '_Eta{eta}_Et{et}'.format(eta=eta, et=et) inputdir = 'ecalnoisestudy' subdir = 'EtaEtBinnedQuantities' f = TFile(inputfile, 'READ') histo = f.Get('{}/{}/{}'.format(inputdir, subdir, histonameFull)) if not histo: print 'ERROR: did not find histogram', inputdir, subdir, histonameFull return False, result histo.SetMarkerStyle(20) histo.GetXaxis().SetTitle( 'E_{{PFcluster}} / E_{{True}} (GeV)'.format(eta=eta)) histo.GetYaxis().SetTitle('Entries') histo.GetXaxis().SetRangeUser(0, 2) #histo.GetYaxis().SetRangeUser(0,1500) if eta == "0p00_0p50" and et == "1_20": if '450ifb_nominal' in outputdir: histo.Rebin(2) #histo.GetYaxis().SetRangeUser(0., 1600) #if 'EE' in det: # histo.GetYaxis().SetRangeUser(0., 600) # better to avoid setting the range, since the mean calculation changes #histo.GetXaxis().SetRangeUser(xrange[0], xrange[1]) ################### # FIT ################## if doCBfit: # first fit a gaussian starting from reasonable parameters f0 = TF1('f1', 'gaus', 0.4, 2.) #f0.SetParameter(0, 200) f0.SetParameter(1, histo.GetMean()) f0.SetParameter(2, histo.GetRMS()) fitresult = histo.Fit(f0, 'SRM') mean = f0.GetParameter(1) sigma = f0.GetParameter(2) # refit to gaussian, just to make sure f0.SetParameter(1, mean) f0.SetParameter(2, sigma) f0.SetRange(mean - 3 * sigma, mean + 3 * sigma) fitresult = histo.Fit(f0, 'SRM') mean = f0.GetParameter(1) sigma = f0.GetParameter(2) # then restrict yourself to +/- 3 sigma and fit a crystal ball there f1 = TF1('f1', 'crystalball', 0.4, 2.) Nsigma = 4 if (eta == "1p48_2p00" and et != "1_20") or (eta == "2p50_3p00" and et == "40_60"): Nsigma = 3 f1.SetRange(mean - Nsigma * sigma, mean + Nsigma * sigma) f1.SetParameters( 200, 1, 0.05, 3, 2 ) # my guess: constant (normalization)=integral, mean = 1, sigma = 0.1, alpha (quanto lontano dal picco si innesta la coda) = 0.7, N = 0.5 (lunghezza della coda(?) f1.SetLineColor(kRed) fitresult = histo.Fit(f1, 'SRM') # fit it one more time, starting from fitted parameters f1.SetParameters(f1.GetParameters()) fitresult = histo.Fit(f1, 'SRM') # ... and one more time f1.SetParameters(f1.GetParameters()) fitresult = histo.Fit(f1, 'SRM') # ... and one more time f1.SetParameters(f1.GetParameters()) fitresult = histo.Fit(f1, 'SRM') else: # do one first fit on the full range f1 = TF1('f1', 'gaus', 0.4, 2.) f1.SetParameter(0, 200) f1.SetParameter(1, histo.GetMean()) f1.SetParameter(2, histo.GetRMS()) fitresult = histo.Fit(f1, 'SRM') # then set the initial parameters to the fit parameters and restrict to +/- 3 sigma mean = f1.GetParameter(1) sigma = f1.GetParameter(2) f1.SetParameter(1, mean) f1.SetParameter(2, sigma) f1.SetRange(mean - 3 * sigma, mean + 3 * sigma) fitresult = histo.Fit(f1, 'SRM') # then re-set the initial parameters to the fit parameters and restrict to +/- 2 sigma mean = f1.GetParameter(1) sigma = f1.GetParameter(2) f1.SetParameter(1, mean) f1.SetParameter(2, sigma) f1.SetRange(mean - 2 * sigma, mean + 2 * sigma) fitresult = histo.Fit(f1, 'SRM') # mean = f1.GetParameter(1) # sigma = f1.GetParameter(2) # f1.SetParameter(1, mean) # f1.SetParameter(2, sigma) # f1.SetRange(mean-2*sigma, mean+2*sigma) # fitresult = histo.Fit(f1, 'SRM') c = TCanvas() histo.Draw('PE') #fitresult = histo.Fit(f1, 'RS') f1.Draw('same') # save later ################### # Efficiency ################## hpass = TH1F('hpass', 'hpass', 1, 0., 1.) #Npass = histo.GetEntries() #Npass = histo.Integral(6,histo.FindLastBinAbove(0.)) # 0.2 cut in EoverEtrue Npass = histo.Integral(histo.FindBin(0.4), histo.FindBin(1.4)) # does it make sense to instead compute efficiency only in +-3 sigma fitted peak for i in range(0, int(Npass)): hpass.Fill(0.5) htot = TH1F('htot', 'htot', 1, 0., 1.) histonameFull = 'h_genP_nEvts_Eta{eta}_Et{Et}'.format(eta=eta, Et=et) h_genP = f.Get('{}/{}/{}'.format(inputdir, subdir, histonameFull)) Ntot = h_genP.GetEntries() for i in range(0, int(Ntot)): htot.Fill(0.5) print 'eff calculated from npass {} over ntot {}'.format( hpass.GetEntries(), htot.GetEntries()) if TEfficiency.CheckConsistency(hpass, htot): pEff = TEfficiency(hpass, htot) # default stat option is clopper pearson eff = pEff.GetEfficiency(1) erru = pEff.GetEfficiencyErrorUp(1) errd = pEff.GetEfficiencyErrorLow(1) else: eff = 1.0 erru = 1.0 errd = 1.0 eff_label = '{:.4f}+/-{:.4f}'.format(eff, erru) # erru and errd are the same #fout = open(det + '_' + outfile, 'a') #fout.write('Total efficiency for seeding={} gathering={}: {} \n'.format(iseeding,igathering,eff_label)) #fout.close() eff_label = 'N_{{reco}}/N_{{gen}}={}'.format(eff_label) defaultLabels([eff_label], x=0.62, y=0.65, spacing=0.04, size=0.06, dx=0.12) #sample_label = '#gamma#gamma, no tracker' sample_label = anaLabel et_label = 'Et=({},{})GeV'.format(et.split('_')[0], et.split('_')[1]) eta_label = 'Region=({},{})'.format(eta.split('_')[0], eta.split('_')[1]) defaultLabels([sample_label, et_label, eta_label], x=0.25, y=0.85, spacing=0.04, size=0.06, dx=0.12) ################### # RESULTS ################## c.SaveAs('{o}/EoverEtrue_Eta{eta}_Et{et}_s{s}_g{g}.pdf'.format( o=outputdir, eta=eta, s=iseeding, g=igathering, et=et)) c.SaveAs('{o}/EoverEtrue_Eta{eta}_Et{et}_s{s}_g{g}.png'.format( o=outputdir, eta=eta, s=iseeding, g=igathering, et=et)) return True, EoverEtrueAnalysisResult(eta=eta, et=et, eff=eff, erreff=erru, mean=f1.GetParameter(1), errmean=f1.GetParError(1), sigma=f1.GetParameter(2), errsigma=f1.GetParError(2), rms=histo.GetRMS(), errrms=histo.GetRMSError(), iseeding=iseeding, igathering=igathering)
def MakeOneHist(dirName, histogramName): HeaderLabel = TPaveLabel(header_x_left,header_y_bottom,header_x_right,header_y_top,HeaderText,"NDC") HeaderLabel.SetTextAlign(32) HeaderLabel.SetTextFont(42) HeaderLabel.SetTextSize(0.697674) HeaderLabel.SetBorderSize(0) HeaderLabel.SetFillColor(0) HeaderLabel.SetFillStyle(0) CMSLabel = TPaveLabel(header_x_left,header_y_bottom,header_x_right,header_y_top,HeaderText,"NDC") CMSLabel.SetTextAlign(32) CMSLabel.SetTextFont(42) CMSLabel.SetTextSize(0.697674) CMSLabel.SetBorderSize(0) CMSLabel.SetFillColor(0) CMSLabel.SetFillStyle(0) if makeFancy: LumiLabel = TPaveLabel(topLeft_x_left,topLeft_y_bottom,topLeft_x_right,topLeft_y_top,"CMS Preliminary","NDC") LumiLabel.SetTextFont(62) LumiLabel.SetTextSize(0.7) LumiLabel.SetTextAlign(12) else: LumiLabel = TPaveLabel(topLeft_x_left,topLeft_y_bottom,topLeft_x_right,topLeft_y_top,LumiText,"NDC") LumiLabel.SetTextAlign(32) LumiLabel.SetTextFont(42) LumiLabel.SetBorderSize(0) LumiLabel.SetFillColor(0) LumiLabel.SetFillStyle(0) #legend coordinates, empirically determined :-) x_left = 0.4 x_right = 0.7 y_min = 0.15 y_max = 0.3 Legend = TLegend(x_left,y_min,x_right,y_max) Legend.SetBorderSize(0) Legend.SetFillColor(0) Legend.SetFillStyle(0) Canvas = TCanvas(histogramName) Histograms = [] HistogramClones = [] NBins = [] MaxXValues = [] MinXValues = [] LegendEntries = [] colorIndex = 0 for source in input_sources: # loop over different input sources in config file dataset_file = "condor/%s/%s.root" % (source['condor_dir'],source['dataset']) inputFile = TFile(dataset_file) NumHistogramObj = inputFile.Get(source['num_channel'] + "Plotter/" + dirName + "/" + histogramName) if 'condor_dir_den' in source: # If specified, take the denominator histogram from a different condor directory. dataset_fileDen = "condor/%s/%s.root" % (source['condor_dir_den'],source['dataset']) inputFileDen = TFile(dataset_fileDen) DenHistogramObj = inputFileDen.Get(source['den_channel'] + "Plotter/" + dirName + "/" + histogramName) else: # Default is to use the same condor directory DenHistogramObj = inputFile.Get(source['den_channel'] + "Plotter/" + dirName + "/" + histogramName) if not NumHistogramObj: print "WARNING: Could not find histogram " + source['num_channel'] + "Plotter/" + dirName + "/" + histogramName + " in file " + dataset_file + ". Will skip it and continue." return if not DenHistogramObj: print "WARNING: Could not find histogram " + source['den_channel'] + "Plotter/" + dirName + "/" + histogramName + " in file " + dataset_file + ". Will skip it and continue." return Histogram = NumHistogramObj.Clone() if Histogram.Class().InheritsFrom("TH2"): Histogram.SetName(Histogram.GetName() + "__" + source['dataset']) Histogram.SetDirectory(0) DenHistogram = DenHistogramObj.Clone() DenHistogram.SetDirectory(0) inputFile.Close() nbinsN = Histogram.GetNbinsX() nbinsD = DenHistogram.GetNbinsX() if not noOverFlow: # Add overflow Histogram.SetBinContent( nbinsN, Histogram.GetBinContent(nbinsN) + Histogram.GetBinContent(nbinsN+1)) DenHistogram.SetBinContent(nbinsD, DenHistogram.GetBinContent(nbinsD) + DenHistogram.GetBinContent(nbinsD+1)) # Set the errors to be the sum in quadrature Histogram.SetBinError( nbinsN, math.sqrt(math.pow(Histogram.GetBinError(nbinsN),2) + math.pow(Histogram.GetBinError(nbinsN+1),2))) DenHistogram.SetBinError(nbinsD, math.sqrt(math.pow(DenHistogram.GetBinError(nbinsD),2) + math.pow(DenHistogram.GetBinError(nbinsD+1),2))) if not noUnderFlow: # Add underflow Histogram.SetBinContent( 1, Histogram.GetBinContent(1) + Histogram.GetBinContent(0)) DenHistogram.SetBinContent(1, DenHistogram.GetBinContent(1) + DenHistogram.GetBinContent(0)) # Set the errors to be the sum in quadrature Histogram.SetBinError( 1, math.sqrt(math.pow(Histogram.GetBinError(1), 2) + math.pow(Histogram.GetBinError(0), 2))) DenHistogram.SetBinError(1, math.sqrt(math.pow(DenHistogram.GetBinError(1), 2) + math.pow(DenHistogram.GetBinError(0), 2))) if arguments.rebinFactor: RebinFactor = int(arguments.rebinFactor) #don't rebin histograms which will have less than 5 bins or any gen-matching histograms if Histogram.GetNbinsX() >= RebinFactor*5 and Histogram.GetTitle().find("GenMatch") is -1 and not Histogram.Class().InheritsFrom("TH2"): Histogram.Rebin(RebinFactor) DenHistogram.Rebin(RebinFactor) xAxisLabel = Histogram.GetXaxis().GetTitle() unitBeginIndex = xAxisLabel.find("[") unitEndIndex = xAxisLabel.find("]") if unitBeginIndex is not -1 and unitEndIndex is not -1: #x axis has a unit yAxisLabel = "#epsilon_{ " + cutName + "} (" + str(Histogram.GetXaxis().GetBinWidth(1)) + " " + xAxisLabel[unitBeginIndex+1:unitEndIndex] + " width)" else: yAxisLabel = "#epsilon_{ " + cutName + "} (" + str(Histogram.GetXaxis().GetBinWidth(1)) + " width)" if arguments.normalizeToUnitArea: yAxisLabel = yAxisLabel + " (Unit Area Norm.)" #check if bin content is consistent TEfficiency.CheckConsistency(Histogram,DenHistogram) for i in range(1,Histogram.GetNbinsX()+1): if Histogram.GetBinContent(i) > DenHistogram.GetBinContent(i): DenHistogram.SetBinContent(i,Histogram.GetBinContent(i)) #HistogramClone and HistogramClones only used for ratio plot HistogramClone = Histogram.Clone() HistogramClone.SetDirectory(0) HistogramClone.Divide(DenHistogram) Nbins = HistogramClone.GetNbinsX() MaxXValue = HistogramClone.GetXaxis().GetBinLowEdge(Nbins+1) MinXValue = HistogramClone.GetXaxis().GetBinLowEdge(1) #this Histogram becomes the main TEfficiency if Histogram.Class().InheritsFrom("TH2"): Histogram.Divide(DenHistogram) else: #using default methods (which give correct uncertainties) #see https://root.cern.ch/doc/master/classTEfficiency.html (c.f. section IV) Histogram = TEfficiency(Histogram,DenHistogram) if not arguments.makeFancy: fullTitle = Histogram.GetTitle() splitTitle = fullTitle.split(":") # print splitTitle if len(splitTitle) > 1: histoTitle = splitTitle[1].lstrip(" ") else: histoTitle = splitTitle[0] else: histoTitle = "" if 'color' in source: Histogram.SetMarkerColor(colors[source['color']]) Histogram.SetLineColor(colors[source['color']]) else: Histogram.SetMarkerColor(colors[colorList[colorIndex]]) Histogram.SetLineColor(colors[colorList[colorIndex]]) colorIndex = colorIndex + 1 if colorIndex is len(colorList): colorIndex = 0 markerStyle = 20 if 'marker' in source: markerStyle = markers[source['marker']] if 'fill' in source: markerStyle = markerStyle + fills[source['fill']] Histogram.SetMarkerStyle(markerStyle) Histogram.SetLineWidth(line_width) Histogram.SetFillStyle(0) LegendEntries.append(source['legend_entry']) Histograms.append(Histogram) HistogramClones.append(HistogramClone) NBins.append(Nbins) MaxXValues.append(MaxXValue) MinXValues.append(MinXValue) ### scaling histograms as per user's specifications for histogram in Histograms: if arguments.normalizeToUnitArea and histogram.Integral() > 0: histogram.Scale(1./histogram.Integral()) ### formatting histograms and adding to legend legendIndex = 0 for histogram in Histograms: Legend.AddEntry(histogram,LegendEntries[legendIndex],"LEP") legendIndex = legendIndex+1 ### finding the maximum value of anything going on the canvas, so we know how to set the y-axis finalMax = 1.1 if arguments.setYMax: finalMax = float(arguments.setYMax) ### Drawing histograms to canvas makeRatioPlots = arguments.makeRatioPlots makeDiffPlots = arguments.makeDiffPlots addOneToRatio = -1 if arguments.addOneToRatio: addOneToRatio = arguments.addOneToRatio dontRebinRatio = -1 if arguments.dontRebinRatio: dontRebinRatio = arguments.dontRebinRatio ratioRelErrMax = -1 if arguments.ratioRelErrMax: ratioRelErrMax = arguments.ratioRelErrMax yAxisMin = 0.0001 if arguments.setYMin: yAxisMin = float(arguments.setYMin) if makeRatioPlots or makeDiffPlots: Canvas.SetFillStyle(0) Canvas.Divide(1,2) Canvas.cd(1) gPad.SetPad(0,0.25,1,1) gPad.SetMargin(0.15,0.05,0.01,0.07) gPad.SetFillStyle(0) gPad.Update() gPad.Draw() if arguments.setLogY: gPad.SetLogy() Canvas.cd(2) gPad.SetPad(0,0,1,0.25) #format: gPad.SetMargin(l,r,b,t) gPad.SetMargin(0.15,0.05,0.4,0.01) gPad.SetFillStyle(0) gPad.SetGridy(1) gPad.Update() gPad.Draw() Canvas.cd(1) histCounter = 0 plotting_options = "" if arguments.plot_hist: plotting_options = "HIST" h = TH2F("h1","",NBins[0],MinXValues[0],MaxXValues[0],110,0.,finalMax) h.SetTitle(";"+xAxisLabel+";"+yAxisLabel) h.Draw() for histogram in Histograms: if histogram.Class().InheritsFrom("TH2"): histogram.SetTitle(histoTitle) histogram.Draw("colz") DatasetName = histogram.GetName() DatasetName = DatasetName[DatasetName.rfind('__')+2:] # substring starting with the last underscore DatasetLabel = TPaveLabel(topLeft_x_left,topLeft_y_bottom,topLeft_x_right,topLeft_y_top,DatasetName,"NDC") DatasetLabel.SetBorderSize(0) DatasetLabel.SetFillColor(0) DatasetLabel.SetFillStyle(0) DatasetLabel.Draw() outputFile.cd() Canvas.SetName(histogram.GetName()) Canvas.Write() else: if histogram.InheritsFrom("TEfficiency") and histCounter==0: plotting_options = "P SAME" histogram.SetTitle(histoTitle) histogram.Draw(plotting_options) if histogram.InheritsFrom("TH1"): histogram.SetMaximum(finalMax) histogram.SetMinimum(yAxisMin) if histCounter is 0: if histogram.InheritsFrom("TH1"): plotting_options = plotting_options + " SAME" elif histogram.InheritsFrom("TEfficiency"): plotting_options = "P" + " SAME" histCounter = histCounter + 1 if histogram.Class().InheritsFrom("TH2"): return Legend.Draw() if arguments.makeFancy: HeaderLabel.Draw() LumiLabel.Draw() #drawing the ratio or difference plot if requested if makeRatioPlots or makeDiffPlots: Canvas.cd(2) if makeRatioPlots: makeRatio = functools.partial (ratioHistogram,HistogramClones[0],HistogramClones[1]) if addOneToRatio != -1: # it gets initialized to this dummy value of -1 makeRatio = functools.partial (makeRatio, addOne = bool (addOneToRatio)) if ratioRelErrMax is not -1: # it gets initialized to this dummy value of -1 makeRatio = functools.partial (makeRatio, relErrMax = float (ratioRelErrMax)) if dontRebinRatio is True: makeRatio = functools.partial (makeRatio, dontRebinRatio) Comparison = makeRatio () elif makeDiffPlots: Comparison = Histograms[0].Clone("diff") Comparison.Add(Histograms[1],-1) Comparison.SetTitle("") Comparison.GetYaxis().SetTitle("hist1-hist2") Comparison.GetXaxis().SetTitle(xAxisLabel) Comparison.GetYaxis().CenterTitle() Comparison.GetYaxis().SetTitleSize(0.1) Comparison.GetYaxis().SetTitleOffset(0.5) Comparison.GetXaxis().SetTitleSize(0.15) Comparison.GetYaxis().SetLabelSize(0.1) Comparison.GetXaxis().SetLabelSize(0.15) if makeRatioPlots: RatioYRange = 1.15 if arguments.ratioYRange: RatioYRange = float(arguments.ratioYRange) if addOneToRatio == -1: # it gets initialized to this dummy value of -1 Comparison.GetYaxis().SetRangeUser(-1*RatioYRange, RatioYRange) else: Comparison.GetYaxis().SetRangeUser(-1*RatioYRange + 1.0, RatioYRange + 1.0) elif makeDiffPlots: YMax = Comparison.GetMaximum() YMin = Comparison.GetMinimum() if YMax <= 0 and YMin <= 0: Comparison.GetYaxis().SetRangeUser(-1.2*YMin,0) elif YMax >= 0 and YMin >= 0: Comparison.GetYaxis().SetRangeUser(0,1.2*YMax) else: #axis crosses y=0 if abs(YMax) > abs(YMin): Comparison.GetYaxis().SetRangeUser(-1.2*YMax,1.2*YMax) else: Comparison.GetYaxis().SetRangeUser(-1.2*YMin,1.2*YMin) Comparison.GetYaxis().SetNdivisions(205) Comparison.Draw("E0") outputFile.cd(dirName) Canvas.Write() if arguments.savePDFs: Canvas.SaveAs("efficiency_histograms_pdfs/"+histogramName+".pdf")
def fillAcceptance(self): ''' This is to calculate the acceptance of the sample ''' if debug: print('Info in Sample.fillAcceptance()') #f = TFile.Open(self.infileName) #t = f.Get(self.treeName) #if not t: # raise RuntimeError( 'ERROR: no tree in file %s' % self.infileName) chain = TChain(self.treeName) for fn in self.infileNames: chain.Add(fn) self.effnum = ROOT.TH1F('effnum', 'effnum', 1, 0, 13000) self.effden = ROOT.TH1F('effden', 'effden', 1, 0, 13000) self.effnumB = dict([(b, ROOT.TH1F('effnum_%s' % b, 'effnum_%s' % b, 1, 0, 13000)) for b in self.Bspecies]) self.effdenB = dict([(b, ROOT.TH1F('effden_%s' % b, 'effden_%s' % b, 1, 0, 13000)) for b in self.Bspecies]) #if doInclusive: cutsnum = '(l0_pt>{mp} && abs(l0_eta)<1.5'.format(mp=muTrigPt) #else: #cutsnum = '(l0_pt>{mp} && abs(l0_eta)<1.5 && k_pt>1 && abs(k_eta)<2.5 && pi_pt>1 && abs(pi_eta)<2.5'.format(mp=muTrigPt) if doSkipDispl: cutsnum += '' else: cutsnum += '&& Lxy < 500' if not doDisplZ: pass else: cutsnum += '&& Lz < 20' if doSkipHNLptEta: cutsnum += '' else: cutsnum += '&& l1_pt>3 && abs(l1_eta)<2.5 && pi1_pt>0.8 && abs(pi1_eta)<2.5' cutsnum += ')' cutsden = '(l0_pt>{mp} && abs(l0_eta)<1.5)'.format(mp=muTrigPt) ###### fill the total acceptance chain.Draw('hnl_pt>>effnum', cutsnum+'*'+self.evt_w, 'goff') chain.Draw('hnl_pt>>effden', cutsden, 'goff') if TEfficiency.CheckConsistency(self.effnum,self.effden): peff = TEfficiency(self.effnum,self.effden) # check usage of TGraphAsymmetricErrors self.acc = peff.GetEfficiency(1) self.acc_errup = peff.GetEfficiencyErrorUp(1) self.acc_errdn = peff.GetEfficiencyErrorLow(1) tgra = TGraphAsymmErrors() tgra.BayesDivide(self.effnum, self.effden) self.acc_tg = tgra.GetY()[0] self.acc_errup_tg = tgra.GetErrorYhigh(0) self.acc_errdn_tg = tgra.GetErrorYlow(0) # for debugging purposes self.num = self.effnum.GetEntries() if self.num==0: print('**** 0 entries for mass={}'.format(self.mass)) self.den = self.effden.GetEntries() ###### fill the partial acceptances for ib,b in enumerate(self.Bspecies): bsel = '(abs(b_pdgid)=={bid})'.format(bid=self.BpdgIds[ib]) selnum = '(' + cutsnum + '&&' + bsel + ')' selden = '(' + cutsden + '&&' + bsel + ')' chain.Draw('hnl_pt>>effnum_{b}'.format(b=b), selnum + '*' + self.evt_w, 'goff') chain.Draw('hnl_pt>>effden_{b}'.format(b=b), selden, 'goff') if TEfficiency.CheckConsistency(self.effnumB[b],self.effdenB[b]): peff = TEfficiency(self.effnumB[b],self.effdenB[b]) self.accB[b] = peff.GetEfficiency(1) self.accB_errup[b] = peff.GetEfficiencyErrorUp(1) self.accB_errdn[b] = peff.GetEfficiencyErrorLow(1) else: self.accB[b] = 0 self.accB_errup[b] = 0 self.accB_errdn[b] = 0