ATLAS Offline Software
Loading...
Searching...
No Matches
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
8import os, sys
9import argparse
10import xmlrpc.client
11from DataQualityUtils import pathExtract
12import ctypes
13import sqlite3
14
15
16import ROOT as R
17
18R.gStyle.SetPalette(1)
19R.gStyle.SetOptStat("em")
20
21nLB = 8000
22
23dqmpassfile="/afs/cern.ch/user/l/larmon/public/atlasdqmpass.txt"
24
25conn = None
26cursor = None
27
28# Some definitions for wildcards which can be used for input plot lists
29wildcards = {}
30wildcardplots = ["CellOccupancyVsEtaPhi", "fractionOverQthVsEtaPhi","DatabaseNoiseVsEtaPhi","CellAvgEnergyVsEtaPhi"]
31
32for 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
41wildcards["TileCellEneEtaPhi"] = [ "A", "B", "D", "E" ]
42wildcards["TileCellEtaPhiOvThr"] = [ "A", "B", "D", "E" ]
43
44def 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
86def 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
98def 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
122def lbStr(lb):
123 """ Return the lb number in string format, e.g. _lb0001 """
124 return "_lb"+str(lb).zfill(4)
125
126def 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
138def 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
243def 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
278def 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
343if __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...")
void print(char *figname, TCanvas *c1)
TGraphErrors * GetMean(TH2F *histo)
TGraphErrors * GetEntries(TH2F *histo)
#define min(a, b)
Definition cfImp.cxx:40
#define max(a, b)
Definition cfImp.cxx:41
std::string replace(std::string s, const std::string &s2, const std::string &s3)
Definition hcg.cxx:310
std::vector< std::string > split(const std::string &s, const std::string &t=":")
Definition hcg.cxx:177
checkCorrel(histos, listLB, checkList)
hType(hist, verbose=False)
LIDProposal(hname, eta, phi, delta=0.15)
getSummary(histos, correls, fractionNonZero)
topNBins(histname, h, topn, bins, h_fracQth=None)
Definition index.py:1