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,25 or run3 or year1_year2_...')
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",
"25"]
44 xtitle =
'Month / Year'
45 date_tag =
"Run 3,#kern[-0.5]{ }#sqrt{s} = 13.6 TeV"
49 elif len(year.split(
"_")) > 1:
50 years = year.split(
"_")
53 xtitle =
'Month / Year'
54 date_tag =
"Run 3,#kern[-0.5]{ }#sqrt{s} = 13.6 TeV"
62 xtitle =
'Date in 20' + year
63 date_tag =
"Data 20" + year +
",#kern[-0.5]{ }#sqrt{s} = 13.6 TeV"
76 print(
"Lumi Channel Comparison vs Time for years: ", years)
81 grl = pt.get_grl(year)
83 for channel
in [
"Zee",
"Zmumu"]:
86 livetime, zlumi, zerr, olumi, timestamp, dfz_small = pt.get_dfz(args.indir, year, run, channel)
88 if livetime < pt.runlivetimecut:
89 if livetime >= 0.:
print(f
"Skip Run {run} because of live time {livetime/60:.1f} min")
92 dict_zlumi[channel, run] = (zlumi, zerr, timestamp)
94 vec_times =
array(
'd')
95 vec_ratio =
array(
'd')
96 vec_ratio_err =
array(
'd')
97 keys = [key[1]
for key
in dict_zlumi
if "Zee" in key]
102 ratio = dict_zlumi[
"Zee", key][0]/dict_zlumi[
"Zmumu", key][0]
103 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) )
104 date = dict_zlumi[
"Zee", key][2]
106 if ratio < ymin
or ratio > ymax:
107 print(
"WARNING: Run", key,
"has Zee/Zmumu ratio %.2f +- %.2f, outside of y-axis range" % (ratio, error))
109 vec_times.append(date)
110 vec_ratio.append(ratio)
111 vec_ratio_err.append(error)
113 print(
"Cannot do ratio for", key)
115 tg = R.TGraphErrors(len(vec_times), vec_times, vec_ratio, R.nullptr, vec_ratio_err)
116 leg = R.TLegend(0.645, 0.72, 0.805, 0.91)
121 c1 = R.TCanvas(
"c1",
"c1", 2000, 1000)
126 tg.GetYaxis().SetTitle(pt.Leemumuratiolabel)
128 tg.GetFunction(
'pol0').SetLineColor(R.kRed)
130 mean = tg.GetFunction(
'pol0').GetParameter(0)
133 stdev = np.percentile(abs(vec_ratio - np.median(vec_ratio)), 68)
134 line1 = pt.make_bands(vec_times, stdev, mean)
136 tg.GetFunction(
'pol0').Draw(
"same l")
139 print(
"Pol0 fit mean +- 68% percentile = ",
round(mean,3),
" +- ",
round(stdev, 3))
142 leg.SetTextSize(0.05)
143 leg.AddEntry(tg, pt.Leemumuratiolabel,
"ep")
144 leg.AddEntry(tg.GetFunction(
"pol0"),
"Mean = %.3f" % mean,
"l")
145 leg.AddEntry(line1,
"68%% band (#pm %.3f)" % stdev,
"f")
148 pt.drawAtlasLabel(xval, 0.88,
"Internal")
149 pt.drawText(xval, 0.82, date_tag, size=labelsize)
153 tg.GetYaxis().SetRangeUser(ymin, ymax)
154 tg.GetXaxis().SetTitle(xtitle)
155 tg.GetXaxis().SetTimeDisplay(2)
156 tg.GetXaxis().SetNdivisions(9,R.kFALSE)
157 tg.GetXaxis().SetTimeFormat(time_format)
158 tg.GetXaxis().SetTimeOffset(0,
"gmt")
160 if years == [
"22",
"23",
"24",
"25"]:
161 plot_title =
"Ratio of Electron and Muon channel Z-counting Luminosities across Run 3"
163 plot_title =
"Ratio of Electron and Muon channel Z-counting Luminosities across 20" + years[0]
165 tg.SetTitle(plot_title)
167 c1.SaveAs(outdir +
"ZeeZmm_ratio_vs_time_"+out_tag+
".pdf")
172 Plot normalised comparison of Z-counting luminosity to ATLAS luminosity.
173 This can be done as a function of time and pileup.
176 zstring = pt.plotlabel[channel]+
" counting"
177 ytitle =
"L_{"+pt.plotlabel[channel]+
"}/L_{ATLAS}"
179 leg_entry =
"L_{"+pt.plotlabel[channel]+
"}"
181 leg_entry =
"L_{"+pt.plotlabel[channel]+
"}^{"+norm_type+
"-normalised}/L_{ATLAS}"
183 print(
"Channel", channel,
"comparison to ATLAS vs time for years: ", years)
194 grl = pt.get_grl(year)
197 livetime, zlumi, zerr, olumi, timestamp, dfz_small = pt.get_dfz(args.indir, year, run, channel)
200 if livetime < pt.runlivetimecut:
201 if livetime >= 0.:
print(f
"Skip Run {run} because of live time {livetime/60:.1f} min")
204 prelratio = zlumi/olumi
205 if prelratio < ymin
or prelratio > ymax:
206 print(
"WARNING: Run", run,
"has", channel,
"/ATLAS ratio %.2f +- %.2f, outside of y-axis range" % (prelratio, zerr/olumi) )
209 arr_date.append(timestamp)
210 arr_olumi.append(olumi)
211 arr_zlumi.append(zlumi)
212 arr_zerr.append(zerr)
214 fill = dfz_small[
'FillNum'].
median()
215 fill_num.append(
int(fill))
219 arr_date =
array(
'd', arr_date)
221 arr_olumi = np.array(arr_olumi)
222 arr_zlumi = np.array(arr_zlumi)
223 arr_zerr = np.array(arr_zerr)
224 total_lumi = arr_olumi.sum()/1000000
225 total_lumi_string =
"Official DQ "
226 if year ==
"25": total_lumi_string =
"Preliminary DQ "
227 total_lumi_string +=
str(
round(total_lumi, 1)) +
" fb^{-1}"
235 normalisation = np.sum(arr_zlumi) / np.sum(arr_olumi)
238 arr_zlumi /= normalisation
239 arr_zerr /= normalisation
242 arr_zlumi_ratio = arr_zlumi/arr_olumi
243 arr_zerr_ratio = arr_zerr/arr_olumi
247 tg = R.TGraphErrors(len(arr_date), arr_date,
array(
'd',arr_zlumi_ratio), R.nullptr,
array(
'd',arr_zerr_ratio))
251 c1 = R.TCanvas(
"c1",
"c1", 2000, 1000)
252 leg = R.TLegend(0.5, 0.18, 0.65, 0.4)
255 leg = R.TLegend(0.6, 0.18, 0.75, 0.4)
258 tg.GetYaxis().SetRangeUser(ymin, ymax)
260 plot_title =
"Absolute L_{"+ zstring +
"} to ATLAS across " + norm_type
262 plot_title =
"Normalised L_{"+ zstring +
"} to ATLAS across " + norm_type
265 stdev = np.percentile(abs(arr_zlumi_ratio - np.median(arr_zlumi_ratio)), 68)
266 print(
"68% band =", stdev)
268 mean = tg.GetFunction(
'pol0').GetParameter(0)
269 print(
"const of pol0 fit", mean)
270 print(
"median", np.median(arr_zlumi_ratio))
271 print(
"mean", np.mean(arr_zlumi_ratio))
273 line1 = pt.make_bands(arr_date, stdev, np.median(arr_zlumi_ratio))
279 leg.SetTextSize(0.05)
280 leg.AddEntry(tg, leg_entry,
"ep")
281 leg.AddEntry(line1,
"68%% band (#pm %.3f)" % stdev,
"f")
284 pt.drawAtlasLabel(xval, yval-0.47,
"Internal")
285 pt.drawText(xval, yval-0.53, date_tag, size=labelsize)
286 pt.drawText(xval, yval-0.59, zstring, size=labelsize)
287 pt.drawText(xval, yval-0.65,
"OflLumi-Run3-006", size=labelsize)
288 pt.drawText(xval, yval-0.04, total_lumi_string, size=labelsize)
290 pt.drawText(xval, 0.88, plot_title, size=labelsize)
292 tg.GetXaxis().SetTitle(xtitle)
293 tg.GetYaxis().SetTitle(ytitle)
294 tg.GetYaxis().SetRangeUser(ymin, ymax)
295 tg.GetXaxis().SetTimeDisplay(2)
296 tg.GetXaxis().SetNdivisions(9,R.kFALSE)
297 tg.GetXaxis().SetTimeFormat(time_format)
298 tg.GetXaxis().SetTimeOffset(0,
"gmt")
303 filename = outdir + channel +
"ATLAS_ratio_vs_time_"+out_tag
305 c1.SaveAs(filename+
"_abs.pdf")
307 c1.SaveAs(filename+
".pdf")
311 csvfile =
open(filename+
"_abs.csv",
'w')
313 csvfile =
open(filename+
".csv",
'w')
314 csvwriter = csv.writer(csvfile, delimiter=
',')
315 csvwriter.writerow([
'FillNum',
'RunNum',
'Time',
'OffLumi',
'ZLumi',
'ZLumiErr',
'OffZlumi',
'OffZlumiErr'])
316 for i
in range(len(run_num)):
317 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]])
322 if __name__ ==
"__main__":
324 R.gROOT.SetBatch(R.kTRUE)