ATLAS Offline Software
yearwise_efficiency.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 """
5 Plot trigger and reconstruction efficiencies over entire data-periods.
6 """
7 
8 import numpy as np
9 import ROOT as R
10 import python_tools as pt
11 import ZLumiScripts.tools.zlumi_mc_cf as dq_cf
12 import math
13 from array import array
14 import argparse
15 
16 parser = argparse.ArgumentParser()
17 parser.add_argument('--year', type=str, help='A year number (15-24) or run3 for full Run3')
18 parser.add_argument('--channel', type=str, help='Zee or Zmumu')
19 parser.add_argument('--indir', type=str, help='Input directory for CSV files')
20 parser.add_argument('--outdir', type=str, help='Output directory for plots')
21 
22 args = parser.parse_args()
23 year = args.year
24 channel = args.channel
25 indir = args.indir
26 outdir = args.outdir
27 
28 if year == "run3":
29  years = ["22", "23", "24"]
30  out_tag = "run3"
31  time_format = "%m/%y"
32  xtitle = 'Month / Year'
33  date_tag = "Run 3, #sqrt{s} = 13.6 TeV"
34  labelsize = 44
35 else:
36  years = [year]
37  out_tag = "data"+year
38  time_format = "%d/%m"
39  xtitle = 'Date in 20' + year
40  date_tag = "Data 20" + year + ", #sqrt{s} = 13.6 TeV"
41  labelsize = 22
42 
43 def main():
44  plot_efficiency(channel, years)
45  plot_efficiency_comb(channel, years)
46 
47 def plot_efficiency_comb(channel, years):
48 
49  arr_date = []
50  arr_combeff = []
51  arr_comberr = []
52  run_num = []
53 
54  for year in years:
55  grl = pt.get_grl(year)
56 
57  for run in grl:
58  livetime, zlumi, zerr, olumi, timestamp, dfz_small = pt.get_dfz(args.indir, year, run, channel)
59  # Cut out short runs
60  if livetime < pt.lblivetimecut:
61  if livetime >= 0.: print(f"Skip Run {run} because of live time {livetime/60:.1f} min")
62  continue
63 
64  dfz_small['CombEff'] = dfz_small[channel + 'EffComb']
65  dfz_small['CombErr'] = dfz_small[channel + 'ErrComb']
66  dfz_small['OffMu'] = dfz_small['OffMu']
67 
68  # Scale event-level efficiency with FMC
69  campaign = "mc23a"
70  dfz_small['CombEff'] *= dq_cf.correction(dfz_small['OffMu'], channel, campaign, int(run))
71  dfz_small['CombErr'] *= dq_cf.correction(dfz_small['OffMu'], channel, campaign, int(run))
72 
73  # Calculate average event-level efficiency
74  dfz_small['CombEff'] *= dfz_small['LBLive']
75  comb_eff_avg = dfz_small['CombEff'].sum()/livetime
76 
77  # Calculate average trigger efficiency error
78  dfz_small['CombErr'] *= dfz_small['LBLive']
79  dfz_small['CombErr'] *= dfz_small['CombErr']
80  comb_err_avg = math.sqrt(dfz_small['CombErr'].sum())/livetime
81 
82  arr_date.append(timestamp)
83  arr_combeff.append(comb_eff_avg)
84  arr_comberr.append(comb_err_avg)
85  run_num.append(run)
86 
87  arr_date = array('d', arr_date)
88 
89  arr_combeff = np.array(arr_combeff)
90  arr_comberr = np.array(arr_comberr)
91 
92  if channel == "Zee":
93  ymin, ymax = 0.56, 0.74
94  elif channel == "Zmumu":
95  ymin, ymax = 0.74, 0.80
96 
97  comb_graph = R.TGraphErrors(len(arr_date), arr_date, arr_combeff, R.nullptr,arr_comberr)
98  comb_graph.GetHistogram().SetYTitle("Efficiency")
99  comb_graph.GetHistogram().GetYaxis().SetRangeUser(ymin, ymax)
100  comb_graph.GetXaxis().SetTimeDisplay(2)
101  comb_graph.GetXaxis().SetNdivisions(9,R.kFALSE)
102  comb_graph.GetXaxis().SetTimeFormat(time_format)
103  comb_graph.GetXaxis().SetTimeOffset(0,"gmt")
104  comb_graph.SetMarkerSize(1)
105 
106  if out_tag == "run3":
107  c1 = R.TCanvas("c1", "c1", 2000, 1200)
108  else:
109  c1 = R.TCanvas()
110 
111  comb_graph.Draw("ap")
112 
113  leg = R.TLegend(0.645, 0.4, 0.805, 0.6)
114  if channel == "Zee":
115  pt.drawAtlasLabel(0.2, ymax-0.06, "Internal")
116  elif channel == "Zmumu":
117  pt.drawAtlasLabel(0.2, ymax-0.4, "Internal")
118 
119  pt.drawText(0.2, ymax-0.46, date_tag, size=labelsize)
120  pt.drawText(0.2, ymax-0.52, pt.plotlabel[channel] + " counting", size=labelsize)
121 
122  leg.SetBorderSize(0)
123  leg.SetTextSize(0.07)
124  leg.AddEntry(comb_graph, "#varepsilon_{event}^{"+pt.plotlabel[channel]+"}", "ep")
125 
126  leg.Draw()
127 
128  if channel == "Zee":
129  new_trig_line = R.TLine(1683743066.0, ymin, 1683743066.0, ymax)
130  new_trig_line.SetLineColor(R.kBlue)
131  new_trig_line.SetLineWidth(3)
132  new_trig_line.SetLineStyle(2)
133  new_trig_line.Draw("same")
134  R.gPad.Update()
135 
136  comb_graph.GetHistogram().SetXTitle("Date")
137  c1.SaveAs(outdir + channel + "_eventeff_vs_time_"+out_tag+".pdf")
138 
139 def plot_efficiency(channel, years):
140 
141  print("Efficiency Plots vs Time for years: ", years)
142 
143  arr_date = []
144  arr_trigeff = []
145  arr_trigerr = []
146  arr_recoeff = []
147  arr_recoerr = []
148  run_num = []
149 
150  trigeff_vs_runlength = R.TH2D("trigeff_vs_runlength",\
151  "Trigger efficiency vs. Run Length;Run Length [h]; Trigger Efficiency;N_{run}",\
152  48, 0., 24., 80, .6, 1.0)
153  recoeff_vs_runlength = R.TH2D("recoeff_vs_runlength",\
154  "Reconstruction efficiency vs. Run Length;Run Length [h]; Reconstruction Efficiency;N_{run}",\
155  48, 0., 24., 60, .8, 1.0)
156 
157  for year in years:
158  grl = pt.get_grl(year)
159 
160  for run in grl:
161  livetime, zlumi, zerr, olumi, timestamp, dfz_small = pt.get_dfz(args.indir, year, run, channel)
162  # Cut out short runs
163  if livetime < pt.lblivetimecut:
164  if livetime >= 0.: print(f"Skip Run {run} because of live time {livetime/60:.1f} min")
165  continue
166 
167  dfz_small['TrigEff'] = dfz_small[channel + 'EffTrig']
168  dfz_small['TrigErr'] = dfz_small[channel + 'ErrTrig']
169  dfz_small['RecoEff'] = dfz_small[channel + 'EffReco']
170  dfz_small['RecoErr'] = dfz_small[channel + 'ErrReco']
171 
172  # Calculate average trigger efficiency
173  dfz_small['TrigEff'] *= dfz_small['LBLive']
174  trig_eff_avg = dfz_small['TrigEff'].sum()/livetime
175 
176  # Calculate average reconstruction efficiency
177  dfz_small['RecoEff'] *= dfz_small['LBLive']
178  reco_eff_avg = dfz_small['RecoEff'].sum()/livetime
179 
180  # Calculate average trigger efficiency error
181  dfz_small['TrigErr'] *= dfz_small['LBLive']
182  dfz_small['TrigErr'] *= dfz_small['TrigErr']
183  trig_err_avg = math.sqrt(dfz_small['TrigErr'].sum())/livetime
184 
185  # Calculate average reconstruction efficiency error
186  dfz_small['RecoErr'] *= dfz_small['LBLive']
187  dfz_small['RecoErr'] *= dfz_small['RecoErr']
188  reco_err_avg = math.sqrt(dfz_small['RecoErr'].sum())/livetime
189 
190  arr_date.append(timestamp)
191  arr_trigeff.append(trig_eff_avg)
192  arr_trigerr.append(trig_err_avg)
193  arr_recoeff.append(reco_eff_avg)
194  arr_recoerr.append(reco_err_avg)
195  run_num.append(run)
196 
197  trigeff_vs_runlength.Fill(min(livetime/3600, 23.99), trig_eff_avg)
198  recoeff_vs_runlength.Fill(min(livetime/3600, 23.99), reco_eff_avg)
199 
200  arr_date = array('d', arr_date)
201 
202  arr_trigeff = np.array(arr_trigeff)
203  arr_trigerr = np.array(arr_trigerr)
204  arr_recoeff = np.array(arr_recoeff)
205  arr_recoerr = np.array(arr_recoerr)
206 
207  if channel == "Zee":
208  lep = "e"
209  elif channel == "Zmumu":
210  lep = "#mu"
211  ymin, ymax = 0.64, 0.96
212 
213  trig_graph = R.TGraphErrors(len(arr_date), arr_date, arr_trigeff, R.nullptr,arr_trigerr)
214  trig_graph.GetHistogram().SetYTitle("Efficiency")
215  trig_graph.GetHistogram().GetYaxis().SetRangeUser(ymin, ymax)
216  trig_graph.GetXaxis().SetTimeDisplay(2)
217  trig_graph.GetXaxis().SetNdivisions(9,R.kFALSE)
218  trig_graph.GetXaxis().SetTimeFormat(time_format)
219  trig_graph.GetXaxis().SetTimeOffset(0,"gmt")
220  trig_graph.SetMarkerSize(1)
221 
222  reco_graph = R.TGraphErrors(len(arr_date), arr_date, arr_recoeff, R.nullptr,arr_recoerr)
223  reco_graph.GetHistogram().GetYaxis().SetRangeUser(ymin, ymax)
224  reco_graph.GetXaxis().SetTimeDisplay(2)
225  reco_graph.GetXaxis().SetNdivisions(9,R.kFALSE)
226  reco_graph.GetXaxis().SetTimeFormat(time_format)
227  reco_graph.GetXaxis().SetTimeOffset(0,"gmt")
228  reco_graph.SetMarkerSize(1)
229  reco_graph.SetMarkerStyle(21)
230  reco_graph.SetMarkerColor(R.kRed)
231  reco_graph.SetLineColor(R.kRed)
232 
233  if out_tag == "run3":
234  c1 = R.TCanvas("c1", "c1", 2000, 1200)
235  else:
236  c1 = R.TCanvas()
237 
238  trig_graph.Draw("ap")
239  reco_graph.Draw("p")
240 
241  if channel == "Zee":
242  leg = R.TLegend(0.645, 0.2, 0.805, 0.4)
243  pt.drawAtlasLabel(0.2, ymax-0.64, "Internal")
244  pt.drawText(0.2, ymax-0.70, date_tag, size=labelsize)
245  pt.drawText(0.2, ymax-0.76, pt.plotlabel[channel] + " counting", size=labelsize)
246  elif channel == "Zmumu":
247  leg = R.TLegend(0.645, 0.45, 0.805, 0.65)
248  pt.drawAtlasLabel(0.2, ymax-0.36, "Internal")
249  pt.drawText(0.2, ymax-0.42, date_tag, size=labelsize)
250  pt.drawText(0.2, ymax-0.48, pt.plotlabel[channel] + " counting", size=labelsize)
251 
252  leg.SetBorderSize(0)
253  leg.SetTextSize(0.07)
254  leg.AddEntry(reco_graph, "#varepsilon_{reco}^{single-"+lep+"}", "ep")
255  leg.AddEntry(trig_graph, "#varepsilon_{trig}^{single-"+lep+"}", "ep")
256 
257  leg.Draw()
258 
259  if channel == "Zee":
260  new_trig_line = R.TLine(1683743066.0, ymin, 1683743066.0, ymax)
261  new_trig_line.SetLineColor(R.kBlue)
262  new_trig_line.SetLineWidth(3)
263  new_trig_line.SetLineStyle(2)
264  new_trig_line.Draw("same")
265  R.gPad.Update()
266 
267  trig_graph.GetHistogram().SetXTitle("Date")
268  c1.SaveAs(outdir + channel + "_eff_vs_time_"+out_tag+".pdf")
269 
270  c1.SetRightMargin(0.15)
271  trigeff_vs_runlength.Draw("colz")
272  if channel == "Zee":
273  ymin, ymax = 0.73, 0.95
274  elif channel == "Zmumu":
275  ymin, ymax = 0.6, 0.85
276  trigeff_vs_runlength.GetYaxis().SetRangeUser(ymin, ymax)
277  pt.drawAtlasLabel(0.2, 0.89, "Internal")
278  pt.drawText(0.2, 0.83, date_tag, size=labelsize)
279  pt.drawText(0.2, 0.77, pt.plotlabel[channel] + " counting", size=labelsize)
280  c1.SaveAs(outdir + channel + "_trigeff_vs_runlength_"+out_tag+".pdf")
281 
282  recoeff_vs_runlength.Draw("colz")
283  if channel == "Zee":
284  ymin, ymax = 0.8, 0.95
285  elif channel == "Zmumu":
286  ymin, ymax = 0.92, 1.0
287  recoeff_vs_runlength.GetYaxis().SetRangeUser(ymin, ymax)
288  pt.drawAtlasLabel(0.2, 0.89, "Internal")
289  pt.drawText(0.2, 0.83, date_tag, size=labelsize)
290  pt.drawText(0.2, 0.77, pt.plotlabel[channel] + " counting", size=labelsize)
291  c1.SaveAs(outdir + channel + "_recoeff_vs_runlength_"+out_tag+".pdf")
292 
293 
294 if __name__ == "__main__":
295  pt.setAtlasStyle()
296  R.gROOT.SetBatch(R.kTRUE)
297  main()
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
plotting.yearwise_efficiency.plot_efficiency_comb
def plot_efficiency_comb(channel, years)
Definition: yearwise_efficiency.py:47
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
plotting.yearwise_efficiency.plot_efficiency
def plot_efficiency(channel, years)
Definition: yearwise_efficiency.py:139
plotting.yearwise_efficiency.main
def main()
Definition: yearwise_efficiency.py:43
min
#define min(a, b)
Definition: cfImp.cxx:40
array
dbg::print
void print(std::FILE *stream, std::format_string< Args... > fmt, Args &&... args)
Definition: SGImplSvc.cxx:70