ATLAS Offline Software
Loading...
Searching...
No Matches
yearwise_efficiency_vs_mu.py
Go to the documentation of this file.
1#!/usr/bin/env python
2# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3
4"""
5Plot trigger and reconstruction efficiencies over entire data-periods.
6"""
7
8import ROOT as R
9import python_tools as pt
10import ZLumiScripts.tools.zlumi_mc_cf as dq_cf
11from math import sqrt
12from array import array
13import argparse
14
15parser = argparse.ArgumentParser()
16parser.add_argument('--year', type=str, help='A year number (15-25) or run3 or year1_year2_...')
17parser.add_argument('--channel', type=str, help='Zee or Zmumu')
18parser.add_argument('--indir', type=str, help='Input directory for CSV files')
19parser.add_argument('--outdir', type=str, help='Output directory for plots')
20
21args = parser.parse_args()
22year = args.year
23channel = args.channel
24indir = args.indir
25outdir = args.outdir
26
27if year == "run3":
28 years = ["22", "23", "24", "25"]
29 out_tag = "run3"
30 time_format = "%m/%y"
31 ymin, ymax = 0.5, 1.1
32 xtitle = 'Month / Year'
33 date_tag = "Run 3, #sqrt{s} = 13.6 TeV"
34 if channel is not None:
35 xval = 0.30
36 yval = 0.33
37 else:
38 xval = 0.43
39 yval = 0.33
40 set_size = 1
41elif len(year.split("_")) > 1:
42 years = year.split("_")
43 out_tag = "data"+year
44 time_format = "%m/%y"
45 ymin, ymax = 0.5, 1.1
46 xtitle = 'Month / Year'
47 date_tag = "Run 3, #sqrt{s} = 13.6 TeV"
48 if channel is not None:
49 xval = 0.30
50 yval = 0.33
51 else:
52 xval = 0.43
53 yval = 0.33
54 set_size = 1
55else:
56 years = [year]
57 out_tag = "data"+year
58 time_format = "%d/%m"
59 ymin, ymax = 0.5, 1.1
60 xtitle = 'Date in 20' + year
61 date_tag = "Data 20" + year + ", #sqrt{s} = 13.6 TeV"
62 xval = 0.235
63 yval = 0.86
64 set_size = 0
65
66def main():
67 plot_efficiency_comb(channel, years)
68
69def plot_efficiency_comb(channel, years):
70
71 all_graphs = []
72
73 for year in years:
74 dict_comb = {}
75 dict_comb_err = {}
76 dict_mu = {}
77
78 vec_comb = array('d')
79 vec_comb_err = array('d')
80 vec_mu = array('d')
81
82 grl = pt.get_grl(year)
83
84 for run in grl:
85 livetime, zlumi, zerr, olumi, timestamp, dfz_small = pt.get_dfz(args.indir, year, run, channel)
86
87 # Cut out short runs
88 if livetime < pt.runlivetimecut:
89 if livetime >= 0.: print(f"Skip Run {run} because of live time {livetime/60:.1f} min")
90 continue
91
92 dfz_small['CombEff'] = dfz_small[channel + 'EffComb']
93 dfz_small['CombErr'] = dfz_small[channel + 'ErrComb']
94 # safety to avoid divide by zero - maybe can be removed again later
95 dfz_small.loc[dfz_small['CombErr'] == 0., 'CombErr'] = 1.
96
97 # Scale event-level efficiency with FMC
98 campaign = "mc23a"
99 dfz_small['CombEff'] *= dq_cf.correction(dfz_small['OffMu'], channel, campaign, int(run))
100 dfz_small['CombErr'] *= dq_cf.correction(dfz_small['OffMu'], channel, campaign, int(run))
101
102 for index, event in dfz_small.iterrows():
103 pileup = int(event.OffMu)
104
105 weight_comb = 1/pow(event.CombErr, 2)
106 if pileup not in dict_mu:
107 dict_mu[pileup] = pileup
108 dict_comb[pileup] = weight_comb * event.CombEff
109 dict_comb_err[pileup] = weight_comb
110 else:
111 dict_comb[pileup] += weight_comb * event.CombEff
112 dict_comb_err[pileup] += weight_comb
113
114 if not dict_mu:
115 print("File has no filled lumi blocks!")
116 return
117
118 for pileup in dict_mu:
119 comb_weighted_average = dict_comb[pileup]/dict_comb_err[pileup]
120 comb_error = sqrt(1/dict_comb_err[pileup])
121 vec_comb.append(comb_weighted_average)
122 vec_comb_err.append(comb_error)
123
124 vec_mu.append(pileup)
125
126 all_graphs.append((year, R.TGraphErrors(len(vec_comb), vec_mu, vec_comb, R.nullptr, vec_comb_err)))
127
128 # now draw all
129 c1 = R.TCanvas()
130 leg = R.TLegend(0.645, 0.7, 0.805, 0.9)
131 if channel == "Zee":
132 ymin, ymax = 0.52, 0.74
133 elif channel == "Zmumu":
134 ymin, ymax = 0.74, 0.84
135 xmin, xmax = 0, 80
136
137 for igraph in range(len(all_graphs)):
138 comb_graph = all_graphs[igraph][1]
139 comb_graph.SetMarkerSize(1)
140 comb_graph.SetMarkerColor(R.kBlack+igraph)
141 comb_graph.SetMarkerStyle(R.kFullCircle+igraph)
142 if igraph == 0:
143 comb_graph.Draw("ap")
144 comb_graph.GetHistogram().SetYTitle("#varepsilon_{event}^{"+pt.plotlabel[channel]+"}#times F^{MC}")
145 comb_graph.GetHistogram().GetYaxis().SetRangeUser(ymin, ymax)
146 comb_graph.GetHistogram().GetXaxis().SetLimits(xmin, xmax)
147 comb_graph.GetHistogram().SetXTitle("Pileup (#mu)")
148 else:
149 comb_graph.Draw("p same")
150 leg.SetBorderSize(0)
151 leg.SetTextSize(0.07)
152 leg.AddEntry(comb_graph, "Data 20"+all_graphs[igraph][0], "ep")
153 leg.Draw()
154
155 if channel == "Zee":
156 pt.drawAtlasLabel(0.6, ymax-0.46, "Internal")
157 pt.drawText(0.2, ymax-0.46, date_tag)
158 pt.drawText(0.2, ymax-0.52, pt.plotlabel[channel] + " counting")
159 elif channel == "Zmumu":
160 pt.drawAtlasLabel(0.6, ymax-0.56, "Internal")
161 pt.drawText(0.2, ymax-0.62, pt.plotlabel[channel] + " counting")
162
163 c1.SaveAs(outdir + channel + "_eventeff_vs_mu_"+out_tag+".pdf")
164
165if __name__ == "__main__":
166 pt.setAtlasStyle()
167 R.gROOT.SetBatch(R.kTRUE)
168 main()
void print(char *figname, TCanvas *c1)
constexpr int pow(int base, int exp) noexcept
STL class.