ATLAS Offline Software
compileRPVLLRates.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
2 # Author: Heather Russel
3 # Modified: 3 Dec 2019 by Guillermo Hamity
4 
5 # STEP 1: PARSE PHYSICS MAIN LOGFILES
6 # $ python readFiles.py [output file name] [InputFolderWithLogFiles]
7 # before deleted, can find physics_Main log files on eos -- ex:
8 # /eos/atlas/atlastier0/tzero/prod/data16_13TeV/physics_Main/00303304/data16_13TeV.00303304.physics_Main.daq.RAW.f716.recon.task.LOG/
9 # 2*n_filters+1 lines should be recovered from each file!
10 # 22 filters + DVAugmentationKernel --> 2*23+1 = 47
11 
12 # NOTE: log files only stay around for a few weeks
13 # or the folder is empty and LOGARC remains -->
14 # logs can likely be recoverd from LOGARC files, if necessary
15 
16 # NOTE: for shorter or local individual runs can grep logs directly:
17 # grep -E "RAWtoALL.*RPVLL.*Events|BSESOutputSvcStreamDRAW_RPVLL.*events" INPUT_LOG_FILES > rpvllLog_runNumber.out &
18 
19 # STEP 2: COMPILE RPVLL RATE INFORMATION
20 # $ python compileRPVLLRates.py rpvllLog_runNumber.out RUNNUMBER lbTimes_runNumber.out
21 # rpvllLog = output from readFiles.py or grep command
22 # RUNNUMBER is data run number (for labeling plots)
23 # lbTimes = list of lumiblocks and seconds/lumiblocks (can be copied from runquery)
24 
25 # NOTE ON lbTimes FILE:
26 # for easiest copying from runquery, code designed to read file with (at least) three columns:
27 # lb | start time (not used) | duration | nEvents in lb (optional)
28 # --> second column must contain any non-empty string
29 # --> fourth column is optional and used for scaling of analyses of partial lb's
30 
31 # outputs n_filters+1 rate plots:
32 # one plot for overall rate + stacked filter rates
33 # n_filters plots for individual filter rates -- one per filter
34 # plots outputted into "plots/" directory
35 # --> MAKE SURE THIS EXISTS IN CURRENT WORKING DIRECTORY (wherever script called from)
36 
37 # NOTE: for personal runs, RAWtoDRAW_RPVLL log files need to be in following format to work w/ this script:
38 # *._lb*._*
39 
40 
41 import sys
42 import ROOT
43 from ROOT import gROOT, TCanvas, TH1F, THStack, gPad, gStyle
44 import math
45 from decimal import Decimal
46 
47 
48 
49 
50 mypath = sys.argv[1]
51 runNumber = sys.argv[2]
52 lb_rates = sys.argv[3]
53 
54 
55 
59 filterNames = [ 'DiLep_SiElectronFilterKernel',
60  'DiLep_SiPhotonXFilterKernel',
61  'DiLep_SiMuonFilterKernel',
62  'DiLep_DiElectronFilterKernel',
63  'DiLep_DiPhotonFilterKernel',
64  'DiLep_DiElPhFilterKernel',
65  'DiLep_DiLoElPhFilterKernel',
66  'DVAugmentationKernel',
67  'DVMuonFilterKernel',
68  'DV_PhotonFilterKernel',
69  'DV_PhotonPlusTLJetFilterKernel',
70  'DV_MultiJetFilterKernel',
71  'DV_METFilterKernel',
72  'DV_MeffFilterKernel',
73  'KinkedTrackJetFilterKernel',
74  'KinkedTrackMultiJetFilterKernel',
75  'KinkedTrackZeeFilterKernel',
76  'KinkedTrackZmumuFilterKernel',
77  'EmergingFilterKernel',
78  'HnlFilterKernel',
79  'HV_MuvtxFilterKernel',
80  'HV_JetMETFilterKernel',
81  'HV_CalRatioFilterKernel',
82  'LargeRTaus_SiFilterKernel',
83  'LargeRTaus_DiFilterKernel',
84  'LargeRTaus_METFilterKernel']
85 
86 # list filter names excluding DVAugmentationKernel -- for plotting and calculating rate
87 filterNames_mAug = [fn for fn in filterNames if fn != 'DVAugmentationKernel']
88 
89 nf = len(filterNames) # number of filters (23)
90 nfm = len(filterNames_mAug) # number of filters excluding DVAug (22)
91 nft = nf*2+1 # number of filters times two (events analyzed + accepted) plus one (total) (47)
92 n_aug = filterNames.index('DVAugmentationKernel') # filterNames ix where DVAug resides (7)
93 
94 
95 
100 def end_lb(lumiBlock, lbEventList = [], rateHists = [], totalRateHist = 0):
101  n_events_lb = lbEventList[0] # get total number of events per lumiblock
102  n_passed_lb = lbEventList[nft-1] # get total number of filter-passing events per lumiblock
103  lbFilters = [0] * (nf-1) # initialize list of filter-passing events for specific lumiblock
104  for i in range (0,nf):
105  # exclude DVAug -- don't want to plot this
106  if i < n_aug:
107  # every second line contains number of accepted events
108  lbFilters[i] = lbEventList[2*i+1]
109  elif i > n_aug:
110  lbFilters[i-1] = lbEventList[2*i+1]
111  # fill each filter histogram with filter rate
112  for i,lb in enumerate(lbFilters):
113  rateHists[i].Fill(lumiBlock, float(lb))
114  # fill total-rate histogram with overal rpvll rate
115  totalRateHist.Fill(lumiBlock, float(n_passed_lb))
116  return
117 
118 
119 
121 rateHists = []
122 for i in range(0,nf-1):
123  rateHists.append(TH1F("ratePerLB_filter" + str(i), "ratePerLB_filter;lb;rate", 2500, 0, 2500))
124  rateHists[i].Sumw2()
125 eventHists=[]
126 for i in range(0,nf-1):
127  eventHists.append(TH1F("eventsPerLB_filter" + str(i), "eventsPerLB_filter;lb;events", 2500, 0, 2500))
128  eventHists[i].Sumw2()
129 # overall rate histogram
130 totalRateHist = TH1F("ratePerLB_overall", "ratePerLB_overall;lb;rate", 2500, 0, 2500)
131 totalRateHist.Sumw2()
132 
133 # lumiblock-time hist (needed to calculate rate)
134 lbTimeHist = TH1F("lbTimeHist", "lbTimeHist", 2500, 0, 2500)
135 lbList = open(lb_rates).readlines()
136 for lineNo,line in enumerate(lbList):
137  lbTimeHist.Fill(float(line.split()[0]), float(line.split()[2]))
138  lbTimeHist.SetBinError(lbTimeHist.FindBin(float(line.split()[0])), 0) # ???
139 
140 
141 
143 List = open(mypath).readlines()
144 
145 # initialize lists to hold filter data from log files
146 lbEventList = [0] * nft # events per lumiblock
147 eventList = [0] * nft # total events for all lumiblocks
148 
149 # initialize lumiblock variables
150 first_lb = 0
151 first_line = List[0]
152 for lb1 in first_line.split("._"):
153  if "lb" in lb1: first_lb = int(lb1[2:])
154 current_lb = first_lb
155 last_lb = 2500 # will change based on data in file
156 print("FIRST LB:", first_lb, current_lb)
157 
158 # initialize list to hold total number of processed events per lumiblock
159 procEvents = []
160 
161 # loop over lines in filter-data list (from rpvll log output)
162 for lineNo,line in enumerate(List):
163  # if line number mod 2*n_filters+1 = 0, we're at the beginning of filter list
164  if lineNo % nft == 0:
165  # extract lumiblock info from line
166  for lb in line.split("._"):
167  if "lb" in lb:
168  # if lumiblock read from line not "current_lb"
169  # we've collected all info for current lumiblock --> start of new lb
170  # --> call end_lb for lumiblock just processed + reset
171  if int(lb[2:]) != current_lb:
172  end_lb(current_lb, lbEventList, rateHists, totalRateHist)
173  # save number of events processed per lumiblock
174  procEvents.append(lbEventList[0])
175  # set current lumiblock to lumiblock read from line
176  current_lb = int(lb[2:])
177  # re-initialize lbEventList -- set all elements to zero
178  lbEventList = [0] * nft
179  # catches any repeats ??? -- necessary to avoid overcounting somehow
180  if (lineNo < len(List) - nft):
181  if (line.split()[0][:-10] == List[lineNo+nft].split()[0][:-10]):
182  continue
183  # get number of events analyzed/accepted from each line
184  s = line.split()[-1]
185  # add number of events analyzed/accepted per lb to lbEventList
186  lbEventList[lineNo % nft] += int(s)
187  eventList[lineNo % nft] += int(s)
188 
189 # run end_lb for last lumiblock; set last_lb to last lb in file; get n events from last lb
190 end_lb(current_lb, lbEventList, rateHists, totalRateHist)
191 last_lb = current_lb
192 procEvents.append(lbEventList[0])
193 
194 
195 
196 totalEvents = eventList[0]
197 totalRPVLLpass = eventList[nft-1]
198 print('Events passing RPVLL filters:', totalRPVLLpass, 'out of', totalEvents)
199 print('RPVLL filter efficiency:', float(totalRPVLLpass)/float(totalEvents) * 100., '%')
200 print('RPVLL normalized average rate: ', float(totalRPVLLpass)/float(totalEvents) * 1000., 'Hz')
201 print('')
202 
203 # calculate fraction of events passing each indidivual filter
204 fracList_total = [0] * nf # fraction of ALL events passing filter
205 fracList_RPVLL = [0] * nf # fraction of RPVLL events passing filter
206 filterEvents = [0] * nf
207 closureTest = 0
208 
209 print('FRACTION OF (RPVLL | TOTAL) EVENTS PASSING EACH FILTER:')
210 for filterNo in range(0,nf):
211  closureTest += eventList[filterNo*2+1]
212  fracList_total[filterNo] = float(eventList[filterNo*2+1])/float(totalEvents)
213  fracList_RPVLL[filterNo] = float(eventList[filterNo*2+1])/float(totalRPVLLpass)
214  filterEvents[filterNo] = eventList[filterNo*2+1]
215  if filterNo != n_aug:
216  print(filterNames[filterNo], ' -- ', '%.2E' % Decimal(fracList_RPVLL[filterNo]), ' | ', '%.2E' % Decimal(fracList_total[filterNo]))
217 print('')
218 
219 print('NORMALIZED (to 1 kHz) AVERAGE FILTER RATE:')
220 for filterNo in range(0,nf):
221  if filterNo != n_aug:
222  print(filterNames[filterNo], ' -- ', '%.2f' % (fracList_total[filterNo]*1000), 'Hz')
223 print('')
224 
225 # subtract away events corresponding to DVAugmentationKernel -- NOT A FILTER
226 # closureTest_mAug will always be larger than totalRPVLLpass because of overlap
227 # --> some RPVLL events will pass multiple filters and thus be added multiple times
228 closureTest_mAug = closureTest - filterEvents[n_aug]
229 print('Total number of events passing filters / total number of events passing RPVLL: ', closureTest_mAug, '/', totalRPVLLpass, '=', float(closureTest_mAug)/float(totalRPVLLpass) * 100., '%')
230 print('')
231 
232 # printout for easy copy-paste into google spreadsheet
233 for n in filterNames_mAug:
234  print(n,)
235 print('')
236 for n in range(0,nf):
237  if n != n_aug: print(filterEvents[n],)
238 print('')
239 
240 
241 
242 
243 lbEventHist = TH1F("lbEventHist", "lbEventHist", 2500, 0, 2500)
244 lbFullEventHist = TH1F("lbFullEventHist", "lbFullEventHist", 2500, 0, 2500)
245 lbScaleHist = TH1F("lbScaleHist", "lbScaleHist", 2500, 0, 2500)
246 # parse lbTimes file for total events per lumiblock per run -- for scaling partial runs
247 scale = []
248 l = 0
249 for lineNo,line in enumerate(lbList):
250  if (float(line.split()[0]) >= first_lb and float(line.split()[0]) <= last_lb):
251  lbEventHist.Fill(float(line.split()[0]), procEvents[l])
252  lbEventHist.SetBinError(lbEventHist.FindBin(float(line.split()[0])), 0)
253  if len(line.split()) > 3:
254  lbFullEventHist.Fill(float(line.split()[0]), float(line.split()[3]))
255  lbFullEventHist.SetBinError(lbFullEventHist.FindBin(float(line.split()[0])), 0)
256  scale.append(float(line.split()[3])/float(procEvents[l]))
257  else:
258  lbFullEventHist.Fill(float(line.split()[0]), procEvents[l])
259  scale.append(1)
260  lbScaleHist.Fill(float(line.split()[0]), scale[l])
261  lbScaleHist.SetBinError(lbScaleHist.FindBin(float(line.split()[0])), 0)
262  #print "TEST: ", line.split()[0], procEvents[l], scale[l], l, lineNo, len(procEvents)
263  l += 1
264 print('')
265 
266 
267 
269 colors = [
270 # seven for DiLep
271 ROOT.kBlue+3, ROOT.kBlue+1, ROOT.kBlue-4, ROOT.kBlue-2, ROOT.kBlue-7,ROOT.kBlue-5, ROOT.kBlue-9,
272 # six for DV
273 ROOT.kRed+3, ROOT.kRed+1, ROOT.kRed-2, ROOT.kRed-4, ROOT.kRed-6,ROOT.kRed-9,
274 # four for kinked track
275 ROOT.kCyan+2, ROOT.kTeal-8, ROOT.kCyan-6, ROOT.kCyan,
276 # emerging
277 ROOT.kGreen+1,
278 # HNL
279 ROOT.kOrange+8,
280 # three for HV
281 ROOT.kViolet+8, ROOT.kViolet+3, ROOT.kViolet-9,
282 # LargeR Taus
283 ROOT.kYellow+2,ROOT.kYellow+9,ROOT.kYellow-5
284  ]
285 
286 # ALL FILTERS -- STACK PLOT
287 # create + configure new canvas
288 c1 = TCanvas('c1', '', 1000, 600)
289 c1.SetRightMargin(0.25)
290 c1.SetLeftMargin(0.1)
291 
292 # create + configure new legend
293 l1 = ROOT.TLegend(0.76, 0.1, 0.97, 0.91)
294 l1.SetFillColor(0)
295 l1.SetFillStyle(0)
296 l1.SetBorderSize(0)
297 l1.SetTextSize(0.02)
298 
299 # FILTER EVENTS
300 # configure total rate hist
301 totalRateHist.SetMarkerStyle(22)
302 totalRateHist.SetMarkerSize(1.2)
303 if (last_lb - first_lb) > 600:
304  totalRateHist.SetMarkerSize(0.6)
305 totalRateHist.SetMarkerColor(ROOT.kBlack)
306 totalRateHist.SetLineColor(ROOT.kBlack)
307 for bin in range(1, totalRateHist.GetNbinsX() + 1):
308  totalRateHist.SetBinError(bin, 0) # no appreciable errors on rate
309 # add total rate hist entry to legend
310 l1.AddEntry(totalRateHist, "Overall RPVLL Events", "lp")
311 
312 # initialize stack for all filter rate hists
313 hs1 = THStack("hs1", "");
314 # add individual filter rate hists to stack
315 for i,hist in enumerate(rateHists):
316  hist.SetFillColor(colors[i])
317  hist.SetLineColor(colors[i])
318  hs1.Add(hist)
319  # add individual rate entries to legend
320  l1.AddEntry(hist, filterNames_mAug[i], "f")
321 
322 # draw individual filter stack + overall rate hist
323 hs1.Draw("HIST")
324 totalRateHist.Draw("pSAME")
325 
326 
328 hs1.GetXaxis().SetTitle("lumi block")
329 hs1.GetYaxis().SetTitle("n events")
330 hs1.GetYaxis().SetTitleOffset(.75)
331 # set axis ranges
332 hs1.GetXaxis().SetRangeUser(first_lb - 20, last_lb + 20)
333 hs1.GetYaxis().SetRangeUser(0, 100)
334 # set tick marks on all axes
335 gPad.SetTicks(1, 1)
336 
337 # draw legend
338 l1.Draw()
339 
340 # add text to plot
341 latex1 = ROOT.TLatex(0.52, 0.875, "#font[72]{ATLAS }#font[42]{Internal}")
342 latex1.SetNDC()
343 latex1.SetTextSize(0.05)
344 latex1.SetTextAlign(13)
345 latex1.Draw()
346 latex2 = ROOT.TLatex(0.55, 0.82, "Run " + runNumber)
347 latex2.SetNDC()
348 latex2.SetTextSize(0.05)
349 latex2.SetTextAlign(13)
350 latex2.SetTextFont(42)
351 latex2.Draw()
352 
353 # print stack
354 c1.Update()
355 c1.Print("run_" + runNumber + "_rpvllEvents.pdf")
356 c1.Clear()
357 l1.Clear()
358 
359 
360 # individual filter events
361 c2 = TCanvas('c2', '', 850, 600)
362 c2.SetRightMargin(0.11765)
363 c2.SetLeftMargin(0.11765)
364 
365 latex3 = ROOT.TLatex(0.62, 0.875, "#font[72]{ATLAS }#font[42]{Internal}")
366 latex3.SetNDC()
367 latex3.SetTextSize(0.05)
368 latex3.SetTextAlign(13)
369 latex4 = ROOT.TLatex(0.65, 0.82, "Run " + runNumber)
370 latex4.SetNDC()
371 latex4.SetTextSize(0.05)
372 latex4.SetTextAlign(13)
373 latex4.SetTextFont(42)
374 
375 # loop over filter rate histograms
376 for j,h in enumerate(rateHists):
377  h.SetMarkerStyle(22)
378  h.SetMarkerSize(1.2)
379  if (last_lb - first_lb) > 600:
380  h.SetMarkerSize(0.6)
381  h.SetMarkerColor(colors[j])
382  h.SetLineColor(colors[j])
383  h.Draw("P")
384  h.SetTitle(filterNames_mAug[j])
385  h.GetXaxis().SetTitle("lumi block")
386  h.GetYaxis().SetTitle("n events")
387  h.GetXaxis().SetRangeUser(first_lb - 20, last_lb + 20)
388  h.SetStats(ROOT.kFALSE)
389  gPad.SetTicks(1,1)
390  gStyle.SetErrorX(0)
391  latex3.Draw()
392  latex4.Draw()
393  c2.Update()
394  c2.Print("run_" + runNumber + "_" + str(j) + "_events.pdf")
395 
396 
397 # FILTER RATES
398 c1.cd()
399 # configure total rate hist
400 totalRateHist.Divide(lbTimeHist)
401 totalRateHist.Multiply(lbScaleHist)
402 for bin in range(1, totalRateHist.GetNbinsX() + 1):
403  totalRateHist.SetBinError(bin, 0) # no appreciable errors on rate
404 # add total rpvll rate hist entry to legend
405 l1.AddEntry(totalRateHist, "Overall RPVLL Rate", "lp")
406 
407 # initialize stack for all filter rate hists
408 hs2 = THStack("hs2", "");
409 # add individual filter rate hists to stack
410 for i,hist in enumerate(rateHists):
411  hist.SetFillColor(colors[i])
412  hist.SetLineColor(colors[i])
413  hist.Divide(lbTimeHist) # calculate rate estimate
414  hist.Multiply(lbScaleHist) # scale to full lb
415  hs2.Add(hist)
416  # add individual event entries to legend
417  l1.AddEntry(hist, filterNames_mAug[i], "f")
418 
419 # draw individual filter stack + overall rate hist
420 hs2.Draw("HIST")
421 totalRateHist.Draw("pSAME")
422 
423 
425 hs2.GetXaxis().SetTitle("lumi block")
426 hs2.GetYaxis().SetTitle("rate [Hz]")
427 hs2.GetYaxis().SetTitleOffset(.75)
428 # set axis ranges
429 hs2.GetXaxis().SetRangeUser(first_lb - 20, last_lb + 20)
430 hs2.GetYaxis().SetRangeUser(0,100)
431 # set tick marks on all axes
432 gPad.SetTicks(1,1)
433 
434 # draw legend
435 l1.Draw()
436 
437 # add text to plot
438 latex1.Draw()
439 latex2.Draw()
440 
441 # print stack
442 c1.Update()
443 c1.Print("run_" + runNumber + "_rpvllRate.pdf")
444 c1.Clear()
445 l1.Clear()
446 
447 
448 # individual filter rates
449 c2.cd()
450 # loop through filter rate histograms
451 for j,h in enumerate(rateHists):
452  h.SetMarkerStyle(22)
453  h.SetMarkerSize(1.2)
454  if (last_lb - first_lb) > 600:
455  h.SetMarkerSize(0.6)
456  h.SetMarkerColor(colors[j])
457  h.SetLineColor(colors[j])
458  # already divided by lb-times + multiplied by scale
459  h.Draw("P")
460  h.SetTitle(filterNames_mAug[j])
461  h.GetXaxis().SetTitle("lumi block")
462  h.GetYaxis().SetTitle("rate [Hz]")
463  h.GetXaxis().SetRangeUser(first_lb - 20, last_lb + 20)
464  h.SetStats(ROOT.kFALSE)
465  gPad.SetTicks(1,1)
466  gStyle.SetErrorX(0)
467  latex3.Draw()
468  latex4.Draw()
469  c2.Update()
470  c2.Print("run_" + runNumber + "_" + str(j) + "_rate.pdf")
471 
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
Trk::open
@ open
Definition: BinningType.h:40
compileRPVLLRates.end_lb
def end_lb(lumiBlock, lbEventList=[], rateHists=[], totalRateHist=0)
CLASS TO FILL RATE HISTOGRAMS W/ NUMBER OF PASSING EVENTS PER LUMIBLOCK ## lumiblock = specific lumib...
Definition: compileRPVLLRates.py:100
Muon::print
std::string print(const MuPatSegment &)
Definition: MuonTrackSteering.cxx:28
str
Definition: BTagTrackIpAccessor.cxx:11
python.TrigEgammaMonitorHelper.TH1F
def TH1F(name, title, nxbins, bins_par2, bins_par3=None, path='', **kwargs)
Definition: TrigEgammaMonitorHelper.py:24
readCCLHist.float
float
Definition: readCCLHist.py:83
Trk::split
@ split
Definition: LayerMaterialProperties.h:38