ATLAS Offline Software
checkCorrelInHIST.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 correlate the number of entries in a region defined by (x;y,delta) arguments
4 # Uses the pathExtract library to extract the EOS path
5 # See the twiki: https://twiki.cern.ch/twiki/bin/viewauth/Atlas/UsingDQInframerge
6 # Author : Benjamin Trocme (LPSC Grenoble) / 2017
7 
8 import os, sys
9 import argparse
10 import xmlrpc.client
11 from DataQualityUtils import pathExtract
12 import ctypes
13 import sqlite3
14 
15 
16 import ROOT as R
17 
18 R.gStyle.SetPalette(1)
19 R.gStyle.SetOptStat("em")
20 
21 nLB = 8000
22 
23 dqmpassfile="/afs/cern.ch/user/l/larmon/public/atlasdqmpass.txt"
24 
25 conn = None
26 cursor = None
27 
28 # Some definitions for wildcards which can be used for input plot lists
29 wildcards = {}
30 wildcardplots = ["CellOccupancyVsEtaPhi", "fractionOverQthVsEtaPhi","DatabaseNoiseVsEtaPhi","CellAvgEnergyVsEtaPhi"]
31 
32 for plot in wildcardplots:
33  wildcards[plot] = {}
34  wildcards[plot]["EMB"] = { "P":"Presampler","1":"Sampling1","2":"Sampling2","3":"Sampling3"}
35  wildcards[plot]["EMEC"] = { "P":"Presampler","1":"Sampling1","2":"Sampling2","3":"Sampling3"}
36  wildcards[plot]["HEC"] = { "0":"Sampling0","1":"Sampling1","2":"Sampling2","3":"Sampling3"}
37  wildcards[plot]["FCAL"] = { "1":"Sampling1","2":"Sampling2","3":"Sampling3"}
38 
39 # e.g. Tile/Cell/AnyPhysTrig/TileCellEneEtaPhi_SampB_AnyPhysTrig
40 # e.g. Tile/Cell/AnyPhysTrig/TileCellEtaPhiOvThr_SampB_AnyPhysTrig
41 wildcards["TileCellEneEtaPhi"] = [ "A", "B", "D", "E" ]
42 wildcards["TileCellEtaPhiOvThr"] = [ "A", "B", "D", "E" ]
43 
44 def expandWildCard(histlist):
45  newhistlist = []
46  grouped = {} # document the grouped plots, so we can show in one canvas
47  for hist in histlist:
48  if "*" in hist:
49  foundwc = False
50  for wc in wildcards.keys():
51  if wc in hist:
52  foundwc = True
53  newpaths = []
54  if "Tile" in wc:
55  for samp in wildcards[wc]:
56  tmp_path = hist
57  new_path = tmp_path.replace("*",samp)
58  newpaths.append(new_path)
59  else:
60  for part in wildcards[wc].keys():
61  tmp_path = hist
62  if part+"*" in tmp_path:
63  for samp in wildcards[wc][part].keys():
64 
65  new_path = tmp_path.replace(part+"*", part+samp)
66 
67  if "*" in new_path:
68  new_path = new_path.replace("*", wildcards[wc][part][samp])
69  newpaths.append(new_path)
70 
71  if len(newpaths) == 0:
72  print("Failed to get the full paths from the wildcard...")
73  sys.exit()
74 
75  print("Expanded",wc,"wildcard to give",len(newpaths),"histograms")
76  newhistlist.extend(newpaths)
77  if foundwc is False:
78  print("A wildcard has been used, but the requested histogram is not yet defined in this script. See the wildcards dictionary:",wildcards.keys())
79  sys.exit()
80  grouped[hist] = newpaths
81  else:
82  newhistlist.append(hist)
83  return newhistlist, grouped
84 
85 
86 def convHname(hname):
87  DET = { "EMB":"0", "EMEC":"1","HEC":"2","FCAL":"3" }
88  AC = { "A":"1", "C":"-1" }
89  SAM = { "P":"0" }
90  for samp in range(0,4): SAM[str(samp)] = str(samp)
91  for det in DET.keys():
92  for sam in SAM.keys():
93  for ac in AC.keys():
94  if det+sam+ac in hname:
95  return DET[det], AC[ac], SAM[sam]
96  return None, None, None
97 
98 def LIDProposal(hname, eta, phi, delta=0.15):
99  """ Print a proposed LArID translator (https://atlas-larmon.cern.ch/LArIdtranslator/) SQL query """
100  det, ac, sam = convHname(hname)
101  if det is None: return
102  if int(det) == 0 and abs(eta) > 1.4 and int(sam)>1:
103  sam = str(int(sam)-1)
104  proposal = "DET="+det+" and AC="+ac+" and SAM="+sam+" and ETA between "+str(eta-delta)+" and "+str(eta+delta)+" and PHI between "+str(phi-delta)+" and "+str(phi+delta)
105  print("*"*30)
106  print("Proposal query for LArID translator for plot",hname,"is as follows:")
107  print(proposal)
108 
109 
111  """ Connect to the atlasDQM web API service: https://twiki.cern.ch/twiki/bin/viewauth/Atlas/DQWebServiceAPIs """
112  if (not os.path.isfile(dqmpassfile)):
113  print("To connect to the DQ web service APIs, you need to generate an atlasdqm key and store it in the specified location ("+dqmpassfile+"). The contents should be yourname:key")
114  print("To generate a key, go here : https://atlasdqm.cern.ch/dqauth/")
115  sys.exit()
116  passfile = open(dqmpassfile)
117  passwd = passfile.read().strip(); passfile.close()
118  passurl = 'https://%s@atlasdqm.cern.ch'%passwd
119  s = xmlrpc.client.ServerProxy(passurl)
120  return s
121 
122 def lbStr(lb):
123  """ Return the lb number in string format, e.g. _lb0001 """
124  return "_lb"+str(lb).zfill(4)
125 
126 def hType(hist, verbose=False):
127  """ Return type of the provided hist as a string, or None if it's not a hist """
128  if isinstance(hist,R.TH2):
129  return "2D"
130  elif isinstance(hist,R.TH1):
131  return "1D"
132  else:
133  if verbose:
134  print("The input hist is not TH1/TH2... it is",type(hist),"- returning None")
135  return None
136 
137 
138 def checkCorrel(histos, listLB, checkList):
139  # Dump the correlations in histograms to be displayed
140  cRatio = {}
141  paveCorrel = {}
142 
143  correls = {}
144 
145  fractionNonZero = 0
146  for iPath in histos.keys():
147  for iPath2 in histos.keys():
148  corr = "%s_%s"%(iPath,iPath2)
149  corr2 = "%s_%s"%(iPath2,iPath)
150  if not any([ cl in iPath for cl in checkList]) and not any([cl in iPath2 for cl in checkList]):
151  print("Skipping comparison of",iPath,"vs",iPath2)
152  if corr in correls.keys(): del correls[corr]
153  if corr2 in correls.keys(): del correls[corr2]
154  continue
155  print("Checking correl for",iPath,"vs",iPath2)
156  if corr not in correls.keys(): correls[corr] = {}
157  if corr2 not in correls.keys(): correls[corr2] = {}
158  if (iPath != iPath2 and "hCorrel" not in correls[corr2].keys()): # Correlation plots
159  print("====== I am checking correlation between %s and %s"%(iPath.split("/")[-1],iPath2.split("/")[-1]))
160  correls[corr]["hCorrel"] = R.TH2D( "Correlation_%s"%corr,"Correlation_%s"%corr,
161  50, min(histos[iPath]["nbHitInHot"])-1, max(histos[iPath]["nbHitInHot"])+1,
162  50, min(histos[iPath2]["nbHitInHot"])-1, max(histos[iPath2]["nbHitInHot"])+1 )
163  correls[corr]["hCorrel"].SetXTitle(iPath.split("/")[-1])
164  correls[corr]["hCorrel"].SetYTitle(iPath2.split("/")[-1])
165 
166  correls[corr]["nbHitRatio"] = [-999.]*nLB
167  correls[corr2]["nbHitRatio"] = [-999.]*nLB
168  for iLB in listLB:
169  if (histos[iPath2]["nbHitInHot"][iLB] !=0):
170  correls[corr]["nbHitRatio"][iLB] = histos[iPath]["nbHitInHot"][iLB]/histos[iPath2]["nbHitInHot"][iLB]
171  if (histos[iPath]["nbHitInHot"][iLB] !=0):
172  correls[corr2]["nbHitRatio"][iLB] = histos[iPath2]["nbHitInHot"][iLB]/histos[iPath]["nbHitInHot"][iLB]
173 
174  correls[corr]["hRatio"] = R.TH1D("Ratio_%s"%corr,"Ratio_%s"%corr,100,0.,max(correls[corr]["nbHitRatio"])+1)
175  correls[corr]["hRatio"].SetXTitle("%s/%s"%(iPath.split("/")[-1],iPath2.split("/")[-1]))
176  correls[corr]["hRatio"].SetMarkerColor(R.kBlue+2)
177  correls[corr]["hRatio"].SetMarkerStyle(20)
178  correls[corr2]["hRatio"] = R.TH1D("Ratio_%s"%corr2,"Ratio_%s"%corr2,100,0.,max(correls[corr2]["nbHitRatio"])+1)
179  correls[corr2]["hRatio"].SetXTitle("%s/%s"%(iPath2.split("/")[-1],iPath.split("/")[-1]))
180  correls[corr2]["hRatio"].SetMarkerColor(R.kBlue+2)
181  correls[corr2]["hRatio"].SetMarkerStyle(20)
182 
183  for iLB in listLB:
184  if (histos[iPath]["nbHitInHot"][iLB] !=0 or histos[iPath2]["nbHitInHot"][iLB] != 0.):
185  correls[corr]["hCorrel"].Fill(histos[iPath]["nbHitInHot"][iLB],histos[iPath2]["nbHitInHot"][iLB])
186  print("LB: %d -> %.2f / %.2f"%(iLB,histos[iPath]["nbHitInHot"][iLB],histos[iPath2]["nbHitInHot"][iLB]))
187  if correls[corr]["nbHitRatio"][iLB]!= -999:
188  correls[corr]["hRatio"].Fill(correls[corr]["nbHitRatio"][iLB])
189  if correls[corr2]["nbHitRatio"][iLB]!= -999:
190  correls[corr2]["hRatio"].Fill(correls[corr2]["nbHitRatio"][iLB])
191 
192  correls[corr]["cCorrel"] = R.TCanvas("Correl-%s"%corr,"Correl-%s"%corr)
193  correls[corr]["hCorrel"].Draw("COLZ")
194  paveCorrel[corr] = R.TPaveText(.1,.72,.9,.9,"NDC")
195  paveCorrel[corr].SetFillColor(R.kBlue-10)
196  paveCorrel[corr].AddText("Run %d / %d LBs in total - %d LBs with >=1 entry in either plot"%(args.runNumber,len(listLB),correls[corr]["hCorrel"].GetEntries()))
197  paveCorrel[corr].AddText("Correlation factor:%.3f"%(correls[corr]["hCorrel"].GetCorrelationFactor()))
198 
199  try:
200  fractionNonZero = correls[corr]["hRatio"].Integral(2,100)/correls[corr]["hRatio"].Integral(1,100)
201  except ZeroDivisionError:
202  fractionNonZero = 0
203  if fractionNonZero != 0.:
204  meanNonZero = correls[corr]["hRatio"].GetMean()/fractionNonZero
205  else:
206  meanNonZero = 0.
207  paveCorrel[corr].AddText("When >=1 entry in X plot(%d LBs), %.0f %% events with >=1 entry in Y plot(<ratio>=%.2f)"%(correls[corr]["hRatio"].Integral(1,100),fractionNonZero*100.,meanNonZero))
208  try:
209  fractionNonZero = correls[corr2]["hRatio"].Integral(2,100)/correls[corr2]["hRatio"].Integral(1,100)
210  except ZeroDivisionError:
211  fractionNonZero = 0
212  if fractionNonZero != 0.:
213  meanNonZero = correls[corr2]["hRatio"].GetMean()/fractionNonZero
214  else:
215  meanNonZero = 0.
216  paveCorrel[corr].AddText("When >=1 entry in Y plot(%d LBs), %.0f %% events with >=1 entry in X plot(<ratio>=%.2f)"%(correls[corr2]["hRatio"].Integral(1,100),fractionNonZero*100.,meanNonZero))
217  paveCorrel[corr].Draw()
218 
219  if args.draw1D:
220  correls[corr]["cRatio"] = R.TCanvas("Ratio-%s"%corr,"Ratio-%s"%corr)
221  correls[corr]["hRatio"].Draw("P HIST")
222  correls[corr2]["cRatio"] = R.TCanvas("Ratio-%s"%corr2,"Ratio-%s"%corr2)
223  correls[corr2]["hRatio"].Draw("P HIST")
224 
225  correls[corr]["cCorrel"].Update() # make sure all of the text is there
226 
227  elif ("hEvol" not in histos[iPath].keys()): # Evolution of nb of hit per LB
228  histos[iPath]["hEvol"] = R.TH1D("Evolution_%s"%iPath,"%s"%(iPath.split("/")[-1]),max(listLB)-min(listLB),min(listLB),max(listLB))
229  histos[iPath]["hEvol"].SetXTitle("Luminosity block")
230  histos[iPath]["hEvol"].SetYTitle("Nb of hits")
231  histos[iPath]["hEvol"].SetMarkerColor(R.kGreen+2)
232  histos[iPath]["hEvol"].SetMarkerStyle(20)
233 
234  for iLB in listLB:
235  histos[iPath]["hEvol"].Fill(iLB,histos[iPath]["nbHitInHot"][iLB])
236 
237  if args.draw1D:
238  histos[iPath]["cEvol"] = R.TCanvas("LB evol - %s"%iPath)
239  histos[iPath]["hEvol"].Draw("P HIST")
240 
241  return correls, fractionNonZero
242 
243 def getSummary(histos, correls, fractionNonZero):
244  print("====== Summary data")
245  already = []
246  for iPath in histos.keys():
247  for iPath2 in histos.keys():
248  corr = "%s_%s"%(iPath,iPath2)
249  corr2 = "%s_%s"%(iPath2,iPath)
250  if corr not in correls.keys() and corr2 not in correls.keys():
251  continue
252  if (iPath != iPath2 and corr2 not in already): # Correlation plots
253  print("====== %s vs %s"%(iPath.split("/")[-1],iPath2.split("/")[-1]))
254  print("Correlation factor: %.3f"%(correls[corr]["hCorrel"].GetCorrelationFactor()))
255  try:
256  fractionNonZero = correls[corr]["hRatio"].Integral(2,100)/correls[corr]["hRatio"].Integral(1,100)
257  except ZeroDivisionError:
258  fractionNonZero = 0
259  if fractionNonZero != 0.:
260  meanNonZero = correls[corr]["hRatio"].GetMean()/fractionNonZero
261  else:
262  meanNonZero = 0.
263  print("When there is at least one entry in %s (%d LBs), there are %.1f %% of events with an entry in %s - Mean ratio: %.2f"%(iPath2.split("/")[-1],correls[corr]["hRatio"].Integral(1,100),fractionNonZero*100.,iPath.split("/")[-1],meanNonZero))
264 
265  try:
266  fractionNonZero = correls[corr2]["hRatio"].Integral(2,100)/correls[corr2]["hRatio"].Integral(1,100)
267  except ZeroDivisionError:
268  fractionNonZero = 0
269  if fractionNonZero != 0.:
270  meanNonZero = correls[corr2]["hRatio"].GetMean()/fractionNonZero
271  else:
272  meanNonZero = 0.
273  print("When there is at least one entry in %s (%d LBs), there are %.1f %% of events with an entry in %s - Mean ratio: %.2f"%(iPath.split("/")[-1],correls[corr2]["hRatio"].Integral(1,100),fractionNonZero*100.,iPath2.split("/")[-1],meanNonZero))
274 
275  already.append(corr)
276 
277 
278 def topNBins(histname,h,topn,bins,h_fracQth=None):
279  content = []
280  binx = []
281  biny = []
282  fracQthContent = []
283  for nb in bins:
284  x, y, z = ctypes.c_int(1), ctypes.c_int(1), ctypes.c_int(1)
285  h.GetBinXYZ(nb, x, y, z)
286  c = h.GetBinContent(nb)
287  xcent = h.GetXaxis().GetBinCenter(x.value)
288  xlow = h.GetXaxis().GetBinLowEdge(x.value)
289  xhi = h.GetXaxis().GetBinUpEdge(x.value)
290  ycent = h.GetYaxis().GetBinCenter(y.value)
291  ylow = h.GetYaxis().GetBinLowEdge(y.value)
292  yhi = h.GetYaxis().GetBinUpEdge(y.value)
293  content.append(c)
294  if h_fracQth is not None and isinstance(h_fracQth, R.TH1):
295  fracQthContent.append(h_fracQth.GetBinContent(nb))
296  else:
297  fracQthContent.append(0)
298  binx.append( [xlow,xcent,xhi] )
299  biny.append( [ylow,ycent,yhi] )
300  # hottest bins
301  top = sorted(range(len(content)), key=lambda i: content[i], reverse=True)[:topn]
302  top = [ t for t in top if content[t] != 0 ]
303  if len(top) == 0: return
304  print("*"*30)
305  print("**",len(top),"hottest bins in",h.GetName(),"**")
306  det, ac, sam = convHname(h.GetName())
307 
308  if det is not None:
309  proposal = "DET="+det+" and AC="+ac+" and SAM="+sam+" and"
310  else:
311  proposal = ""
312  for ind in top:
313  # Special treatment for barrel
314  thisprop = proposal
315  if det is not None and int(det) == 0:
316  if (abs(binx[ind][0]) > 1.4 or abs(binx[ind][2]) > 1.4) and int(sam)>1:
317  thissam = str(int(sam)-1)
318  thisprop = thisprop.replace("SAM="+sam, "SAM="+thissam)
319  printstr = thisprop+" ETA between "+str(format(binx[ind][0],".4f"))+" and "+str(format(binx[ind][2],".4f"))+" and PHI between "+str(format(biny[ind][0],".4f"))+" and "+str(format(biny[ind][2],".4f"))
320 
321  ONL_ID = []
322  if "LArCellMon" in histname:
323  conn = sqlite3.connect('/afs/cern.ch/user/l/larmon/public/prod/LArIdtranslator/LArId.db')
324  conn.row_factory = sqlite3.Row
325  cursor = conn.cursor()
326  cmd = 'select distinct LARID.ONL_ID from LARID where '
327  cmd += printstr.replace("DET","LARID.DET").replace("SAM","LARID.SAM").replace("ETA","LARID.ETA").replace("PHI","LARID.PHI")
328  cursor.execute(cmd)
329  all_row = cursor.fetchall()
330  ONL_ID=[hex(all_row[i]['ONL_ID']) for i in range(len(all_row))]
331 
332 
333 
334  printstr += " (content = "+str(content[ind])
335  if h_fracQth is not None:
336  printstr += " & /Qth = "+str(format(fracQthContent[ind],".3f"))
337  printstr += ")"
338  if len(ONL_ID) != 0:
339  printstr += " ONL_ID = "+(", ".join(ONL_ID))
340  print(printstr)
341 
342 
343 if __name__ == "__main__":
344  parser = argparse.ArgumentParser(description='Process some integers.')
345  parser.add_argument('-r','--run',type=int,dest='runNumber',default='267599',help="Run number",action='store')
346  parser.add_argument('-ll','--lowerlb',type=int,dest='lowerlb',default='0',help="Lower lb",action='store')
347  parser.add_argument('-ul','--upperlb',type=int,dest='upperlb',default='999999',help="Upper lb",action='store')
348  parser.add_argument('-s','--stream',dest='stream',default='Main',help="Stream with or without prefix: express/CosmicCalo/Main/ZeroBias/MinBias",action='store')
349  parser.add_argument('-t','--tag',dest='tag',default='',help="DAQ tag: data16_13TeV, data16_cos...By default retrieve it via atlasdqm",action='store')
350  parser.add_argument('-a','--amiTag',dest='amiTag',default='f',help="First letter of AMI tag: x->express / f->bulk",action='store')
351  parser.add_argument('-x','--globalX',type=float,dest='globalX',default='-999.',help='X region common to all histos',action='store')
352  parser.add_argument('-y','--globalY',type=float,dest='globalY',default='-999.',help='Y region common to all histos - Only for 2d',action='store')
353  parser.add_argument('-ia','--integralAbove',type=float,dest='integralAbove',default='-999.',help='Lower bound of integral - Not used so far',action='store')
354  parser.add_argument('-d','--globalDelta',type=float,dest='globalDelta',default='0.15',help='Distance to look around x/(x;y) for 1d/2d plot',action='store')
355  parser.add_argument('--histo',dest='histo',default='',help='ROOT-file path of histograms - As many as you want with : [type("1d" or "2d")] [root path] [x] [y if 2d] [delta] (if not provided use global)',action='store',nargs="*")
356  parser.add_argument('--histoWD',dest='histoWD',default='',help='Webdisplay path of histograms - As many as you want with : [type("1d" or "2d")] [root path] [x] [y if 2d] [delta] (if not provided use global)',action='store',nargs="*")
357  parser.add_argument('--onlyBoxes', dest='onlyBoxes', default=False, action='store_true', help="Only show the histograms with the box around the target area - don't do the correlation analysis")
358  parser.add_argument('--draw1D', dest='draw1D', default=False, action='store_true', help="Also draw the 1D correlation plots")
359  parser.add_argument('-n','--topN', dest='topN', type=int, default=4, help="Report the N bins with the highest content")
360  parser.add_argument('--checkCorr', dest='checkCorr', nargs='*', default = [ 'CaloTopoClusters' ], help="Only check the full per-LB correlation for combinations of plots where one of the plots contains this substring. As many as you want")
361  args = parser.parse_args()
362 
363  # Info for the DQM APIs... if we are using them
364  run_spec = {'stream': 'physics_CosmicCalo', 'proc_ver': 1,'source': 'tier0', 'low_run': args.runNumber, 'high_run':args.runNumber}
365 
366  dqmAPI = None
367 
368  grouped = {}
369 
370  if args.tag == "": # Try to retrieve the data project tag via atlasdqm
371  dqmAPI = setupDqmAPI()
372  run_info= dqmAPI.get_run_information(run_spec)
373  if '%d'%args.runNumber not in list(run_info.keys()) or len(run_info['%d'%args.runNumber])<2:
374  print("Unable to retrieve the data project tag via atlasdqm... Please double check your atlasdqmpass.txt or define it by hand with -t option")
375  sys.exit()
376  args.tag = run_info['%d'%args.runNumber][1]
377 
378 
379  if len(args.histo) > 0: # The histograms ROOT file paths are directly provided
380  hArgs = args.histo
381  for h in hArgs:
382  if "*" in h:
383  print("A wildcard was passed for histogram name input - this is not yet supported. Perhaps you meant to use the histoWD option?")
384  sys.exit()
385  elif len(args.histoWD) > 0: # The histograms paths are provided as webdisplay paths
386  print("Web display paths provided: I will have to retrieve the ROOT file path of histograms")
387  args.histoWD, grouped = expandWildCard(args.histoWD)
388 
389  if dqmAPI is None:
390  dqmAPI = setupDqmAPI()
391  prefix = {'express':'express_','Egamma':'physics_','CosmicCalo':'physics_','JetTauEtmiss':'physics_','Main':'physics_','ZeroBias':'physics_','MinBias':'physics_'}
392  run_spec['stream'] = "%s%s"%(prefix[args.stream],args.stream)
393  hArgs = []
394  for hist in args.histoWD:
395  dqmf_config = dqmAPI.get_dqmf_configs(run_spec, hist)
396  if len(dqmf_config.keys())== 0:
397  print("Problem getting hist path from the provided WD string... is there a typo? You submitted",hist)
398  print("Note - if you see two strings here perhaps you had a misplaced quote in your input arguments")
399  sys.exit()
400  histpath = dqmf_config['%d'%args.runNumber]['annotations']['inputname']
401  hArgs.append(histpath)
402  if hist in [ val for k,v in grouped.items() for val in v ]:
403  gk = [ k for k,b in grouped.items() if hist in grouped[k] ][0]
404  gi = grouped[gk].index(hist)
405  grouped[gk][gi] = histpath
406  else:
407  print("You need to define at least 1 histogram...")
408  sys.exit()
409 
410 
411  print("Requested histograms are",hArgs)
412 
413  histos = {}
414  canvs = {}
415  for h in hArgs:
416  # Print a proposed LArID translator SQL query
417  # LIDProposal(h, args.globalX, args.globalY, args.globalDelta)
418  histos[h] = {}
419  canvs[h] = {}
420 
421  for hist in histos.keys():
422  histos[hist]["nbHitInHot"] = [0.] * nLB
423  histos[hist]["regionBins"] = []
424 
425  print("Finding the path to the merged hist file")
426  mergedFilePath = pathExtract.returnEosHistPath( args.runNumber,
427  args.stream, args.amiTag,
428  args.tag )
429  runFilePath = "root://eosatlas.cern.ch/%s"%(mergedFilePath).rstrip()
430  if ("FILE NOT FOUND" in runFilePath):
431  print("No merged file found for this run")
432  print("pathExtract.returnEosHistPath( "+str(args.runNumber)+", "+str( args.stream)+", "+str(args.amiTag)+", "+str(args.tag)+" )")
433  print("HINT: check if there is a folder like","/eos/atlas/atlastier0/rucio/"+args.tag+"/physics_"+args.stream+"/00"+str(args.runNumber)+"/"+args.tag+".00"+str(args.runNumber)+".physics_"+args.stream+".*."+args.amiTag)
434  else:
435  print("I have found the merged HIST file %s"%(runFilePath))
436  drawngroup = {}
437  print("Opening the merged hist file and getting some information")
438  f = R.TFile.Open(runFilePath)
439  print("File is",runFilePath)
440  for hist in histos.keys():
441  hpath = "run_%d/%s"%(args.runNumber,hist)
442  print("Reading histogram",hpath)
443  histos[hist]["merged"] = f.Get(hpath)
444  if not isinstance(histos[hist]["merged"], R.TH1) and not isinstance(histos[hist]["merged"], R.TH2):
445  print("WARNING: path",hpath,"was not found in merged file")
446  continue
447  histos[hist]["type"] = hType(histos[hist]["merged"])
448  histos[hist]["min"] = histos[hist]["merged"].GetMinimum()*0.8
449  histos[hist]["max"] = histos[hist]["merged"].GetMaximum()*1.2
450  histos[hist]["merged"].SetMinimum(histos[hist]["min"])
451  histos[hist]["merged"].SetMaximum(histos[hist]["max"])
452 
453 
454  # here, find another way to define x y delta?
455  tmp_x = args.globalX
456  tmp_delta = args.globalDelta
457  # steps for iterating over bins in the scan
458  nSteps = 1000
459  subStep = 2*tmp_delta/nSteps
460 
461  groupname = None
462  if hist in [ val for k,v in grouped.items() for val in v ]:
463  groupname = [ k for k,b in grouped.items() if hist in grouped[k] ][0]
464  if groupname not in canvs.keys():
465  canvs[groupname] = R.TCanvas(groupname.replace("*","x"), groupname.replace("*","x"), 400*len(grouped[groupname]), 400)
466  drawngroup[groupname] = 1
467  if len(grouped[groupname]) <6:
468  canvs[groupname].Divide(len(grouped[groupname]),1)
469  print("dividing canvas", len(grouped[groupname]))
470  else:
471  print("Too many plots in the wildcard", groupname, len(grouped[groupname]))
472  groupname = None
473 
474  if groupname is None:
475  canvs[hist]["canv"] = R.TCanvas(hist, hist)
476  thiscanv = canvs[hist]["canv"]
477  else:
478  thiscanv = canvs[groupname]
479  thiscanv.cd(drawngroup[groupname])
480 
481  if histos[hist]["type"] == "1d":
482  histos[hist]["merged"].Draw()
483  histos[hist]["box"] = R.TBox( tmp_x-tmp_delta,
484  histos[hist]["min"],
485  tmp_x+tmp_delta,
486  histos[hist]["max"] )
487  # Extract the list of bins where to count.
488  # Scans the window to find all bins that fall in the window
489  # The regionBins is defined for each histogram allowing different binning
490  for ix in range(nSteps):
491  iX = tmp_x - tmp_delta + ix * subStep
492  tmp_bin = histos[hist]["merged"].FindBin(iX)
493  if (tmp_bin not in histos[hist]["regionBins"]):
494  histos[hist]["regionBins"].append(tmp_bin)
495  else: # 2D hist
496  tmp_y = args.globalY
497  R.gPad.SetLogz(1)
498  R.gStyle.SetPalette(1)
499  R.gStyle.SetOptStat("")
500  print("Draw",hist)
501  histos[hist]["merged"].Draw("COLZ")
502  histos[hist]["box"] = R.TBox( tmp_x-tmp_delta,
503  tmp_y-tmp_delta,
504  tmp_x+tmp_delta,
505  tmp_y+tmp_delta )
506  # find the >Qth plot equivalent if this is the occupancy vs eta phi plot
507  QthHist = None
508  if "CellOccupancyVsEtaPhi" in hist:
509  QthHistPath= hist.replace("2d_Occupancy/CellOccupancyVsEtaPhi", "2d_PoorQualityFraction/fractionOverQthVsEtaPhi").replace("_5Sigma_CSCveto", "_hiEth_noVeto").replace("_hiEth_CSCveto", "_hiEth_noVeto")
510  QthHist = f.Get("run_%d/%s"%(args.runNumber,QthHistPath))
511 
512  # Extract the list of bins where to count.
513  # Scans the window to find all bins that fall in the window
514  # The regionBins is defined for each histogram allowing different binning
515  for ix in range(nSteps):
516  iX = tmp_x - tmp_delta + ix * subStep
517  for iy in range (nSteps):
518  iY = tmp_y - tmp_delta + iy * subStep
519  tmp_bin = histos[hist]["merged"].FindBin(iX,iY)
520  if (tmp_bin not in histos[hist]["regionBins"]):
521  histos[hist]["regionBins"].append(tmp_bin)
522  topNBins(hist,histos[hist]["merged"],args.topN,histos[hist]["regionBins"], QthHist)
523  # Draw a box on each of the plots, highlighting the region that we will compare
524  histos[hist]["box"].SetLineColor(R.kRed+1)
525  histos[hist]["box"].SetLineWidth(3)
526  histos[hist]["box"].SetFillStyle(0)
527  histos[hist]["box"].Draw()
528 
529  thiscanv.objs = []
530  thiscanv.objs.append(histos[hist]["box"])
531  thiscanv.Update()
532  if groupname is not None:
533  drawngroup[groupname] += 1
534  thiscanv.cd()
535 
536  if args.onlyBoxes is True:
537  input("I am done...")
538  sys.exit()
539 
540 
541  print("Finding the paths to the per-LB hist files")
542  # Extract all the unmerged files available with the LB range
543  lbFilePathList = pathExtract.returnEosHistPathLB( args.runNumber,
544  args.lowerlb, args.upperlb,
545  args.stream, args.amiTag, args.tag )
546 
547  if isinstance(lbFilePathList,str) and "NOT FOUND" in lbFilePathList:
548  print("Could not find per-LB files for this run")
549  print("HINT: check if there is a folder like","/eos/atlas/atlastier0/tzero/prod/"+args.tag+"/physics_"+args.stream+"/00"+str(args.runNumber)+"/"+args.tag+".00"+str(args.runNumber)+".physics_"+args.stream+".*."+args.amiTag)
550  sys.exit()
551 
552  print("I have found %d unmerged HIST files"%(len(lbFilePathList)))
553  print("The first one is root://eosatlas.cern.ch/%s"%(lbFilePathList[0]))
554  print("The last one is root://eosatlas.cern.ch/%s"%(lbFilePathList[-1]))
555 
556  print("Now iterating over per-LB files and getting bin contents")
557  # Loop on all unmerged files
558  # and store number of hits per histogram
559  listLB = []
560  for count,lbFile in enumerate(lbFilePathList):
561  lbFilePath = "root://eosatlas.cern.ch/%s"%(lbFile).rstrip()
562  # Extract lb from the filename and display it
563  ilb = int((lbFile.split("_lb")[1]).split("._")[0])
564  if ilb not in listLB:
565  listLB.append(ilb)
566  if (count%100 == 0):
567  sys.stdout.write("\n I processed %d/%d files \n LBs:"%(count,len(lbFilePathList)))
568  sys.stdout.write("%d "%(ilb))
569  sys.stdout.flush()
570  fLB = R.TFile.Open(lbFilePath)
571  for iPath in histos.keys():
572  histos[iPath][ilb] = fLB.Get("run_%d/%s"%(args.runNumber,iPath))
573  if not isinstance(histos[iPath][ilb], R.TH1) and not isinstance(histos[iPath][ilb], R.TH2):
574  continue
575 
576  for iBin in histos[iPath]['regionBins']:
577  histos[iPath]["nbHitInHot"][ilb] = histos[iPath]["nbHitInHot"][ilb] + histos[iPath][ilb].GetBinContent(iBin)
578 
579  fLB.Close()
580 
581  print("Time to check for correlations")
582  correls, fractionNonZero = checkCorrel(histos, listLB, args.checkCorr)
583 
584  getSummary(histos, correls, fractionNonZero)
585 
586  input("I am done...")
checkCorrelInHIST.getSummary
def getSummary(histos, correls, fractionNonZero)
Definition: checkCorrelInHIST.py:243
checkCorrelInHIST.LIDProposal
def LIDProposal(hname, eta, phi, delta=0.15)
Definition: checkCorrelInHIST.py:98
replace
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition: hcg.cxx:307
vtune_athena.format
format
Definition: vtune_athena.py:14
index
Definition: index.py:1
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
RootHelpers::FindBin
Int_t FindBin(const TAxis *axis, const double x)
Definition: RootHelpers.cxx:14
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
GetMean
TGraphErrors * GetMean(TH2F *histo)
Definition: TRTCalib_makeplots.cxx:3907
GetEntries
TGraphErrors * GetEntries(TH2F *histo)
Definition: TRTCalib_makeplots.cxx:4019
dumpHVPathFromNtuple.append
bool append
Definition: dumpHVPathFromNtuple.py:91
checkCorrelInHIST.int
int
Definition: checkCorrelInHIST.py:345
checkCorrelInHIST.convHname
def convHname(hname)
Definition: checkCorrelInHIST.py:86
checkCorrelInHIST.hType
def hType(hist, verbose=False)
Definition: checkCorrelInHIST.py:126
PlotPulseshapeFromCool.input
input
Definition: PlotPulseshapeFromCool.py:106
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
checkCorrelInHIST.setupDqmAPI
def setupDqmAPI()
Definition: checkCorrelInHIST.py:110
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename T::value_type > sorted(T begin, T end)
Helper function to create a sorted vector from an unsorted one.
checkCorrelInHIST.lbStr
def lbStr(lb)
Definition: checkCorrelInHIST.py:122
print
void print(char *figname, TCanvas *c1)
Definition: TRTCalib_StrawStatusPlots.cxx:25
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
Trk::open
@ open
Definition: BinningType.h:40
checkCorrelInHIST.type
type
Definition: checkCorrelInHIST.py:345
checkCorrelInHIST.topNBins
def topNBins(histname, h, topn, bins, h_fracQth=None)
Definition: checkCorrelInHIST.py:278
str
Definition: BTagTrackIpAccessor.cxx:11
python.Bindings.keys
keys
Definition: Control/AthenaPython/python/Bindings.py:798
Trk::split
@ split
Definition: LayerMaterialProperties.h:38
checkCorrelInHIST.expandWildCard
def expandWildCard(histlist)
Definition: checkCorrelInHIST.py:44
checkCorrelInHIST.checkCorrel
def checkCorrel(histos, listLB, checkList)
Definition: checkCorrelInHIST.py:138