def resolutionGraph( tree, xVar, yVar, title, measure, cut='', weightExpression='' ): ## Create and fill a resolution graph for this dataset, i.e. resolution of y vs. x # @ param tree TTree object used to create the histogram # @ param xVar Variable object defining the xAxis and the draw command # @ param yVar Variable object defining the xAxis and the draw command # @ param title histogram title # @param measure Measure object to evaluate the resolution # @ param cut Cut object (optional) # @ param weightExpression weight expression (optional) # @ return the generated histogram bins = xVar.binning.bins title = '%s vs %s' % (yVar.title, xVar.title) if not title else title name = 'h%s_%s' % ( title.replace(' ', '_').replace('(', '').replace(')',''), uuid.uuid1() ) from ROOT import TGraphAsymmErrors graph = TGraphAsymmErrors( xVar.binning.nBins ) graph.SetNameTitle( name, '%s;%s;%s' % (title, xVar.axisLabel, measure.getDecoratedLabel( yVar ) ) ) # create a histogram of y for each bin in x and evaluate measure for iBin in xrange( xVar.binning.nBins ): low = bins[iBin] up = bins[iBin+1] xMean = low + 0.5 * (up - low) xErr = xMean - low myCut = (Cut( '%s >= %s && %s < %s' % (xVar.command, low, xVar.command, up) ) + cut) * weightExpression values, weights = getValuesFromTree( tree, yVar.command, myCut.cut ) yMean, yErrLow, yErrUp = measure.calculateFromValues( values, weights ) graph.SetPoint( iBin, xMean, yMean ) graph.SetPointError( iBin, xErr, xErr, yErrLow, yErrUp ) return graph
def histToGraph(hist, name='', keepErrors=True, poissonErrors=True): ## Helper method to convert a histogram to a corresponding graph # @hist TH1 object # @name name of the graph (default is name of histogram) # @keepErrors decide if the y-errors should be propagated to the graph # @poissonErrors decide if the y-errors should be calculated as Poisson errors # @return graph if not name: name = 'g%s' % (hist.GetName()) from ROOT import TGraphAsymmErrors nBins = hist.GetNbinsX() graph = TGraphAsymmErrors(nBins) graph.SetNameTitle(name, hist.GetTitle()) xAxis = hist.GetXaxis() for i in xrange(nBins): xVal = xAxis.GetBinCenter(i + 1) yVal = hist.GetBinContent(i + 1) graph.SetPoint(i, xVal, yVal) graph.SetPointEXlow(i, abs(xVal - xAxis.GetBinLowEdge(i + 1))) graph.SetPointEXhigh(i, abs(xVal - xAxis.GetBinUpEdge(i + 1))) if keepErrors: if poissonErrors: lo, hi = calculatePoissonErrors(yVal) graph.SetPointEYlow(i, lo) graph.SetPointEYhigh(i, hi) else: graph.SetPointEYlow(i, hist.GetBinErrorLow(i + 1)) graph.SetPointEYhigh(i, hist.GetBinErrorUp(i + 1)) # copy the style graph.SetMarkerStyle(hist.GetMarkerStyle()) graph.SetMarkerColor(hist.GetMarkerColor()) graph.SetMarkerSize(hist.GetMarkerSize()) graph.SetLineStyle(hist.GetLineStyle()) graph.SetLineColor(hist.GetLineColor()) graph.SetLineWidth(hist.GetLineWidth()) graph.SetFillColor(hist.GetFillColor()) graph.SetFillStyle(hist.GetFillStyle()) return graph
def main(): """ Main function """ parser = argparse.ArgumentParser(description="Arguments to pass") parser.add_argument( "configfile_name", metavar="text", default="config_Dplus_pp5TeV.yml", help="input yaml config file", ) parser.add_argument("--batch", action="store_true", default=False, help="suppress video output") args = parser.parse_args() if args.batch: gROOT.SetBatch(True) # load info from config file with open(args.configfile_name, "r") as yml_configfile: cfg = yaml.safe_load(yml_configfile) frac_method = cfg["fraction"] histos, norm = load_inputs(cfg) # consistency check of bins ptlims = {} for histo in ["rawyields", "acceffp", "acceffnp"]: ptlims[histo] = get_hist_binlimits(histos[histo]) if (histo != "rawyields" and not np.equal(ptlims[histo], ptlims["rawyields"]).all()): print("\033[91mERROR: histo binning not consistent. Exit\033[0m") sys.exit(10) # compute cross section axistit_cross = "d#sigma/d#it{p}_{T} (pb GeV^{-1} #it{c})" axistit_cross_times_br = "d#sigma/d#it{p}_{T} #times BR (pb GeV^{-1} #it{c})" axistit_pt = "#it{p}_{T} (GeV/#it{c})" axistit_fprompt = "#if{f}_{prompt}" gfraction = TGraphAsymmErrors(0) gfraction.SetNameTitle("gfraction", f";{axistit_pt};{axistit_fprompt}") hptspectrum = TH1F( "hptspectrum", f";{axistit_pt};{axistit_cross}", len(ptlims["rawyields"]) - 1, ptlims["rawyields"], ) hptspectrum_wo_br = TH1F( "hptspectrum_wo_br", f";{axistit_pt};{axistit_cross_times_br}", len(ptlims["rawyields"]) - 1, ptlims["rawyields"], ) for i_pt, (ptmin, ptmax) in enumerate( zip(ptlims["rawyields"][:-1], ptlims["rawyields"][1:])): pt_cent = (ptmax + ptmin) / 2 pt_delta = ptmax - ptmin rawy = histos["rawyields"].GetBinContent(i_pt + 1) rawy_unc = histos["rawyields"].GetBinError(i_pt + 1) eff_times_acc_prompt = histos["acceffp"].GetBinContent(i_pt + 1) eff_times_acc_nonprompt = histos["acceffnp"].GetBinContent(i_pt + 1) ptmin_fonll = ( histos["FONLL"]["nonprompt"]["central"].GetXaxis().FindBin(ptmin * 1.0001)) ptmax_fonll = ( histos["FONLL"]["nonprompt"]["central"].GetXaxis().FindBin(ptmax * 0.9999)) crosssec_nonprompt_fonll = [ histos["FONLL"]["nonprompt"][pred].Integral( ptmin_fonll, ptmax_fonll, "width") / (ptmax - ptmin) for pred in histos["FONLL"]["nonprompt"] ] # compute prompt fraction if frac_method == "Nb": frac = compute_fraction_nb( # BR already included in FONLL prediction rawy, eff_times_acc_prompt, eff_times_acc_nonprompt, crosssec_nonprompt_fonll, pt_delta, 1.0, 1.0, norm["events"], norm["sigmaMB"], ) elif frac_method == "fc": crosssec_prompt_fonll = [ histos["FONLL"]["prompt"][pred].Integral( ptmin_fonll, ptmax_fonll, "width") / (ptmax - ptmin) for pred in histos["FONLL"]["prompt"] ] frac = compute_fraction_fc( eff_times_acc_prompt, eff_times_acc_nonprompt, crosssec_prompt_fonll, crosssec_nonprompt_fonll, ) # compute cross section times BR crosssec, crosssec_unc = compute_crosssection( rawy, rawy_unc, frac[0], eff_times_acc_prompt, ptmax - ptmin, 1.0, norm["sigmaMB"], norm["events"], 1.0, frac_method, ) hptspectrum.SetBinContent(i_pt + 1, crosssec / norm["BR"]) hptspectrum.SetBinError(i_pt + 1, crosssec_unc / norm["BR"]) hptspectrum_wo_br.SetBinContent(i_pt + 1, crosssec) hptspectrum_wo_br.SetBinError(i_pt + 1, crosssec_unc) gfraction.SetPoint(i_pt, pt_cent, frac[0]) gfraction.SetPointError(i_pt, pt_delta / 2, pt_delta / 2, frac[0] - frac[1], frac[2] - frac[0]) # create plots style_hist = StyleObject1D() style_hist.markercolor = kAzure + 4 style_hist.markerstyle = kFullCircle style_hist.markersize = 1 style_hist.linecolor = kAzure + 4 style_hist.linewidth = 2 style_hist.draw_options = "P" fig_crosssec = ROOTFigure(1, 1, column_margin=(0.14, 0.035), row_margin=(0.1, 0.035), size=(600, 800)) fig_crosssec.axes(label_size=0.025, title_size=0.030) fig_crosssec.axes("x", title=axistit_pt, title_offset=1.5) fig_crosssec.axes("y", title=axistit_cross_times_br, title_offset=1.8) fig_crosssec.define_plot(0, 0, y_log=True) fig_crosssec.add_object(hptspectrum_wo_br, style=style_hist) fig_crosssec.create() output_dir = cfg["output"]["directory"] if not os.path.exists(output_dir): os.makedirs(output_dir) fig_crosssec.save( os.path.join(output_dir, f'{cfg["output"]["filename"]}.pdf')) # save output file output_file = TFile( os.path.join(output_dir, f'{cfg["output"]["filename"]}.root'), "recreate") hptspectrum.Write() hptspectrum_wo_br.Write() gfraction.Write() for hist in histos: if isinstance(histos[hist], TH1): histos[hist].Write() else: for flav in histos[hist]: for pred in histos[hist][flav]: histos[hist][flav][pred].Write() output_file.Close()