ATLAS Offline Software
hotSpotInHIST.py
Go to the documentation of this file.
1 #!/usr/bin env python
2 # Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration
3 # Script to browse the unmerged HIST files and extract LBs for which at least N occurences of an object is found
4 # at a position found to be noisy
5 # Uses the pathExtract library to extract the EOS path
6 # See the twiki: https://twiki.cern.ch/twiki/bin/viewauth/Atlas/UsingDQInframerge
7 # Author: Benjamin Trocme (LPSC Grenoble) / 2015-2016
8 # Update for Run 3 by Benjamin Trocme (LPSC Grenoble): March 2022
9 # * Adding a protection for the missing histograms in HIST file
10 # * Commenting the getStruct method (added by who???)
11 # * Adding the LoosePhotons object
12 
13 
14 import os, sys
15 import argparse
16 from six.moves import xmlrpc_client as xmlrpclib
17 import math
18 from DataQualityUtils import pathExtract
19 
20 sys.path.append("/afs/cern.ch/user/l/larmon/public/prod/Misc")
21 from LArMonCoolLib import GetLBTimeStamps,GetOnlineLumiFromCOOL
22 
23 import ROOT as R
24 
25 
27 def lbStr(lb):
28  """Return formatted lumiblock string"""
29  return "_lb"+lb.zfill(5)
30 
31 def getHistoInfo(objectType, runNumber):
32  """Histo path definition base on object type"""
33  # histoPath : Histogram path in the ROOT file
34  # histoLegend : Histogram legend
35  # histoColor : Colors for the final summary plot
36  # histoName : Name of object
37  # Types of plot
38  # 2d_etaPhi_Occupancy : 2D occupancy plots: (eta/phi) required
39  # 2d_etaPhi_MeanPt : 2D mean Pt plots: (eta/phi) required
40  # 2d_xy_Occupancy : any 2D plots: (x/y) required
41  # 1d_eta_Occupancy : 1D occupancy plot along eta: (eta) required
42  # 1d_phi_Occupancy : 1D occupancy plot along phi: (phi) required
43  # 1d_integralAbove_Occupancy : integral between (integralAbove) and infinity. (integralAbove) required
44  # NB : if the required arguments are not provided, consider the whole histogram
45 
46  runstr = "run_"+str(runNumber)
47 
48  if objectType == "TopoClusters": # Release 22 : OK
49  histoPath = {"ECA_thr1":runstr+"/CaloTopoClusters/CalECA/Thresh1ECAOcc",
50  "ECA_thr2":runstr+"/CaloTopoClusters/CalECA/Thresh2ECAOcc",
51  "ECA_thr3":runstr+"/CaloTopoClusters/CalECA/Thresh3ECAOcc",
52  "ECC_thr1":runstr+"/CaloTopoClusters/CalECC/Thresh1ECCOcc",
53  "ECC_thr2":runstr+"/CaloTopoClusters/CalECC/Thresh2ECCOcc",
54  "ECC_thr3":runstr+"/CaloTopoClusters/CalECC/Thresh3ECCOcc",
55  "BAR_thr1":runstr+"/CaloTopoClusters/CalBAR/Thresh1BAROcc",
56  "BAR_thr2":runstr+"/CaloTopoClusters/CalBAR/Thresh2BAROcc",
57  "BAR_thr3":runstr+"/CaloTopoClusters/CalBAR/Thresh3BAROcc"}
58  histoLegend = {"ECA_thr1":"ECA - Et > 10 GeV",
59  "ECA_thr2":"ECA - Et > 15 GeV",
60  "ECA_thr3":"ECA - Et > 25 GeV",
61  "ECC_thr1":"ECC - Et > 10 GeV",
62  "ECC_thr2":"ECC - Et > 15 GeV",
63  "ECC_thr3":"ECC - Et > 25 GeV",
64  "BAR_thr1":"BAR - Et > 10 GeV",
65  "BAR_thr2":"BAR - Et > 15 GeV",
66  "BAR_thr3":"BAR - Et > 25 GeV"}
67  histoType = "2d_etaPhi_Occupancy"
68  histoName = "TopoClusters occupancy"
69 
70  elif objectType == "EMTopoClusters": # Release 22 : OK
71  histoPath = {"Et4GeV":runstr+"/CaloMonitoring/ClusterMon/LArClusterEMNoTrigSel/2d_Rates/m_clus_etaphi_Et_thresh1",
72  "Et10GeV":runstr+"/CaloMonitoring/ClusterMon/LArClusterEMNoTrigSel/2d_Rates/m_clus_etaphi_Et_thresh2",
73  "Et25GeV":runstr+"/CaloMonitoring/ClusterMon/LArClusterEMNoTrigSel/2d_Rates/m_clus_etaphi_Et_thresh3"}
74  histoLegend = {"Et4GeV":"Et > 4GeV",
75  "Et10GeV":"Et > 10GeV",
76  "Et25GeV":"Et > 25GeV"}
77  histoPath = {"ECA_thr1":runstr+"/CaloTopoClusters/CalEMECA/EMThresh1ECAOcc",
78  "ECA_thr2":runstr+"/CaloTopoClusters/CalEMECA/EMThresh2ECAOcc",
79  "ECA_thr3":runstr+"/CaloTopoClusters/CalEMECA/EMThresh3ECAOcc",
80  "ECC_thr1":runstr+"/CaloTopoClusters/CalEMECC/EMThresh1ECCOcc",
81  "ECC_thr2":runstr+"/CaloTopoClusters/CalEMECC/EMThresh2ECCOcc",
82  "ECC_thr3":runstr+"/CaloTopoClusters/CalEMECC/EMThresh3ECCOcc",
83  "BAR_thr1":runstr+"/CaloTopoClusters/CalEMBAR/EMThresh1BAROcc",
84  "BAR_thr2":runstr+"/CaloTopoClusters/CalEMBAR/EMThresh2BAROcc",
85  "BAR_thr3":runstr+"/CaloTopoClusters/CalEMBAR/EMThresh3BAROcc"}
86  histoLegend = {"ECA_thr1":"ECA - Et > 4 GeV",
87  "ECA_thr2":"ECA - Et > 10 GeV",
88  "ECA_thr3":"ECA - Et > 15 GeV",
89  "ECC_thr1":"ECC - Et > 4 GeV",
90  "ECC_thr2":"ECC - Et > 10 GeV",
91  "ECC_thr3":"ECC - Et > 15 GeV",
92  "BAR_thr1":"BAR - Et > 4 GeV",
93  "BAR_thr2":"BAR - Et > 10 GeV",
94  "BAR_thr3":"BAR - Et > 15 GeV"}
95  histoType = "2d_etaPhi_Occupancy"
96  histoName = "EMTopoClusters occupancy"
97 
98  elif objectType == "EMTopoJet": # Release 22 : Missing histograms
99  histoPath = {"noCut":runstr+"/Jets/AntiKt4EMTopoJets/OccupancyEtaPhi",
100  "cut1":runstr+"/Jets/AntiKt4EMTopoJets/OccupancyEtaPhisel_20000_inf_pt_inf_500000",
101  "cut2":runstr+"/Jets/AntiKt4EMTopoJets/OccupancyEtaPhisel_500000_inf_pt_inf_1000000",
102  "cut3":runstr+"/Jets/AntiKt4EMTopoJets/OccupancyEtaPhisel_1000000_inf_pt_inf_2000000",
103  "cut4":runstr+"/Jets/AntiKt4EMTopoJets/OccupancyEtaPhisel_2000000_inf_pt_inf_8000000"}
104  histoLegend = {"noCut":"No cut",
105  "cut1":"20GeV-500GeV",
106  "cut2":"500GeV-1TeV",
107  "cut3":"1TeV-2TeV",
108  "cut4":"2TeV-8TeV"}
109  histoType = "2d_etaPhi_Occupancy"
110  histoName = "EMTopoJets"
111 
112  elif objectType == "AntiKt4EMTopoJets": # Release 22 : OK
113  histoPath = {"noCut":runstr+"/Jets/AntiKt4EMTopoJets/standardHistos/phi_eta"}
114  histoLegend = {"noCut":"No cut"}
115  histoType = "2d_etaPhi_Occupancy"
116  histoName = "Occupancy of AntiKt4EMTopoJets"
117 
118  elif objectType == "AntiKt4EMTopoJets_pt": # Release 22 : OK
119  histoPath = {"noCut":runstr+"/Jets/AntiKt4EMTopoJets/standardHistos/phi_eta_pt"}
120  histoLegend = {"noCut":"No cut"}
121  histoType = "2d_etaPhi_MeanPt"
122  histoName = "Mean Pt of AntiKt4EMTopoJets"
123 
124  elif objectType == "MET_Topo_phi": # Release 22 : OK
125  histoPath = {"MET":runstr+"/MissingEt/AllTriggers/MET_Calo/EMTopo/MET_Topo_phi"}
126  histoLegend = {"MET":"MET"}
127  histoType = "1d_phi_Occupancy"
128  histoName = "MET phi"
129 
130  elif objectType == "Tau": # Release 22 : OK
131  histoPath = {"NoCut":runstr+"/Tau/tauPhiVsEta",
132  "Et15GeV":runstr+"/Tau/tauPhiVsEta_et15"}
133  histoLegend = {"NoCut":"Et > 0 GeV (tbc)",
134  "Et15GeV":"Et > 15 GeV"}
135  histoType = "2d_etaPhi_Occupancy"
136  histoName = "Tau occupancy"
137 
138  elif objectType == "Tau_phi": # Release 22 : OK
139  histoPath = {"single":runstr+"/Tau/tauPhi"}
140  histoLegend = {"single":"All candidates"}
141  histoType = "1d_phi_Occupancy"
142  histoName = "Tau"
143 
144  elif objectType == "Tau_eta": # Release 22 : OK
145  histoPath = {"single":runstr+"/Tau/tauEta"}
146  histoLegend = {"single":"All candidates"}
147  histoType = "1d_eta_Occupancy"
148  histoName = "Tau phi"
149 
150  elif objectType == "NumberTau": # Release 22 : OK
151  histoPath = {"highPt":runstr+"/Tau/nHightPtTauCandidates"}
152  histoLegend = {"highPt":"High Pt (>100GeV) candidates"}
153  histoType = "1d_integralAbove_Occupancy"
154  histoName = "Number of Tau candidates"
155 
156  elif objectType == "TightFwdElectrons": # Release 22 : Missing histogram
157  histoPath = {"single":runstr+"/egamma/forwardElectrons/forwardElectronTightEtaPhi"}
158  histoLegend = {"single":"10GeV"}
159  histoType = "2d_etaPhi_Occupancy"
160  histoName = "Tight electrons"
161 
162  elif objectType == "LoosePhotons": # Release 22 : Missing histogram
163  histoPath = {"single":runstr+"/egamma/CBLoosePhotons/Eta_Phi_distribution_with_Pt.gt.4GeV"}
164  histoLegend = {"single":"4GeV"}
165  histoType = "2d_etaPhi_Occupancy"
166  histoName = "Loose photons"
167 
168  elif objectType == "NumberTightFwdElectrons": # Release 22 : Missing histogram
169  histoPath = {"single":runstr+"/egamma/forwardElectrons/forwardElectronTightN"}
170  histoLegend = {"single":"All candidates"}
171  histoType = "1d_integralAbove_Occupancy"
172  histoName = "Number of tight forward electrons"
173 
174  elif objectType == "HLT_TausRoIs":
175  histoPath = {"single":runstr+"/HLT/ResultMon/HLT_Taus/HLT_TausRoIs"}
176  histoLegend = {"single":""}
177  histoType = "2d_etaPhi_Occupancy"
178  histoName = "HLT TausRoIs"
179 
180  elif objectType == "NumberHLTJet": # Release 22 : Missing histogram
181  histoPath = {"HLTJet":runstr+"/HLT/JetMon/HLT/10j40_L14J20/HLTJet_n"}
182  histoLegend = {"HLTJet":"All candidates"}
183  histoType = "1d_integralAbove_Occupancy"
184  histoName = "Number of HLT jets - 10J40_L14J20 trigger"
185 
186  elif objectType == "HLT_ConfigConsistency": # Missing histogram
187  histoPath = {"HLTJet":runstr+"/HLT/ResultMon/ConfigConsistency_HLT"}
188  histoLegend = {"HLTJet":"Configuration consistency"}
189  histoType = "1d_integralAbove_Occupancy"
190  histoName = "Number of HLT config inconsistencies"
191 
192  elif objectType == "LArDigits": # Release 22 : not tested
193  histoPath = {"Null-EMBA":runstr+"/LAr/Digits/Barrel/NullDigitChan_BarrelA",
194  "Satu-EMBA":runstr+"/LAr/Digits/Barrel/SaturationChan_BarrelA",
195  "Null-EMBC":runstr+"/LAr/Digits/Barrel/NullDigitChan_BarrelC",
196  "Satu-EMBC":runstr+"/LAr/Digits/Barrel/SaturationChan_BarrelC",
197  }
198  histoLegend = {"Null-EMBA":"Null digit - EMBA",
199  "Satu-EMBA":"Saturated digit - EMBA",
200  "Null-EMBC":"Null digit - EMBC",
201  "Satu-EMBC":"Saturated digit - EMBC",}
202  histoType = "2d_xy_Occupancy"
203  histoName = "LAr saturated/null digits"
204 
205  else:
206  print("Object type:",objectType,"not recognised!")
207  sys.exit()
208 
209  cols = [R.kBlue+1, R.kGreen+1, R.kOrange+7, R.kMagenta+2, R.kCyan-3,
210  R.kGreen-5, R.kRed, R.kCyan, R.kViolet,
211  R.kAzure-4, R.kMagenta-9, R.kGreen-9, R.kYellow]
212  histoColor = {k:cols[list(histoPath.keys()).index(k)] for k in histoPath.keys()}
213 
214  return histoPath, histoLegend, histoColor, histoType, histoName
215 
216 
218 def main(args):
219  histoPath, histoLegend, histoColor, histoType, histoName = getHistoInfo(args.objectType, args.runNumber)
220 
221 
224  b_wholeHisto = False
225  b_ValueNotEntries = False
226 
227  if histoType == "2d_etaPhi_Occupancy" or histoType == "2d_etaPhi_MeanPt":
228  if histoType == "2d_etaPhi_Occupancy":
229  summaryTitle = "Nb of hits in a region of %.2f around the position (%.2f,%.2f) - %s"%(args.deltaSpot,args.etaSpot,args.phiSpot,histoName)
230  else:
231  summaryTitle = "Mean Pt in a region of %.2f around the position (%.2f,%.2f) - %s"%(args.deltaSpot,args.etaSpot,args.phiSpot,histoName)
232  if (args.deltaSpot != 0):
233  print("Warning: you have been summing over several bins a variable that may be not summable (different from summing hits!)")
234 
235  statement = "I have looked for LBs with at least %.0f entries at position (%.2f,%.2f) in %s histogram"%(args.minInLB,args.etaSpot,args.phiSpot,histoName)
236  if (args.etaSpot==-999. or args.phiSpot==-999.):
237  print("No eta/phi defined -> whole histogram considered!")
238  b_wholeHisto = True
239  if histoType == "2d_xy_Occupancy":
240  b_ValueNotEntries = True
241  if (args.deltaSpot != 0):
242  print("Warning: you have been summing over several bins a variable that may be not summable (different from summing hits!)")
243  summaryTitle = "Value in a region of %.2f around the position (%.2f,%.2f) - %s"%(args.deltaSpot,args.xSpot,args.ySpot,histoName)
244  statement = "I have looked for LBs with at least variable > %.2f at position (%.2f,%.2f) in %s histogram"%(args.minInLB,args.xSpot,args.ySpot,histoName)
245  if (args.xSpot==-999. or args.ySpot==-999.):
246  print("No x/y defined -> whole histogram considered!")
247  print("Warning: you have been summing over several bins a variable that may be not summable (different from summing hits!)")
248  b_wholeHisto = True
249  elif histoType == "1d_eta_Occupancy":
250  summaryTitle = "Nb of hits in a region of %.2f around the eta position %.2f - %s"%(args.deltaSpot,args.etaSpot,histoName)
251  statement = "I have looked for LBs with at least %.0f entries at eta position %.2f in %s histogram"%(args.minInLB,args.etaSpot,histoName)
252  if (args.etaSpot==-999.):
253  print("No eta/phi -> whole histogram considered!")
254  b_wholeHisto = True
255  elif histoType == "1d_phi_Occupancy":
256  summaryTitle = "Nb of hits in a region of %.2f around the phi position %.2f - %s"%(args.deltaSpot,args.phiSpot,histoName)
257  statement = "I have looked for LBs with at least %.0f entries at phi position %.2f in %s histogram"%(args.minInLB,args.phiSpot,histoName)
258  if (args.phiSpot==-999.):
259  print("No eta/phi defined -> whole histogram considered!")
260  b_wholeHisto = True
261  elif histoType == "1d_integralAbove_Occupancy":
262  summaryTitle = "Nb of hits in the band above %.2f - %s"%(args.integralAbove,histoName)
263  statement = "I have looked for LBs with at least %.0f entries in band above %.2f in %s histogram"%(args.minInLB,args.integralAbove,histoName)
264  if (args.integralAbove==-999.):
265  print("No lower bound defined -> whole histogram considered!")
266  b_wholeHisto = True
267 
268  # Definition of Canvas option depending on histogram type
269  if (args.objectType == "NumberTightFwdElectrons" or args.objectType == "NumberTau"):
270  canvasOption = "logy"
271  else:
272  canvasOption = ""
273 
274 
278  runFilePath = "root://eosatlas.cern.ch/%s"%(pathExtract.returnEosHistPath(args.runNumber,args.stream,args.amiTag,args.tag)).rstrip()
279  if ("FILE NOT FOUND" in runFilePath):
280  print("No merged file found for this run")
281  print("HINT: check if there is a folder like","/eos/atlas/atlastier0/tzero/prod/"+args.tag+"/physics_CosmicCalo/00"+str(args.runNumber)+"/"+args.tag+".00"+str(args.runNumber)+".physics_CosmicCalo.*."+args.amiTag)
282  sys.exit()
283 
284  f = R.TFile.Open(runFilePath)
285 
286  histo = {}
287 
288  # print("Looking in file",runFilePath)
289  for iHisto in histoPath.keys():
290  #if histoPath[iHisto] not in histPathList:
291  # print("The desired histo path",histoPath[iHisto],"is not in the input file!")
292  histo[iHisto] = f.Get(histoPath[iHisto])
293  histo[iHisto].SetTitle("%s (%s) - Run %d"%(histo[iHisto].GetTitle(),histoLegend[iHisto],args.runNumber))
294 
295 
300  regionBins = {}
301  for iHisto in histoPath.keys():
302  if b_wholeHisto:
303  regionBins[iHisto] = []
304  if ("2d" in histoType):
305  maxBin = (histo[iHisto].GetNbinsX()+2)*(histo[iHisto].GetNbinsY()+2)
306  else:
307  maxBin = (histo[iHisto].GetNbinsX()+2)
308  for iBin in range(maxBin):
309  regionBins[iHisto].append(iBin)
310  else:
311  nSteps = 1000
312  subStep = 2*args.deltaSpot/nSteps
313  regionBins[iHisto] = []
314  if histoType == "2d_etaPhi_Occupancy" or histoType == "2d_etaPhi_MeanPt":
315  for ix in range(nSteps):# Assume that eta is on x axis
316  iEta = args.etaSpot - args.deltaSpot + ix * subStep
317  for iy in range (nSteps):
318  iPhi = args.phiSpot - args.deltaSpot + iy * subStep
319  tmpBin = histo[iHisto].FindBin(iEta,iPhi)
320  if (tmpBin not in regionBins[iHisto]):
321  regionBins[iHisto].append(tmpBin)
322  elif histoType == "2d_xy_Occupancy":
323  for ix in range(nSteps):
324  iX = args.xSpot - args.deltaSpot + ix * subStep
325  for iy in range (nSteps):
326  iY = args.ySpot - args.deltaSpot + iy * subStep
327  tmpBin = histo[iHisto].FindBin(iX,iY)
328  if (tmpBin not in regionBins[iHisto]):
329  regionBins[iHisto].append(tmpBin)
330  elif histoType == "1d_eta_Occupancy":
331  for ix in range(nSteps):
332  iEta = args.etaSpot - args.deltaSpot + ix * subStep
333  tmpBin = histo[iHisto].FindBin(iEta)
334  if (tmpBin not in regionBins[iHisto]):
335  regionBins[iHisto].append(tmpBin)
336  elif histoType == "1d_phi_Occupancy":
337  for ix in range(nSteps):
338  iPhi = args.phiSpot - args.deltaSpot + ix * subStep
339  tmpBin = histo[iHisto].FindBin(iPhi)
340  if (tmpBin not in regionBins[iHisto]):
341  regionBins[iHisto].append(tmpBin)
342  elif (histoType == "1d_integralAbove_Occupancy"):
343  for iBin in range(histo[iHisto].FindBin(args.integralAbove),histo[iHisto].GetNbinsX()):
344  regionBins[iHisto].append(iBin)
345 
346 
349 
350  c = {}
351  box = {}
352  line = {}
353  line2 = {}
354  arrow = {}
355  for iHisto in histoPath.keys():
356  total_tmp = 0
357  for iBin in regionBins[iHisto]:
358  total_tmp = total_tmp + histo[iHisto].GetBinContent(iBin)
359  if total_tmp == 0: # If no entry in the concerned area, do not display the merged histogram
360  continue
361 
362  c[iHisto] = R.TCanvas(histoLegend[iHisto])
363  if "logy" in canvasOption:
364  c[iHisto].SetLogy(1)
365  # draw line, arrows, box to highlight the suspicious region considered
366  if histoType.startswith("2d"):
367  R.gStyle.SetPalette(1)
368  R.gStyle.SetOptStat("")
369  #print(iHisto, histo[iHisto].GetEntries())
370  histo[iHisto].Draw("COLZ")
371  if not b_wholeHisto:
372  if histoType == "2d_etaPhi_Occupancy" or histoType == "2d_etaPhi_MeanPt":
373  box[iHisto] = R.TBox(args.etaSpot-args.deltaSpot,args.phiSpot-args.deltaSpot,args.etaSpot+args.deltaSpot,args.phiSpot+args.deltaSpot)
374  elif (histoType == "2d_xy_Occupancy"):
375  box[iHisto] = R.TBox(args.xSpot-args.deltaSpot,args.ySpot-args.deltaSpot,args.xSpot+args.deltaSpot,args.ySpot+args.deltaSpot)
376  box[iHisto].SetLineColor(R.kRed+1)
377  box[iHisto].SetLineWidth(3)
378  box[iHisto].SetFillStyle(0)
379  box[iHisto].Draw()
380 
381  elif histoType.startswith("1d"):
382  maxH = histo[iHisto].GetMaximum()*1.2
383  histo[iHisto].SetMaximum(maxH)
384  if histoType == "1d_eta_Occupancy" or histoType == "1d_phi_Occupancy":
385  minH = histo[iHisto].GetMinimum()*0.8
386  histo[iHisto].SetMinimum(minH)
387  histo[iHisto].Draw()
388 
389  if not b_wholeHisto:
390  if histoType == "1d_eta_Occupancy" or histoType == "1d_phi_Occupancy":
391  if maxH >0.:
392  if histoType == "1d_eta_Occupancy":
393  box[iHisto] = R.TBox(args.etaSpot-args.deltaSpot,minH,args.etaSpot+args.deltaSpot,maxH)
394  if histoType == "1d_phi_Occupancy":
395  box[iHisto] = R.TBox(args.phiSpot-args.deltaSpot,minH,args.phiSpot+args.deltaSpot,maxH)
396  box[iHisto].SetLineColor(R.kRed+1)
397  box[iHisto].SetLineWidth(3)
398  box[iHisto].SetFillStyle(0)
399  box[iHisto].Draw()
400  elif histoType == "1d_integralAbove_Occupancy":
401  line[iHisto] = R.TLine(args.integralAbove,0,args.integralAbove,maxH)
402  line[iHisto].SetLineColor(R.kRed+1)
403  line[iHisto].SetLineWidth(3)
404  line[iHisto].Draw()
405  arrow[iHisto] = R.TArrow(args.integralAbove,0.2*histo[iHisto].GetMaximum(),histo[iHisto].GetBinLowEdge(histo[iHisto].GetNbinsX()),0.2*histo[iHisto].GetMaximum(),0.02,">")
406  arrow[iHisto].SetLineColor(R.kRed+1)
407  arrow[iHisto].SetLineWidth(3)
408  arrow[iHisto].Draw()
409 
410 
414 
415  lbFilePathList = pathExtract.returnEosHistPathLB(args.runNumber,args.lowerLumiBlock,args.upperLumiBlock,args.stream,args.amiTag,args.tag)
416  nbHitInHot = []
417  if isinstance(lbFilePathList,str) and "NOT FOUND" in lbFilePathList:
418  print("Could not find per-LB files for this run")
419  print("HINT: check if there is a folder like","/eos/atlas/atlastier0/tzero/prod/"+args.tag+"/physics_CosmicCalo/00"+str(args.runNumber)+"/"+args.tag+".00"+str(args.runNumber)+".physics_CosmicCalo.*."+args.amiTag)
420  sys.exit()
421 
422  LBs = [int(f.split("_lb")[1].split(".")[0]) for f in lbFilePathList]
423  maxLB = max(LBs)
424  print("Max LB is",maxLB)
425 
426  nLB=maxLB
427  nbHitInHot = {}
428  for iHisto in histoPath.keys():
429  nbHitInHot[iHisto] = [0.] * (nLB+1)
430  lowerLB = maxLB
431  upperLB = 0
432  lbCanvas = []
433  histoLBNoisy = []
434  fLB = {}
435 
436  print("I have found the merged HIST file %s"%(runFilePath))
437  print("I have found %d unmerged HIST files"%(len(lbFilePathList)))
438  print("The first one is root://eosatlas.cern.ch/%s"%(lbFilePathList[0]))
439  print("The last one is root://eosatlas.cern.ch/%s"%(lbFilePathList[len(lbFilePathList)-1]))
440 
441  # Loop on all unmerged files
442 
443  for count,lbFile in enumerate(lbFilePathList):
444  lbFilePath = "root://eosatlas.cern.ch/%s"%(lbFile).rstrip()
445  # Extract lb from the filename and display it
446  ilb = int((lbFile.split("_lb")[1]).split("._")[0])
447  if (count%100 == 0):
448  sys.stdout.write("\n I processed %d/%d files \n LBs:"%(count,len(lbFilePathList)))
449  sys.stdout.write("%d "%(ilb))
450  sys.stdout.flush()
451  fLB[lbFile] = R.TFile.Open(lbFilePath)
452  histoLB = {}
453  for iHisto in histoPath.keys():
454  histoLB[iHisto] = fLB[lbFile].Get(histoPath[iHisto])
455  if (histoLB[iHisto] != None):
456  for iBin in regionBins[iHisto]:
457  nbHitInHot[iHisto][ilb] = nbHitInHot[iHisto][ilb] + histoLB[iHisto].GetBinContent(iBin)
458 
459  fLB[lbFile].Close()
460 
461 
465 
466  for iHisto in histoPath.keys():
467  for ilb in range(len(nbHitInHot[iHisto])):
468  if (nbHitInHot[iHisto][ilb]>=args.minInLB):
469  if ilb<lowerLB : lowerLB = ilb
470  if ilb>upperLB : upperLB = ilb
471 
472  if (lowerLB == upperLB):
473  lowerLB = lowerLB - 1
474  upperLB = upperLB + 4
475 
476  print("")
477  print(statement)
478 
479  maxNbInHot = 0
480  maxNbInHot_histo = ""
481  totalInRegionRecomp = {}
482  totalInRegion = {}
483  suspiciousLBlist = []
484 
485  # Initialize the number of events in suspicious regions for both the merged
486  # and the remerged files.
487  for iHisto in histoPath.keys():
488  totalInRegionRecomp[iHisto] = 0
489  totalInRegion[iHisto] = 0
490  # Then count the number of events and check if equal
491  # Also sort the LB to highlight most problematic LB
492  sortedLB = {}
493 
494  for iHisto in histoPath.keys():
495  print("======= ",histoLegend[iHisto])
496  for iBin in regionBins[iHisto]:
497  totalInRegion[iHisto] = totalInRegion[iHisto] + histo[iHisto].GetBinContent(iBin)
498 
499  sortedLB[iHisto] = [0] * nLB
500  for i in range(nLB):
501  totalInRegionRecomp[iHisto] = totalInRegionRecomp[iHisto] + nbHitInHot[iHisto][i]
502 
503  sortedLB[iHisto][i] = i
504  if (nbHitInHot[iHisto][i]>=args.minInLB):
505  suspiciousLBlist.append(i)
506  if (nbHitInHot[iHisto][i]>maxNbInHot):
507  maxNbInHot = nbHitInHot[iHisto][i]
508  maxNbInHot_histo = iHisto
509 
510  sortedLB[iHisto].sort(key=dict(zip(sortedLB[iHisto],nbHitInHot[iHisto])).get,reverse=True)
511  nLB_aboveThreshold = 0
512  for i in range(nLB):
513  if nbHitInHot[iHisto][sortedLB[iHisto][i]]>=args.minInLB:
514  nLB_aboveThreshold = nLB_aboveThreshold + 1
515  if not b_ValueNotEntries:
516  print("%d-LB: %d -> %d hits"%(i,sortedLB[iHisto][i],nbHitInHot[iHisto][sortedLB[iHisto][i]]))
517  else:
518  print("%d-LB: %d -> %.2f"%(i,sortedLB[iHisto][i],nbHitInHot[iHisto][sortedLB[iHisto][i]]))
519 
520  if not b_ValueNotEntries:
521  print("In the whole run, there are %d entries"%(totalInRegion[iHisto]))
522  if (totalInRegionRecomp[iHisto] != totalInRegion[iHisto]):
523  print("To be compared with %d entries cumulated from unmerged files"%(totalInRegionRecomp[iHisto]))
524  if (totalInRegionRecomp[iHisto] < totalInRegion[iHisto]):
525  print("This is normal only if you restricted the LB range...")
526  if (totalInRegionRecomp[iHisto] > totalInRegion[iHisto]):
527  print("This can be also caused by multiple processing, try to filter with -a option")
528  print("File path of the first file:",lbFilePathList[0])
529  else:
530  print("In the whole run, the value is %.2f"%(totalInRegion[iHisto]))
531 
532  affectedLB_forSummaryBinning = []
533  if (maxNbInHot != 0):
534  for i in range(35):
535  if (nbHitInHot[maxNbInHot_histo][sortedLB[maxNbInHot_histo][i]] > 0.05*maxNbInHot):
536  affectedLB_forSummaryBinning.append(sortedLB[maxNbInHot_histo][i])
537 
538 
541  leg = R.TLegend(0.855, 0.90-0.05*len(histoPath.keys()),
542  0.98, 0.9 )
543  leg.SetBorderSize(0)
544 
545  if (upperLB>=lowerLB): # check that at least one noisy LB was found
546  c0 = R.TCanvas("c0","Evolution vs LB",1400,550)
547  R.gStyle.SetOptStat("")
548  if histoType != "2d_xy_Occupancy":
549  c0.SetLogy(1)
550  c0.SetLeftMargin(.045)
551  c0.SetRightMargin(.15)
552  h0Evol = {}
553  first = True
554  for iHisto in histoPath.keys():
555  h0Evol[iHisto] = R.TH1I("h0Evol%s"%(iHisto),summaryTitle,upperLB-lowerLB+1,lowerLB-0.5,upperLB+0.5)
556  h0Evol[iHisto].SetXTitle("Run %d - LumiBlock (Only LB with >= %.0f entries)"%(args.runNumber,args.minInLB))
557  h0Evol[iHisto].SetLineColor(histoColor[iHisto])
558  h0Evol[iHisto].SetMarkerColor(histoColor[iHisto])
559  h0Evol[iHisto].SetMarkerStyle(20)
560  for i in range(lowerLB,upperLB+1):
561  h0Evol[iHisto].Fill(i,nbHitInHot[iHisto][i])
562 
563  if (h0Evol[iHisto].GetMaximum() >= args.minInLB):
564  leg.AddEntry(h0Evol[iHisto],"#splitline{%s}{(%d entries in the run)}"%(histoLegend[iHisto],totalInRegion[iHisto]))
565 
566  if first:
567  h0Evol[iHisto].Draw("P HIST")
568  if histoType != "2d_xy_Occupancy":
569  h0Evol[iHisto].SetMinimum(args.minInLB-0.8)
570  h0Evol[iHisto].SetMaximum(maxNbInHot*1.5)
571  first = False
572  else:
573  h0Evol[iHisto].Draw("PSAME HIST")
574  leg.Draw()
575  c0.Update()
576 
577 
578  leg2 = R.TLegend(0.855, 0.90-0.05*len(histoPath.keys()),
579  0.98, 0.9 )
580  leg2.SetBorderSize(0)
581 
582  h_affectedLB = {}
583 
584  print("Affected luminosity blocks sorted by the noise amplitude",affectedLB_forSummaryBinning)
585 
586  if (len(affectedLB_forSummaryBinning)>0):
587  c0_2 = R.TCanvas("c0_2","Most affected LB summary", 1400,550)
588  R.gStyle.SetOptStat("")
589  if histoType != "2d_xy_Occupancy":
590  c0_2.SetLogy(1)
591  c0_2.SetLeftMargin(.045)
592  c0_2.SetRightMargin(.15)
593 
594  onlineLumi = GetOnlineLumiFromCOOL(args.runNumber,0)
595  cumulatedAffectedLumi = 0.
596 
597  first = True
598  for iHisto in histoPath.keys():
599  h_affectedLB[iHisto] = R.TH1F("affectedLB%s"%(iHisto),"%s - Most affected LB"%summaryTitle,len(affectedLB_forSummaryBinning),0.5,len(affectedLB_forSummaryBinning)+0.5)
600 
601  h_affectedLB[iHisto].SetXTitle("Run %d - LumiBlock / Cumulated luminosity in pb-1"%(args.runNumber))
602  h_affectedLB[iHisto].SetLineColor(histoColor[iHisto])
603  h_affectedLB[iHisto].SetMarkerColor(histoColor[iHisto])
604  h_affectedLB[iHisto].SetMarkerStyle(20)
605 
606  for i in range(1,len(affectedLB_forSummaryBinning)+1):
607  cumulatedAffectedLumi = cumulatedAffectedLumi + onlineLumi[affectedLB_forSummaryBinning[i-1]]*60/1e6
608  h_affectedLB[iHisto].GetXaxis().SetBinLabel(i,"%d / %.1f"%(affectedLB_forSummaryBinning[i-1],cumulatedAffectedLumi))
609  h_affectedLB[iHisto].GetXaxis().SetTitleOffset(1.4)
610  h_affectedLB[iHisto].Fill(i,nbHitInHot[iHisto][affectedLB_forSummaryBinning[i-1]])
611 
612  if (h_affectedLB[iHisto].GetMaximum() >= args.minInLB):
613  leg2.AddEntry(h_affectedLB[iHisto],"#splitline{%s}{(%d entries in the run)}"%(histoLegend[iHisto],totalInRegion[iHisto]))
614 
615  if first:
616  h_affectedLB[iHisto].Draw("P HIST")
617  if histoType != "2d_xy_Occupancy":
618  h_affectedLB[iHisto].SetMinimum(args.minInLB-0.8)
619  h_affectedLB[iHisto].SetMaximum(maxNbInHot*1.5)
620  first = False
621  else:
622  h_affectedLB[iHisto].Draw("PSAME HIST")
623 
624  leg2.Draw()
625 
626  c0_2.SetGridx()
627  c0_2.Update()
628 
629  print("WARNING: only the 35 most affected LB are displayed in the summary plot")
630 
631 
632  if args.defectQuery:
633  print("I am looking for LAr/Tile/Calo defects defined for the suspicious LB")
634  from DQDefects import DefectsDB
635  db = DefectsDB()
636  defectList = [d for d in (db.defect_names | db.virtual_defect_names) if ((d.startswith("LAR") and "SEV" in d) or (d.startswith("TILE")) or (d.startswith("CALO")))]
637  defects = db.retrieve((args.runNumber, 1), (args.runNumber+1, 0), defectList)
638  for iDef in defects:
639  associatedSuspicious = False
640  for iLB in range(iDef.since.lumi,iDef.until.lumi):
641  if iLB in suspiciousLBlist:
642  associatedSuspicious = True
643  if associatedSuspicious:
644  if (iDef.since.lumi == iDef.until.lumi-1):
645  print("%s: %d set by %s - %s"%(iDef.channel,iDef.since.lumi,iDef.user,iDef.comment))
646  else:
647  print("%s: %d->%d set by %s - %s"%(iDef.channel,iDef.since.lumi,iDef.until.lumi-1,iDef.user,iDef.comment))
648 
649  input("Please press the Enter key to proceed")
650 
651  sys.exit()
652 
653 
655 if __name__ == "__main__":
656  R.gStyle.SetPalette(1)
657  R.gStyle.SetOptStat("em")
658  # command-line arguments
659  parser = argparse.ArgumentParser(description='Process some integers.')
660  parser.add_argument('-r','--run',type=int,dest='runNumber',default='267599',help="Run number",action='store')
661  parser.add_argument('-ll','--lowerlb',type=int,dest='lowerLumiBlock',default='0',help="Lower lb",action='store')
662  parser.add_argument('-ul','--upperlb',type=int,dest='upperLumiBlock',default='999999',help="Upper lb",action='store')
663  parser.add_argument('-s','--stream',dest='stream',default='Main',help="Stream with or without prefix: express/CosmicCalo/Main/ZeroBias/MinBias",action='store')
664  parser.add_argument('-t','--tag',dest='tag',default='',help="DAQ tag: data16_13TeV, data16_cos... By default retrieve it via atlasdqm",action='store')
665  parser.add_argument('-a','--amiTag',dest='amiTag',default='f',help="First letter of AMI tag: x->express / f->bulk",action='store')
666  parser.add_argument('-e','--eta',type=float,dest='etaSpot',default='-999.',help='Eta of hot spot',action='store')
667  parser.add_argument('-p','--phi',type=float,dest='phiSpot',default='-999.',help='Phi of hot spot',action='store')
668  parser.add_argument('-x','--x',type=float,dest='xSpot',default='-999.',help='X of hot spot',action='store')
669  parser.add_argument('-y','--y',type=float,dest='ySpot',default='-999.',help='Y of hot spot',action='store')
670  parser.add_argument('-ia','--integralAbove',type=float,dest='integralAbove',default='-999.',help='Lower bound of integral',action='store')
671  parser.add_argument('-d','--delta',type=float,dest='deltaSpot',default='0.1',help='Distance to look around hot spot',action='store')
672  parser.add_argument('-o','--object',dest='objectType',default='TopoClusters',help='2D OCCUPANCY: TopoClusters,EMTopoClusters,\n EMTopoJets,TightFwdElectrons,Tau \n1D OCCUPANCY: EMTopoJets_eta,Tau_eta,Tau_phi \nINTEGRAL : NumberTau,NumberTightFwdElectrons,NumberHLTJet',action='store')
673  parser.add_argument('-m','--min',type=float,dest='minInLB',default='5',help='Min number of occurences in a LB',action='store')
674  parser.add_argument('-g','--grl',dest='defectQuery',help='Look for Calo/LAr/Tile defects set in suspicious LBs',action='store_true')
675 
676  args = parser.parse_args()
677 
678  if args.tag == "":
679  # Try to retrieve the data project tag via atlasdqm
680  if (not os.path.isfile("atlasdqmpass.txt")):
681  print("To retrieve the data project tag, you need to generate an atlasdqm key and store it in this directory as atlasdqmpass.txt (yourname:key)")
682  print("To generate a key, go here : https://atlasdqm.cern.ch/dqauth/")
683  print("You can also define by hand the data project tag wit hthe option -t")
684  sys.exit()
685  passfile = open("atlasdqmpass.txt")
686  passwd = passfile.read().strip(); passfile.close()
687  passurl = 'https://%s@atlasdqm.cern.ch'%passwd
688  s = xmlrpclib.ServerProxy(passurl)
689  run_spec = {'stream': 'physics_CosmicCalo', 'proc_ver': 1,'source': 'tier0', 'low_run': args.runNumber, 'high_run':args.runNumber}
690  run_info= s.get_run_information(run_spec)
691  if '%d'%args.runNumber not in run_info.keys() or len(run_info['%d'%args.runNumber])<2:
692  print("Unable to retrieve the data project tag via atlasdqm... Please double check your atlasdqmpass.txt or define it by hand with -t option")
693  sys.exit()
694  args.tag = run_info['%d'%args.runNumber][1]
695 
696 
697  # parser.print_help()
698  main(args)
max
#define max(a, b)
Definition: cfImp.cxx:41
hotSpotInHIST.int
int
Definition: hotSpotInHIST.py:660
index
Definition: index.py:1
RootHelpers::FindBin
Int_t FindBin(const TAxis *axis, const double x)
Definition: RootHelpers.cxx:14
dumpHVPathFromNtuple.append
bool append
Definition: dumpHVPathFromNtuple.py:91
hotSpotInHIST.main
def main(args)
Definition: hotSpotInHIST.py:218
Get
T * Get(TFile &f, const std::string &n, const std::string &dir="", const chainmap_t *chainmap=0, std::vector< std::string > *saved=0)
get a histogram given a path, and an optional initial directory if histogram is not found,...
Definition: comparitor.cxx:178
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
Trk::open
@ open
Definition: BinningType.h:40
hotSpotInHIST.getHistoInfo
def getHistoInfo(objectType, runNumber)
Definition: hotSpotInHIST.py:31
str
Definition: BTagTrackIpAccessor.cxx:11
dbg::print
void print(std::FILE *stream, std::format_string< Args... > fmt, Args &&... args)
Definition: SGImplSvc.cxx:70
hotSpotInHIST.lbStr
def lbStr(lb)
Definition: hotSpotInHIST.py:27
Trk::split
@ split
Definition: LayerMaterialProperties.h:38