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