def importHistograms(filepath): # dictionary structure for collecting all histograms hists = {} f_allhists = HistogramGetter.getHistograms(filepath) for fs, sp in f_allhists: if fs not in hists: hists[fs] = {} for hkey in f_allhists[(fs, sp)]: if hkey not in hists[fs]: hists[fs][hkey] = f_allhists[(fs, sp)][hkey].Clone() else: hists[fs][hkey].Add(f_allhists[(fs, sp)][hkey]) hname = hists[fs][hkey].GetName() if "HTo2X" in hname: if "4Mu" in hname: # hkey has the form KEY_HTo2XTo4Mu_mH_mX_cTau matches = Patterns["HTo2XTo4Mu"].match(hname) fs = "4Mu" elif "2Mu2J" in hname: # hname has the form KEY_HTo2XTo2Mu2J_mH_mX_cTau matches = Patterns["HTo2XTo2Mu2J"].match(hname) if "reHLT_CosmicSeed" in hname: matches = Patterns[ "HTo2XTo2Mu2J_reHLT_CosmicSeed"].match(hname) if "reHLT_ppSeed" in hname: matches = Patterns["HTo2XTo2Mu2J_reHLT_ppSeed"].match( hname) if matches: sp = tuple(map(int, matches.group(2, 3, 4))) hname = hname.replace("_{}_{}_{}".format(*sp), "") hists[fs][hkey].SetName(hname) else: raise NotImplementedError( "Only signal samples supported at this point") return hists
import re import ROOT as R import DisplacedDimuons.Analysis.Plotter as Plotter import DisplacedDimuons.Analysis.RootTools as RT import DisplacedDimuons.Analysis.Selections as Selections from DisplacedDimuons.Common.Utilities import SPStr, SPLumiStr import DisplacedDimuons.Analysis.HistogramGetter as HistogramGetter TRIGGER = False # get histograms HISTS = HistogramGetter.getHistograms( '../analyzers/roots/Main/nMinusOnePlots.root') f = R.TFile.Open('../analyzers/roots/Main/nMinusOnePlots.root') # make per sample plots def makePerSamplePlots(): for ref in HISTS: for key in HISTS[ref]: if type(ref) == tuple: if ref[0] == '4Mu': name = 'HTo2XTo4Mu_' elif ref[0] == '2Mu2J': name = 'HTo2XTo2Mu2J_' name += SPStr(ref[1]) if TRIGGER: name = 'Trig-' + name lumi = SPLumiStr(ref[0], *ref[1]) legName = HistogramGetter.PLOTCONFIG['HTo2XTo' + ref[0]]['LATEX'] else: name = ref
import re import ROOT as R import DisplacedDimuons.Analysis.Plotter as Plotter import DisplacedDimuons.Analysis.RootTools as RT from DisplacedDimuons.Common.Utilities import SPStr, SPLumiStr import DisplacedDimuons.Analysis.HistogramGetter as HistogramGetter import DisplacedDimuons.Analysis.PlotterParser as PlotterParser ARGS = PlotterParser.PARSER.parse_args() TRIGGER = ARGS.TRIGGER CUTSTRING = ARGS.CUTSTRING MCONLY = ARGS.MCONLY # get histograms HISTS = HistogramGetter.getHistograms( '../analyzers/roots/Main/RecoMuonPlots.root') f = R.TFile.Open('../analyzers/roots/Main/RecoMuonPlots.root') # make plots that are per sample def makePerSamplePlots(): for ref in HISTS: if not type(ref) == tuple: continue for key in HISTS[ref]: if 'deltaRGR' in key: continue if 'VS' in key: continue if type(ref) == tuple: if ref[0] == '4Mu': name = 'HTo2XTo4Mu_' latexFS = '4#mu' elif ref[0] == '2Mu2J':
import re import ROOT as R import DisplacedDimuons.Analysis.Plotter as Plotter import DisplacedDimuons.Analysis.RootTools as RT from DisplacedDimuons.Common.Constants import SIGNALPOINTS from DisplacedDimuons.Common.Utilities import SPStr, SPLumiStr import DisplacedDimuons.Analysis.HistogramGetter as HistogramGetter import DisplacedDimuons.Analysis.PlotterParser as PlotterParser ARGS = PlotterParser.PARSER.parse_args() TRIGGER = ARGS.TRIGGER CUTSTRING = ARGS.CUTSTRING # get histograms HISTS = HistogramGetter.getHistograms( '../analyzers/roots/Main/SignalVertexFitEffPlots.root') f = R.TFile.Open('../analyzers/roots/Main/SignalVertexFitEffPlots.root') # make overlaid plots that combine all signal points def makeEffPlots(quantity, fs, SP=None): HKeys = { 'Eff': '{}Eff', 'Den': '{}Den', } for key in HKeys: HKeys[key] = HKeys[key].format(quantity) h = {} p = {} g = {}
def importHistograms(DISTRIBUTION_SPECS): """ Read and add specified histograms from one or many files. Extracts histograms from one or many ROOT files (defined via the argument 'DISTRIBUTION_SPECS') and adds them to the given HistSpecs objects. Parameters ---------- DISTRIBUTION_SPECS : HistSpecs object An instance of the HistSpecs class, which defines all the relevant histogram properties """ # perform some basic sanity checks for el in DISTRIBUTION_SPECS: filepath = el.getAttribute("filepath") histname_identifier = el.getAttribute("histname_identifier") histname_exclude = el.getAttribute("histname_exclude") types = ((filepath, str), (histname_identifier, str), (histname_exclude, list)) for o, t in types: if not isinstance(o, t): raise Exception( "Invalid type of {}: should be {}, but is {}".format( o, t, type(o))) if not os.path.exists(filepath): raise Exception("No such file: {}".format(filepath)) # dictionary structure for collecting the relevant distributions hists = {} cnt_files = 1 for el in DISTRIBUTION_SPECS: filepath = el.getAttribute("filepath") histname_identifier = el.getAttribute("histname_identifier") histname_exclude = el.getAttribute("histname_exclude") print("[{}/{}] Reading file {}...".format(cnt_files, len(DISTRIBUTION_SPECS), filepath)) f_allhists = HistogramGetter.getHistograms(filepath) histogram = None for dataset in f_allhists: selected_hists_names = getHistNames(f_allhists, dataset, histname_identifier, exclude=histname_exclude) print("hist names: {}".format(selected_hists_names)) if len(selected_hists_names) > 1: raise Exception( "Ambiguous histogram identifier: {} would select the following {} histograms: {}" .format(histname_identifier, len(selected_hists_names), '\n'.join(selected_hists_names))) for key in selected_hists_names: if histogram is None: histogram = f_allhists[dataset][key].Clone() else: histogram.Add(f_allhists[dataset][key]) if histogram: print("\tImported histogram {}".format(histogram.GetName())) else: print("\tNo histograms found.") # prepare the histogram RT.addFlows(histogram) if el.getAttribute("histogram") is not None: print( "Warning: Histogram already exists in the HistSpecs object and will be overwritten" ) # add the actual histrogram to the corresponding HistSpecs object el.setAttribute("histogram", histogram) cnt_files += 1 del f_allhists
def collectHistograms(file_specs, hist_patterns_and_excludes): # structure for storing the histograms h = { f: { "appearance": app, "descr": d, "hists": {} } for app, f, d in file_specs } # lists of keys for each file (for consistency checks) lists_of_keys = {f: [] for __, f, __ in file_specs} cnt = 1 for __, f, __ in file_specs: print("[{}/{}] Reading file {}...".format(cnt, len(file_specs), f)) cnt += 1 f_hists = HistogramGetter.getHistograms(f) for pattern, exclude in hist_patterns_and_excludes: for dataset in f_hists: selected_hists_names = getHistNames(f_hists, dataset, pattern, exclude=exclude) for key in selected_hists_names: if key not in h[f]["hists"]: h[f]["hists"][key] = f_hists[dataset][key].Clone() else: h[f]["hists"][key].Add(f_hists[dataset][key]) lists_of_keys[f].append(key) print("\tImported {} histograms".format(len(h[f]["hists"].keys()))) # check whether all the histograms exist in all the files found_inconsistency = False for i, f in enumerate(lists_of_keys): for j in range(len(lists_of_keys.keys())): if i == j: continue for key in lists_of_keys[f]: if key not in lists_of_keys[lists_of_keys.keys()[j]]: print("[WARNING] Inconsistency in file contents. " "Histogram {} not present in file {}".format( key, lists_of_keys.keys()[j])) found_inconsistency = True if not found_inconsistency: print("[INFO] Consistency checks passed") else: print("[WARNING] Consistency checks failed") return h
"pTdiff": (-1.1, 10.0), "d0": (0.0, 200), "L1pTres": (-1.0, 8.0), "L2pTres": (-1.0, 8.0), "dimVtxChi2": (0.0, 60.0), "dimLxySig": (0.0, 230.0), "chi2": (0.0, 30.0), "pTSig": (0.0, 2.0), "nStations": (0.0, 10.0), "nCSCDTHits": (10.0, 60.0), "chargeprod": (-1.0, 2.0), "charge": (-1.0, 2.0), } HISTS = HistogramGetter.getHistograms( "/afs/cern.ch/work/s/stempl/private/DDM/cosmics-studies/simulation-validation/Cosmics2016_UGMT-bottomOnly_HLT-ppSeed.root" ) def makePerSamplePlots(selection=None): rebinning_exceptions = ("pTdiff", "nCSCDTHits") h = {} p = {} for dataset in HISTS: if selection is not None: selected_hists_names = getHistNames(dataset, *selection) else: selected_hists_names = HISTS[dataset] for key in selected_hists_names:
import re import ROOT as R from ROOT import gStyle, gPad import DisplacedDimuons.Analysis.Plotter as Plotter import DisplacedDimuons.Analysis.RootTools as RT from DisplacedDimuons.Common.Utilities import SPStr, SPLumiStr import DisplacedDimuons.Analysis.HistogramGetter as HistogramGetter TRIGGER = True PRINTINTEGRALS = False # get histograms HISTS = HistogramGetter.getHistograms( '../analyzers/roots/muonQualityStudies_HTo2XTo2Mu2J_1000_150_1000.root') #HISTS = HistogramGetter.getHistograms('../analyzers/roots/muonQualityStudies_HTo2XTo2Mu2J_125_20_1300.root') #f = R.TFile.Open('../analyzers/roots/muonQualityStudies_HTo2XTo2Mu2J_1000_150_1000.root') # make plots that are per sample def makePerSamplePlots(): for ref in HISTS: print "ref: ,", ref if type(ref) == tuple: if ref[0] == '4Mu': name = 'HTo2XTo4Mu_' latexFS = '4#mu' elif ref[0] == '2Mu2J': name = 'HTo2XTo2Mu2J_' latexFS = '2#mu2j' if TRIGGER:
import re import ROOT as R import DisplacedDimuons.Analysis.Plotter as Plotter import DisplacedDimuons.Analysis.RootTools as RT import DisplacedDimuons.Analysis.Selections as Selections from DisplacedDimuons.Common.Utilities import SPStr, SPLumiStr import DisplacedDimuons.Analysis.HistogramGetter as HistogramGetter TRIGGER = False # get histograms HISTS = HistogramGetter.getHistograms('../analyzers/roots/Main/TailCumulativePlots.root') f = R.TFile.Open('../analyzers/roots/Main/TailCumulativePlots.root') # make per sample plots def makePerSamplePlots(): for ref in HISTS: for key in HISTS[ref]: if type(ref) == tuple: if ref[0] == '4Mu': name = 'HTo2XTo4Mu_' elif ref[0] == '2Mu2J' : name = 'HTo2XTo2Mu2J_' name += SPStr(ref[1]) if TRIGGER: name = 'Trig-'+name lumi = SPLumiStr(ref[0], *ref[1]) legName = HistogramGetter.PLOTCONFIG['HTo2XTo'+ref[0]]['LATEX'] else: name = ref lumi = ref legName = HistogramGetter.PLOTCONFIG[ref]['LATEX']
import re import ROOT as R import DisplacedDimuons.Analysis.Plotter as Plotter import DisplacedDimuons.Analysis.RootTools as RT from DisplacedDimuons.Common.Constants import SIGNALPOINTS from DisplacedDimuons.Common.Utilities import SPStr, SPLumiStr import DisplacedDimuons.Analysis.HistogramGetter as HistogramGetter import DisplacedDimuons.Analysis.PlotterParser as PlotterParser ARGS = PlotterParser.PARSER.parse_args() TRIGGER = ARGS.TRIGGER # get histograms HISTS = HistogramGetter.getHistograms( '../analyzers/roots/Main/SignalRecoEffPlots.root') f = R.TFile.Open('../analyzers/roots/Main/SignalRecoEffPlots.root') # make overlaid plots that combine all signal points def makeEffPlots(quantity, fs, SP=None): HKeys = { 'DSA_Eff': 'DSA_{}Eff', 'RSA_Eff': 'RSA_{}Eff', 'REF_Eff': 'REF_{}Eff', 'REF_Den': 'REF_{}Den', 'Den': '{}Den', # 'Extra' : '{}Extra' , 'DSA_ChargeEff': 'DSA_{}ChargeEff', 'RSA_ChargeEff': 'RSA_{}ChargeEff', 'REF_ChargeEff': 'REF_{}ChargeEff', 'DSA_ChargeDen': 'DSA_{}ChargeDen',
def makeSystematicsPlots(RESOLUTIONVARIABLE, data_filepath, MC_filepath, d0intervals, strategy="max"): HISTS_data = HistogramGetter.getHistograms(data_filepath) HISTS_MC = HistogramGetter.getHistograms(MC_filepath) # make sure that all given d0 interval limits are actually floats d0intervals = [(float(l), float(u)) for l, u in d0intervals] data_hists, data_d0hists = importHistogram( HISTS_data, RESOLUTIONVARIABLE, includes=["DSA_lowerLeg", RESOLUTIONVARIABLE], excludes=["EffNum", "EffDen"], ) MC_hists, MC_d0hists = importHistogram( HISTS_MC, RESOLUTIONVARIABLE, includes=["DSA_lowerLeg", RESOLUTIONVARIABLE], excludes=["EffNum", "EffDen"], ) # define a set of d0 bins for the plots d0intervals = [(i, i + 5.) for i in np.arange(0., 30., 5.)] d0intervals += [(i, i + 10.) for i in np.arange(30., 100., 10.)] def varyRebinningParameter(number_of_rebins_range=range(11)): plot_data = {} for hists, histtypes in ( (data_hists, "CosmicsData"), (MC_hists, "SignalMC"), ): plot_data[histtypes] = [] for h in hists: # x coordinates are defined by the varying rebin parameter for x_val in number_of_rebins_range: h_vary = h.Clone() h_autoRebin = h.Clone() auto_rebin_parameter = autoRebin(h_autoRebin) # y coordinates are defined by the d0 bins d0min, d0max = extractD0Values(h_vary.GetName()) if (d0min, d0max) not in d0intervals: continue y_val = d0min if x_val > 0: h_vary.Rebin(2 * x_val) # z coordinates are defined by the peak position value z_val = h_vary.GetXaxis().GetBinCenter( h_vary.GetMaximumBin()) else: # z coordinates are defined by the peak position value z_val = getPeakPosition(h_vary, strategy=strategy)[0] # z_val = h_vary.GetXaxis().GetBinCenter(h_vary.GetMaximumBin()) plot_data[histtypes].append( (x_val, y_val, z_val, auto_rebin_parameter)) return plot_data def varyRebinningErrorFraction(fraction_range=np.arange(0, 0.3, 0.01)): plot_data = {} for hists, histtypes in ( (data_hists, "CosmicsData"), (MC_hists, "SignalMC"), ): plot_data[histtypes] = [] for h in hists: # x coordinates are defined by the varying fraction parameter for x_val in fraction_range: h_vary = h.Clone() # y coordinates are defined by the d0 bins d0min, d0max = extractD0Values(h_vary.GetName()) if (d0min, d0max) not in d0intervals: continue y_val = d0min # z coordinates are defined by the peak position value autoRebin(h_vary, error_fraction=x_val) z_val = getPeakPosition(h_vary, strategy=strategy)[0] # z_val = h_vary.GetXaxis().GetBinCenter(h_vary.GetMaximumBin()) plot_data[histtypes].append((x_val, y_val, z_val, None)) return plot_data def varyRebinningNeighbors(nNeighbors_range=range(1, 11)): plot_data = {} for hists, histtypes in ( (data_hists, "CosmicsData"), (MC_hists, "SignalMC"), ): plot_data[histtypes] = [] for h in hists: # x coordinates are defined by the varying nNeighbors parameter for x_val in nNeighbors_range: h_vary = h.Clone() # y coordinates are defined by the d0 bins d0min, d0max = extractD0Values(h_vary.GetName()) if (d0min, d0max) not in d0intervals: continue y_val = d0min # z coordinates are defined by the peak position value autoRebin(h_vary, neighboring_bins=x_val) z_val = getPeakPosition(h_vary, strategy=strategy)[0] # z_val = h_vary.GetXaxis().GetBinCenter(h_vary.GetMaximumBin()) plot_data[histtypes].append((x_val, y_val, z_val, None)) return plot_data def make2DPlot( RESOLUTIONVARIABLE, data, name="", title="", lumi="", xlabel="", ylabel="", zlabel="", nbinsx=10, xrange_min=0, xrange_max=10, nbinsy=10, yrange_min=0, yrange_max=100, vline=None, ): hist2D = R.TH2F(name, title, nbinsx, xrange_min, xrange_max, nbinsy, yrange_min, yrange_max) hist2D.GetXaxis().SetTitle(xlabel) hist2D.GetYaxis().SetTitle(ylabel) hist2D.GetZaxis().SetTitle(zlabel) # initialize histogram bins for bx in range(1, hist2D.GetNbinsX() + 1): for by in range(1, hist2D.GetNbinsY() + 1): # initialize with value below the z axis minimum in order to # make empty bins appear transparent (requires z axis range to be set # explicitly) hist2D.SetBinContent(hist2D.GetBin(bx, by), -999) for d in data: hist2D.SetBinContent(hist2D.FindBin((d[0]), (d[1])), d[2]) # fill in the blanks for bx in range(1, hist2D.GetNbinsX() + 1): for by in range(1, hist2D.GetNbinsY() + 1): if hist2D.GetBinContent(hist2D.GetBin(bx, by)) == -999: hist2D.SetBinContent(hist2D.GetBin(bx, by), hist2D.GetBinContent(bx, by - 1)) canvas = Plotter.Canvas(lumi=lumi) canvas.addMainPlot(Plotter.Plot(hist2D, "", "colz", "colz")) pave = [] for d in data: if d[3] is None: continue marker_bin_xcoord = hist2D.GetXaxis().GetBinCenter( hist2D.GetXaxis().FindBin(d[3])) marker_bin_ycoord = hist2D.GetYaxis().GetBinCenter( hist2D.GetYaxis().FindBin(d[1])) if marker_bin_ycoord <= 30: pave.append( R.TPaveText(marker_bin_xcoord - 0.5, marker_bin_ycoord - 2.5, marker_bin_xcoord + 0.5, marker_bin_ycoord + 2.5)) else: pave.append( R.TPaveText(marker_bin_xcoord - 0.5, marker_bin_ycoord - 2.5, marker_bin_xcoord + 0.5, marker_bin_ycoord + 7.5)) pave[-1].SetTextAlign(13) pave[-1].SetTextFont(42) pave[-1].SetMargin(0) pave[-1].SetFillStyle(0) pave[-1].SetFillColor(0) pave[-1].SetLineStyle(0) pave[-1].SetLineColor(0) pave[-1].SetBorderSize(1) pave[-1].AddText(0.5, 0.5, "") pave[-1].Draw() if vline: l = R.TLine(vline, yrange_min, vline, yrange_max) l.SetLineColor(R.kWhite) l.SetLineWidth(1) l.Draw() hist2D.GetZaxis().SetRangeUser(-1.0, 0.2) canvas.mainPad.SetRightMargin(0.16) canvas.finishCanvas() canvas.save("pdfs/test_{}_{}_{}_{}".format( RESOLUTIONVARIABLE, name, lumi.replace(" ", ""), "CosmicSeed" if IS_COSMIC_SEED else "ppSeed"), extList=[".pdf", ".root"]) canvas.deleteCanvas() for datatype, lumi in ( ("CosmicsData", "2016 Cosmics data"), ("SignalMC", "2016 MC signal samples"), ): varyRebinningParameter_data = varyRebinningParameter() make2DPlot( RESOLUTIONVARIABLE, varyRebinningParameter_data[datatype], name="varyRebinningParameter", lumi=lumi, xlabel="number of rebinning steps", ylabel="d0 [cm]", zlabel="position of maximum bin" if "L1pTres" in RESOLUTIONVARIABLE else "fitted resolution mean", nbinsx=10, xrange_min=0, xrange_max=10, nbinsy=20, yrange_min=0, yrange_max=100, ) varyRebinningErrorFraction_data = varyRebinningErrorFraction() make2DPlot( RESOLUTIONVARIABLE, varyRebinningErrorFraction_data[datatype], name="varyRebinningErrorFraction", lumi=lumi, xlabel="bin error fraction (rebinning)", ylabel="d0 [cm]", zlabel="position of maximum bin" if "L1pTres" in RESOLUTIONVARIABLE else "fitted resolution mean", nbinsx=30, xrange_min=0, xrange_max=0.3, nbinsy=20, yrange_min=0, yrange_max=100, vline=0.05, ) varyRebinningNeighbors_data = varyRebinningNeighbors() make2DPlot( RESOLUTIONVARIABLE, varyRebinningNeighbors_data[datatype], name="varyRebinningNeighbors", lumi=lumi, xlabel="number of neighbors (rebinning)", ylabel="d0 [cm]", zlabel="position of maximum bin" if "L1pTres" in RESOLUTIONVARIABLE else "fitted resolution mean", nbinsx=9, xrange_min=1, xrange_max=10, nbinsy=20, yrange_min=0, yrange_max=100, vline=6, )
def makeResolutionVsD0Plots( RESOLUTIONVARIABLE, data_filepath, MC_filepath, d0intervals, strategy="max", ): HISTS_data = HistogramGetter.getHistograms(data_filepath) HISTS_MC = HistogramGetter.getHistograms(MC_filepath) # make sure that all given d0 interval limits are actually floats d0intervals = [(float(l), float(u)) for l, u in d0intervals] h_ylabel_value, h_ylabel_width, h_ylabel_fraction_in_tail, h_ylabel_quality, h_xlabel, canvas_text = getLabels( RESOLUTIONVARIABLE) data_hists, data_d0hists = importHistogram( HISTS_data, RESOLUTIONVARIABLE, includes=["DSA_lowerLeg", RESOLUTIONVARIABLE], excludes=["EffNum", "EffDen"], ) MC_hists, MC_d0hists = importHistogram( HISTS_MC, RESOLUTIONVARIABLE, includes=["DSA_lowerLeg", RESOLUTIONVARIABLE], excludes=["EffNum", "EffDen"], ) resVsD0_data = generateGraphData(data_hists, data_d0hists, d0intervals=d0intervals, strategy=STRATEGY) resVsD0_MC = generateGraphData(MC_hists, MC_d0hists, d0intervals=d0intervals, strategy=STRATEGY) canvas = Plotter.Canvas(lumi="2016 MC vs. Cosmics data") # data distributions and specifications graph_data = generateGraph(resVsD0_data, distribution="res_val") canvas.addMainPlot(Plotter.Plot(graph_data, legend_name_data, "elp", "pe")) graph_data.SetLineColor(R.kBlue if IS_COSMIC_SEED else R.kRed) graph_data.SetMarkerColor(R.kBlue if IS_COSMIC_SEED else R.kRed) # data width distribution and specifications graph_data_width = generateGraph(resVsD0_data, distribution="res_width", error_axes="") if STRATEGY == "max": canvas.addMainPlot( Plotter.Plot(graph_data_width, legend_name_data + " std. dev.", "elp", "pe")) elif STRATEGY == "gaussfit": canvas.addMainPlot( Plotter.Plot(graph_data_width, legend_name_data + " FWHM", "elp", "pe")) graph_data_width.SetLineColor(R.kBlue if IS_COSMIC_SEED else R.kRed) graph_data_width.SetMarkerColor(R.kBlue if IS_COSMIC_SEED else R.kRed) graph_data_width.SetMarkerStyle(R.kMultiply) # MC distribution and specifications graph_MC = generateGraph(resVsD0_MC, distribution="res_val") canvas.addMainPlot(Plotter.Plot(graph_MC, legend_name_MC, "elp", "pe")) graph_MC.SetLineColor(R.kCyan + 1 if IS_COSMIC_SEED else R.kOrange - 3) graph_MC.SetMarkerColor(R.kCyan + 1 if IS_COSMIC_SEED else R.kOrange - 3) # MC width distributions and specifications graph_MC_width = generateGraph(resVsD0_MC, distribution="res_width", error_axes="") canvas.addMainPlot( Plotter.Plot(graph_MC_width, legend_name_MC + " std. dev.", "elp", "pe")) # canvas.addMainPlot(Plotter.Plot(graph_MC_width, legend_name_MC + " FWHM", "elp", "pe")) graph_MC_width.SetLineColor(R.kCyan + 1 if IS_COSMIC_SEED else R.kOrange - 3) graph_MC_width.SetMarkerColor(R.kCyan + 1 if IS_COSMIC_SEED else R.kOrange - 3) graph_MC_width.SetMarkerStyle(R.kMultiply) # add horizontal line at zero zero_line_horizontal = R.TLine(resVsD0_data["d0_min"][0], 0.0, resVsD0_data["d0_max"][-1], 0.0) R.SetOwnership(zero_line_horizontal, 0) zero_line_horizontal.SetLineColor(R.kGray) zero_line_horizontal.SetLineStyle(2) zero_line_horizontal.Draw() # set axis titles canvas.firstPlot.GetXaxis().SetTitle(h_xlabel) canvas.firstPlot.GetYaxis().SetTitle("Resolution peak parameters") # set axis ranges if "L2pTres" in RESOLUTIONVARIABLE: if IS_COSMIC_SEED: canvas.firstPlot.GetYaxis().SetRangeUser(-0.1, 0.3) else: canvas.firstPlot.GetYaxis().SetRangeUser(-0.6, 1.5) elif "L1pTres" in RESOLUTIONVARIABLE: canvas.firstPlot.GetYaxis().SetRangeUser(-1.1, 1.5) # create legend canvas.makeLegend(lWidth=0.37, pos="tr", fontscale=0.85) canvas.legend.resizeHeight() if canvas_text: pavetext = R.TPaveText(0.18, 0.78, 0.5, 0.9, "NDCNB") pavetext.SetTextAlign(13) pavetext.SetTextFont(42) pavetext.SetMargin(0) pavetext.SetFillStyle(0) pavetext.SetFillColor(0) pavetext.SetLineStyle(0) pavetext.SetLineColor(0) pavetext.SetBorderSize(0) pavetext.AddText( 0.0, 0.0, canvas_text + ", {} seed".format("cosmic" if IS_COSMIC_SEED else "pp"), ) pavetext.Draw() canvas.finishCanvas() canvas.save( "pdfs/" + FILENAME_TEMPLATE.format( RESOLUTIONVARIABLE=RESOLUTIONVARIABLE, SEEDING="CosmicSeed" if IS_COSMIC_SEED else "ppSeed"), extList=[".pdf", ".root"], ) canvas.deleteCanvas()