ATLAS Offline Software
Loading...
Searching...
No Matches
ReadBchFromCrest.py
Go to the documentation of this file.
1#!/bin/env python
2
3# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
4#
5# Sanya Solodkov 2025-10-20
6#
7# Purpose: Read channel status from CREST DB or from JSON file
8# ReadBchFromCrest.py --schema='CREST' --tag='UPD4'
9#
10
11import getopt,sys,os
12os.environ['TERM'] = 'linux'
13
14def usage():
15 print ("Usage: ",sys.argv[0]," [OPTION] ... ")
16 print ("Dumps the TileCal status bits from various schemas / folders")
17 print ("")
18 print ("-h, --help shows this help")
19 print ("-f, --folder= specify status folder to use ONL01 or OFL02, don't need to specify full path")
20 print ("-t, --tag= specify tag to use, f.i. UPD1 or UPD4 or full suffix like RUN2-HLT-UPD1-00")
21 print ("-r, --run= specify run number, by default uses latest iov")
22 print ("-l, --lumi= specify lumi block number, default is 0")
23 print ("-b, --begin= specify run number of first iov in multi-iov mode, by default uses very first iov")
24 print ("-e, --end= specify run number of last iov in multi-iov mode, by default uses latest iov")
25 print ("-m, --module= specify module to use, default is not set")
26 print ("-N, --chmin= specify minimal channel to use, default is 0")
27 print ("-X, --chmax= specify maximal channel to use, default is 47")
28 print ("-c, --chan= specify channel to use , default is all channels from chmin to chmax")
29 print ("-g, --gain=, -a, --adc= specify adc(gain) to use, default is 2 (i.e. both low and high gains)")
30 print ("-C, --comment print comment for every IOV")
31 print ("-i, --iov print IOVs only for every module")
32 print ("-I, --IOV print IOVs only")
33 print ("-d, --default print also default values stored in AUX01-AUX20")
34 print ("-B, --blob print additional blob info")
35 print ("-H, --hex print frag id instead of module name")
36 print ("-P, --pmt print pmt number in addition to channel number")
37 print ("-s, --schema= specify name of input JSON file or CREST_SERVER_PATH")
38 #print ("-D, --dbname= specify dbname part of schema if schema only contains file name, default is CONDBR2")
39 #print ("-S, --server= specify server - ORACLE or FRONTIER, default is FRONTIER")
40 print ("-w, --warning suppress warning messages about missing drawers in DB")
41
42letters = "hr:l:s:t:f:D:S:dBHPwm:b:e:a:g:c:N:X:CiI"
43keywords = ["help","run=","lumi=","schema=","tag=","folder=","dbname=","server=","default","blob","hex","pmt","warning","module=","begin=","end=","chmin=","chmax=","gain=","adc=","chan=","comment","iov","IOV"]
44
45try:
46 opts, extraparams = getopt.getopt(sys.argv[1:],letters,keywords)
47except getopt.GetoptError as err:
48 print (str(err))
49 usage()
50 sys.exit(2)
51
52# defaults
53run = 2147483647
54lumi = 0
55#schema = "output.%s.json" % (run)
56schema = 'CREST'
57dbname = ''
58server = ''
59folderPath = "/TILE/OFL02/STATUS/ADC"
60tag = "UPD4"
61rosmin = 1
62rosmax = 5
63blob = False
64hexid = False
65pmt = False
66warn = 1
67modmin = 0
68modmax = 99999
69modulename="AUX-1"
70partname=""
71one_mod = False
72mod = -1
73ros = -1
74chan_n= -1
75chanmin = -1
76chanmax = -1
77gain_n = -1
78gainmin = -1
79gainmax = -1
80begin = -1
81end = 2147483647
82iov = False
83iovonly = False
84IOVONLY = False
85comment = False
86
87for o, a in opts:
88 a = a.strip()
89 if o in ("-f","--folder"):
90 if '/TILE' in a:
91 folderPath = a
92 else:
93 folderPath = "/TILE/%s/STATUS/ADC" % a
94 elif o in ("-t","--tag"):
95 tag = a
96 elif o in ("-s","--schema"):
97 schema = a
98 elif o in ("-D","--dbname"):
99 dbname = a
100 elif o in ("-S","--server"):
101 server = a
102 elif o in ("-r","--run"):
103 run = int(a)
104 elif o in ("-l","--lumi"):
105 lumi = int(a)
106 elif o in ("-b","--begin"):
107 begin = int(a)
108 iov = True
109 one_mod = True
110 elif o in ("-e","--end"):
111 end = int(a)
112 iov = True
113 one_mod = True
114 elif o in ("-i","--iov"):
115 iov = True
116 iovonly = True
117 if modulename=='AUX-1':
118 modulename='ALL00'
119 elif o in ("-I","--IOV"):
120 iov = True
121 IOVONLY = True
122 if modulename=='AUX-1':
123 modulename='ALL00'
124 elif o in ("-a","--adc","-g","--gain"):
125 gain_n = int(a)
126 elif o in ("-m","--module"):
127 modulename = a
128 one_mod = True
129 elif o in ("-c","--chan"):
130 chan_n = int(a)
131 elif o in ("-N","--chmin"):
132 chanmin = int(a)
133 elif o in ("-X","--chmax"):
134 chanmax = int(a)
135 elif o in ("-C","--comment"):
136 comment = True
137 elif o in ("-d","--default"):
138 rosmin = 0
139 elif o in ("-B","--blob"):
140 blob = True
141 elif o in ("-H","--hex"):
142 hexid = True
143 elif o in ("-P","--pmt"):
144 pmt = True
145 elif o in ("-w","--warning"):
146 warn = -1
147 elif o in ("-h","--help"):
148 usage()
149 sys.exit(2)
150 else:
151 raise RuntimeError("unhandled option")
152
153
154from TileCalibBlobPython import TileBchCrest
155from TileCalibBlobObjs.Classes import TileCalibUtils
156
157from TileCalibBlobPython.TileCalibLogger import getLogger
158log = getLogger("ReadBchFrCrest")
159import logging
160logLevel=logging.DEBUG
161log.setLevel(logLevel)
162log1 = getLogger("TileBchCrest")
163log1.setLevel(logLevel)
164log2 = getLogger("TileCalibCrest")
165log2.setLevel(logLevel)
166
167if tag.upper().endswith('HEAD'):
168 tag=tag.upper()
169if len(tag)==0 or tag.endswith('HEAD'):
170 folderPath='/TILE/ONL01/STATUS/ADC'
171 log.info("tag is %s, using %s folder", tag if tag else 'empty', folderPath)
172 if tag=='HEAD':
173 tag=''
174
175folderTag = tag
176if folderTag.upper().startswith("TILE") or folderTag.upper().startswith("CALO") :
177 folderPath=""
178log.info("Initializing folder %s with tag %s", folderPath, folderTag)
179
180#=== create bad channel manager
181mgr = TileBchCrest.TileBchMgr()
182mgr.setLogLvl(logLevel)
183mgr.initialize(schema, folderPath, folderTag, (run,lumi), warn, -2)
184if iov or comment or warn<0:
185 blobReader = mgr.getBlobReader()
186
187#=== Dump the current isBad definition
189if len(list(isBadDef.keys())):
190 log.info( "isBad Definition: " )
191 for prbCode in sorted(isBadDef.keys()):
192 prbDesc = isBadDef[prbCode]
193 msg = "- %2i (%s)" % (prbCode,prbDesc)
194 log.info( msg )
195#=== Dump the current isBadTiming definition
197if len(list(isBadTimingDef.keys())):
198 log.info( "isBadTiming Definition: " )
199 for prbCode in sorted(isBadTimingDef.keys()):
200 prbDesc = isBadTimingDef[prbCode]
201 msg = "- %2i (%s)" % (prbCode,prbDesc)
202 log.info( msg )
203
204
205#=== check ROS and module numbers
206if one_mod:
207 partname = modulename[:3]
208 mod = int(modulename[3:]) -1
209
210part_dict = {'AUX':0,'LBA':1,'LBC':2,'EBA':3,'EBC':4}
211if partname in part_dict:
212 ros = part_dict[partname]
213 rosmin = ros
214 rosmax = ros+1
215else:
216 ros = -1
217
218if mod >= 0:
219 modmin = mod
220 modmax = mod+1
221elif mod < -1:
222 modmax = modmin
223
224if chan_n >= 0 and chan_n < TileCalibUtils.max_chan():
225 chanmin = chan_n
226 chanmax = chan_n+1
227else:
228 if chanmin<0:
229 chanmin = 0
230 if chanmax<0:
231 chanmax = TileCalibUtils.max_chan()
232 else:
233 chanmax += 1
234
235if gain_n >= 0 and gain_n < TileCalibUtils.max_gain():
236 gainmin = gain_n
237 gainmax = gain_n+1
238else:
239 gainmin = 0
240 gainmax = TileCalibUtils.max_gain()
241
242
243#=== Filling the iovList
244iovList = []
245if iov:
246 if begin<0:
247 if iovonly or IOVONLY:
248 begin = end
249 else:
250 begin=0
251 iovList = blobReader.getIovs((begin,0),(end,0))
252
253 be=iovList[0][0]
254 en=iovList[-1][0]
255
256 if begin != be or end != en:
257 ib=0
258 ie=len(iovList)
259 for i,iovs in enumerate(iovList):
260 run = iovs[0]
261 lumi = iovs[1]
262 if (run<begin and run>be) or (run==begin and lumi==0) :
263 be=run
264 ib=i
265 if run>=end and run<en:
266 en=run
267 ie=i+1
268 log.info( "" )
269 if be != begin:
270 log.info( "Changing begin run from %d to %d (start of IOV)", begin,be)
271 begin=be
272 if en != end:
273 if en>end:
274 log.info( "Changing end run from %d to %d (start of next IOV)", end,en)
275 else:
276 log.info( "Changing end run from %d to %d (start of last IOV)", end,en)
277 end=en
278 iovList=iovList[ib:ie]
279 log.info( "%d IOVs in total", len(iovList))
280
281 #=== IOV only option
282 if iovonly or IOVONLY:
283 alliovs={}
284 allmods={}
285 zeroiovs={}
286 nmod=0
287 for ros in range(rosmin,rosmax):
288 for mod in range(modmin, min(modmax,TileCalibUtils.getMaxDrawer(ros))):
289 allmods[TileCalibUtils.getDrawerString(ros,mod)] = ""
290 nmod+=1
291 for since in iovList:
292 iov="(%s,%s)" % since
293 allmod=""
294 zeromod=0
295 miss=0
296 for ros in range(rosmin,rosmax):
297 for mod in range(modmin, min(modmax,TileCalibUtils.getMaxDrawer(ros))):
298 flt = blobReader.getDrawer(ros, mod, since, False, False)
299 if flt is not None:
300 mod = TileCalibUtils.getDrawerString(ros,mod)
301 if flt==0:
302 zeromod += 1
303 allmod += " " + mod + "_zero"
304 allmods[mod] += " " + iov + "_zero"
305 else:
306 allmod += " " + mod
307 allmods[mod] += " " + iov
308 else:
309 miss+=1
310 if miss==0 and nmod>1:
311 alliovs[iov] = " All %d modules" % nmod
312 else:
313 alliovs[iov] = allmod
314 zeroiovs[iov] = zeromod
315 print("")
316 if len(iovList)>0:
317 if iovonly:
318 for key,value in allmods.items():
319 if value=="":
320 value=" None"
321 print("%s\t%s" % (key,value))
322 if IOVONLY:
323 for key,value in alliovs.items():
324 if value=="":
325 value=" None"
326 if zeroiovs[key] and zeroiovs[key]>0:
327 print("%s\t%s - zero-sized blobs for %d modules" % (key,value,zeroiovs[key]))
328 else:
329 print("%s\t%s" % (key,value))
330 else:
331 print("No IOVs found")
332 sys.exit(0)
333else:
334 iovList.append((run,lumi))
335
336log.info( "\n" )
337
338
339
342dummy = [0]*48
343barrel = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
344 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
345 27, 26, 25, 30, 29, 28,-33,-32, 31, 36, 35, 34,
346 39, 38, 37, 42, 41, 40, 45,-44, 43, 48, 47, 46]
347extbar = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
348 13, 14, 15, 16, 17, 18,-19,-20, 21, 22, 23, 24,
349 -27,-26,-25,-31,-32,-28, 33, 29, 30,-36,-35, 34,
350 44, 38, 37, 43, 42, 41,-45,-39,-40,-48,-47,-46]
351
352ch2pmt = [ dummy, barrel, barrel, extbar, extbar ]
353gname = [ "LG", "HG" ]
354
355#=== Get ADC problems
356
357#=== get the channel status (if it is bad and will be masked)
358#=== the channel status depends on the definition of isBad stored
359#=== in the database drawer 1, channel 0
360#=== isAffected = has a problem not included in isBad definition
361#=== isGood = has no problem at all
362
363pref = ""
364for iovs in iovList:
365 if iov:
366 pref = "(%i,%i) " % (iovs[0],iovs[1])
367 mgr.updateFromDb(schema, folderPath, folderTag, iovs, 1, warn)
368 if comment:
369 log.info( pref + str(blobReader.getComment(iovs)) )
370 modOk = False
371 miss = 0
372 good = 0
373 aff = 0
374 bad = 0
375 nMod = 0
376 for ros in range(rosmin,rosmax):
377 for mod in range(modmin, min(modmax,TileCalibUtils.getMaxDrawer(ros))):
378 nMod += 1
379 if hexid:
380 modName = "0x%x" % ((ros<<8)+mod)
381 else:
382 modName = TileCalibUtils.getDrawerString(ros,mod)
383 if warn<0:
384 bch = blobReader.getDrawer(ros, mod, iovs, False, False)
385 if bch is None:
386 modOk = False
387 miss+=1
388 #print ("%s is missing in DB" % modName)
389 else:
390 modOk = True
391 if blob and bch:
392 print ("%s Blob type: %d Version: %d Nchannels: %d Ngains: %d Nval: %d" % (modName, bch.getObjType(), bch.getObjVersion(), bch.getNChans(), bch.getNGains(), bch.getObjSizeUint32()))
393 nBad=0
394 for chn in range(chanmin,chanmax):
395 chnName = " %2i" % chn
396 for adc in range(gainmin,gainmax):
397
398 stat = mgr.getAdcStatus(ros,mod,chn,adc)
399 #log.info( "- ADC status = isBad: %d" % stat.isBad() )
400 #log.info( "- ADC status = isGood: %d" % stat.isGood() )
401 #log.info( "- ADC status = isAffected: %d" % stat.isAffected() )
402
403 #=== get all problems of the channel
404 prbs = mgr.getAdcProblems(ros,mod,chn,adc)
405 #log.info( "ADC Problems: " )
406 if len(prbs) or iov:
407 modOk = False
408 if pmt:
409 msg = "%s pm %02i ch %02i %s " % ( modName, abs(ch2pmt[ros][chn]), chn, gname[adc] )
410 else:
411 msg = "%s %2i %1i " % ( modName,chn,adc )
412 for prbCode in sorted(prbs.keys()):
413 prbDesc = prbs[prbCode]
414 msg += " %5i (%s)" % (prbCode,prbDesc)
415 if stat.isBad():
416 msg += " => BAD"
417 nBad+=1
418 elif stat.isAffected():
419 msg += " => Affected"
420 elif stat.isGood():
421 msg += " => good"
422 print (pref+msg)
423 if modOk:
424 good+=1
425 print ("%s ALL GOOD" % (modName))
426 elif nBad==0:
427 aff+=1
428 elif nBad==TileCalibUtils.max_gain()*TileCalibUtils.max_chan() or (nBad==90 and 'LB' in modName) or (nBad==64 and 'EB'in modName) or (nBad==60 and 'EBA15' in modName) or (nBad==60 and 'EBC18' in modName):
429 bad+=1
430 if warn<0:
431 if miss:
432 print ("%3i drawers are missing in DB" % miss)
433 print ("%3i drawers are absolutely good" % good)
434 print ("%3i drawers have good and affected channels" % (aff-miss))
435 print ("%3i drawers have some bad channels" % (nMod-good-bad-aff))
436 print ("%3i drawers are completely bad" % bad)
437 #=== print all bad channels
438 #log.info("listing bad channels")
439 #mgr.listBadAdcs()
void print(char *figname, TCanvas *c1)
#define min(a, b)
Definition cfImp.cxx:40
static unsigned int max_gain()
Python compatibility function.
static unsigned int badtiming_definition_chan()
Python compatibility function.
static std::string getDrawerString(unsigned int ros, unsigned int drawer)
Return the drawer name, e.g.
static unsigned int max_chan()
Python compatibility function.
static unsigned int getMaxDrawer(unsigned int ros)
Returns the maximal channel number for a given drawer.
static unsigned int definitions_draweridx()
Python compatibility function.
static unsigned int bad_definition_chan()
Python compatibility function.