5 Plot comparisons of Zee/Zmumu and Z/ATLAS over entire data-periods.
6 This can be done as a function of time or pileup
11 import python_tools
as pt
13 from array
import array
17 parser = argparse.ArgumentParser()
18 parser.add_argument(
'--year', type=str, help=
'15,16,17,18,22,23,24 or run3 for full Run-3')
19 parser.add_argument(
'--channel', type=str, help=
'Zee or Zmumu')
20 parser.add_argument(
'--comp', action=
'store_true', help=
'Compare Zee and Zmumu?')
21 parser.add_argument(
'--absolute', action=
'store_true', help=
'Compare absolute luminosity')
22 parser.add_argument(
'--indir', type=str, help=
'Input directory for CSV files')
23 parser.add_argument(
'--outdir', type=str, help=
'Output directory for plots')
24 parser.add_argument(
'--outcsv', action=
'store_true', help=
'Create short CSV with plot content')
26 args = parser.parse_args()
28 channel = args.channel
29 absolute = args.absolute
37 if args.absolute: ymin, ymax = 0.91, 1.09
38 else: ymin, ymax = 0.93, 1.07
41 years = [
"22",
"23",
"24"]
44 xtitle =
'Month / Year'
45 date_tag =
"Run 3, #sqrt{s} = 13.6 TeV"
52 xtitle =
'Date in 20' + year
53 date_tag =
"Data 20" + year +
", #sqrt{s} = 13.6 TeV"
65 print(
"Lumi Channel Comparison vs Time for years: ", years)
70 grl = pt.get_grl(year)
72 for channel
in [
"Zee",
"Zmumu"]:
75 livetime, zlumi, zerr, olumi, timestamp, dfz_small = pt.get_dfz(args.indir, year, run, channel)
77 if livetime < pt.runlivetimecut:
78 if livetime >= 0.:
print(f
"Skip Run {run} because of live time {livetime/60:.1f} min")
81 dict_zlumi[channel, run] = (zlumi, zerr, timestamp)
83 vec_times =
array(
'd')
84 vec_ratio =
array(
'd')
85 vec_ratio_err =
array(
'd')
86 keys = [key[1]
for key
in dict_zlumi
if "Zee" in key]
91 ratio = dict_zlumi[
"Zee", key][0]/dict_zlumi[
"Zmumu", key][0]
92 error = ratio * math.sqrt(
pow(dict_zlumi[
"Zee", key][1]/dict_zlumi[
"Zee", key][0], 2) +
pow(dict_zlumi[
"Zmumu", key][1]/dict_zlumi[
"Zmumu", key][0], 2) )
93 date = dict_zlumi[
"Zee", key][2]
95 if ratio < ymin
or ratio > ymax:
96 print(
"WARNING: Run", key,
"has Zee/Zmumu ratio", ratio,
", outside of y-axis range")
98 vec_times.append(date)
99 vec_ratio.append(ratio)
100 vec_ratio_err.append(error)
102 print(
"Cannot do ratio for", key)
104 tg = R.TGraphErrors(len(vec_times), vec_times, vec_ratio, R.nullptr, vec_ratio_err)
105 leg = R.TLegend(0.645, 0.72, 0.805, 0.91)
109 if out_tag ==
"run3":
110 c1 = R.TCanvas(
"c1",
"c1", 2000, 1000)
115 tg.GetYaxis().SetTitle(
'L_{Z #rightarrow ee} / L_{Z #rightarrow #mu#mu}')
117 tg.GetFunction(
'pol0').SetLineColor(R.kRed)
119 mean = tg.GetFunction(
'pol0').GetParameter(0)
122 stdev = np.percentile(abs(vec_ratio - np.median(vec_ratio)), 68)
123 line1 = pt.make_bands(vec_times, stdev, mean)
125 tg.GetFunction(
'pol0').Draw(
"same l")
128 print(
"Pol0 fit mean +- 68% percentile = ",
round(mean,3),
" +- ",
round(stdev, 3))
131 leg.SetTextSize(0.05)
132 leg.AddEntry(tg,
"L_{Z #rightarrow ee}/L_{Z #rightarrow #mu#mu}",
"ep")
133 leg.AddEntry(tg.GetFunction(
"pol0"),
"Mean = " +
str(
round(mean, 3)),
"l")
134 leg.AddEntry(line1,
"68% band",
"f")
137 pt.drawAtlasLabel(xval, 0.88,
"Internal")
138 pt.drawText(xval, 0.82, date_tag, size=labelsize)
140 new_trig_line = R.TLine(1683743066.0, 0.95, 1683743066.0, 1.05)
142 new_trig_line.SetLineColor(R.kBlue)
143 new_trig_line.SetLineWidth(1)
144 new_trig_line.SetLineStyle(2)
145 new_trig_line.Draw(
"same")
148 tg.GetYaxis().SetRangeUser(ymin, ymax)
149 tg.GetXaxis().SetTitle(xtitle)
150 tg.GetXaxis().SetTimeDisplay(2)
151 tg.GetXaxis().SetNdivisions(9,R.kFALSE)
152 tg.GetXaxis().SetTimeFormat(time_format)
153 tg.GetXaxis().SetTimeOffset(0,
"gmt")
155 if years == [
"22",
"23",
"24"]:
156 plot_title =
"Ratio of Electron and Muon channel Z-counting Luminosities across Run 3"
158 plot_title =
"Ratio of Electron and Muon channel Z-counting Luminosities across 20" + years[0]
160 tg.SetTitle(plot_title)
162 c1.SaveAs(outdir +
"ZeeZmm_ratio_vs_time_"+out_tag+
".pdf")
167 Plot normalised comparison of Z-counting luminosity to ATLAS luminosity.
168 This can be done as a function of time and pileup.
171 zstring = pt.plotlabel[channel]+
" counting"
172 ytitle =
"L_{"+pt.plotlabel[channel]+
"}/L_{ATLAS}"
174 leg_entry =
"L_{"+pt.plotlabel[channel]+
"}"
176 leg_entry =
"L_{"+pt.plotlabel[channel]+
"}^{"+norm_type+
"-normalised}/L_{ATLAS}"
178 print(
"Channel", channel,
"comparison to ATLAS vs time for years: ", years)
189 grl = pt.get_grl(year)
192 livetime, zlumi, zerr, olumi, timestamp, dfz_small = pt.get_dfz(args.indir, year, run, channel)
195 if livetime < pt.runlivetimecut:
196 if livetime >= 0.:
print(f
"Skip Run {run} because of live time {livetime/60:.1f} min")
199 prelratio = zlumi/olumi
200 if prelratio < ymin
or prelratio > ymax:
201 print(
"WARNING: Run", run,
"has", channel,
"/ATLAS ratio", prelratio,
", outside of y-axis range")
204 arr_date.append(timestamp)
205 arr_olumi.append(olumi)
206 arr_zlumi.append(zlumi)
207 arr_zerr.append(zerr)
209 fill = dfz_small[
'FillNum'].
median()
210 fill_num.append(
int(fill))
214 arr_date =
array(
'd', arr_date)
216 arr_olumi = np.array(arr_olumi)
217 arr_zlumi = np.array(arr_zlumi)
218 arr_zerr = np.array(arr_zerr)
219 total_lumi = arr_olumi.sum()/1000000
220 total_lumi_string =
"Official DQ "
221 if year ==
"24": total_lumi_string =
"Preliminary DQ "
222 total_lumi_string +=
str(
round(total_lumi, 1)) +
" fb^{-1}"
230 normalisation = np.sum(arr_zlumi) / np.sum(arr_olumi)
233 arr_zlumi /= normalisation
234 arr_zerr /= normalisation
237 arr_zlumi_ratio = arr_zlumi/arr_olumi
238 arr_zerr_ratio = arr_zerr/arr_olumi
242 tg = R.TGraphErrors(len(arr_date), arr_date,
array(
'd',arr_zlumi_ratio), R.nullptr,
array(
'd',arr_zerr_ratio))
245 if out_tag ==
"run3":
246 c1 = R.TCanvas(
"c1",
"c1", 2000, 1000)
251 tg.GetYaxis().SetRangeUser(ymin, ymax)
253 plot_title =
"Absolute L_{"+ zstring +
"} to ATLAS across " + norm_type
255 plot_title =
"Normalised L_{"+ zstring +
"} to ATLAS across " + norm_type
258 stdev = np.percentile(abs(arr_zlumi_ratio - np.median(arr_zlumi_ratio)), 68)
259 print(
"68% band =", stdev)
261 mean = tg.GetFunction(
'pol0').GetParameter(0)
262 print(
"const of pol0 fit", mean)
263 print(
"median", np.median(arr_zlumi_ratio))
264 print(
"mean", np.mean(arr_zlumi_ratio))
266 line1 = pt.make_bands(arr_date, stdev, np.median(arr_zlumi_ratio))
270 leg = R.TLegend(0.55, 0.20, 0.69, 0.45)
273 leg.SetTextSize(0.05)
274 leg.AddEntry(tg, leg_entry,
"ep")
275 leg.AddEntry(line1,
"68% band",
"f")
278 pt.drawAtlasLabel(xval, yval-0.47,
"Internal")
279 pt.drawText(xval, yval-0.53, date_tag, size=labelsize)
280 pt.drawText(xval, yval-0.59, zstring, size=labelsize)
281 pt.drawText(xval, yval-0.65,
"OflLumi-Run3-005", size=labelsize)
282 pt.drawText(xval, yval-0.04, total_lumi_string, size=labelsize)
284 pt.drawText(xval, 0.88, plot_title, size=labelsize)
286 tg.GetXaxis().SetTitle(xtitle)
287 tg.GetYaxis().SetTitle(ytitle)
288 tg.GetYaxis().SetRangeUser(ymin, ymax)
289 tg.GetXaxis().SetTimeDisplay(2)
290 tg.GetXaxis().SetNdivisions(9,R.kFALSE)
291 tg.GetXaxis().SetTimeFormat(time_format)
292 tg.GetXaxis().SetTimeOffset(0,
"gmt")
297 filename = outdir + channel +
"ATLAS_ratio_vs_time_"+out_tag
299 c1.SaveAs(filename+
"_abs.pdf")
301 c1.SaveAs(filename+
".pdf")
305 csvfile =
open(filename+
"_abs.csv",
'w')
307 csvfile =
open(filename+
".csv",
'w')
308 csvwriter = csv.writer(csvfile, delimiter=
',')
309 csvwriter.writerow([
'FillNum',
'RunNum',
'Time',
'OffLumi',
'ZLumi',
'ZLumiErr',
'OffZlumi',
'OffZlumiErr'])
310 for i
in range(len(run_num)):
311 csvwriter.writerow([fill_num[i], run_num[i], arr_date[i], arr_olumi[i], arr_zlumi[i], arr_zerr[i], arr_zlumi_ratio[i], arr_zerr_ratio[i]])
316 if __name__ ==
"__main__":
318 R.gROOT.SetBatch(R.kTRUE)