ATLAS Offline Software
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 
11 import getopt,sys,os
12 os.environ['TERM'] = 'linux'
13 
14 def 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 
42 letters = "hr:l:s:t:f:D:S:dBHPwm:b:e:a:g:c:N:X:CiI"
43 keywords = ["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 
45 try:
46  opts, extraparams = getopt.getopt(sys.argv[1:],letters,keywords)
47 except getopt.GetoptError as err:
48  print (str(err))
49  usage()
50  sys.exit(2)
51 
52 # defaults
53 run = 2147483647
54 lumi = 0
55 #schema = "output.%s.json" % (run)
56 schema = 'CREST'
57 dbname = ''
58 server = ''
59 folderPath = "/TILE/OFL02/STATUS/ADC"
60 tag = "UPD4"
61 rosmin = 1
62 rosmax = 5
63 blob = False
64 hexid = False
65 pmt = False
66 warn = 1
67 modmin = 0
68 modmax = 99999
69 modulename="AUX-1"
70 partname=""
71 one_mod = False
72 mod = -1
73 ros = -1
74 chan_n= -1
75 chanmin = -1
76 chanmax = -1
77 gain_n = -1
78 gainmin = -1
79 gainmax = -1
80 begin = -1
81 end = 2147483647
82 iov = False
83 iovonly = False
84 IOVONLY = False
85 comment = False
86 
87 for 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 
154 from TileCalibBlobPython import TileBchCrest
155 from TileCalibBlobObjs.Classes import TileCalibUtils
156 
157 from TileCalibBlobPython.TileCalibLogger import getLogger
158 log = getLogger("ReadBchFrCrest")
159 import logging
160 logLevel=logging.DEBUG
161 log.setLevel(logLevel)
162 log1 = getLogger("TileBchCrest")
163 log1.setLevel(logLevel)
164 log2 = getLogger("TileCalibCrest")
165 log2.setLevel(logLevel)
166 
167 if tag.upper().endswith('HEAD'):
168  tag=tag.upper()
169 if 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 
175 folderTag = tag
176 if folderTag.upper().startswith("TILE") or folderTag.upper().startswith("CALO") :
177  folderPath=""
178 log.info("Initializing folder %s with tag %s", folderPath, folderTag)
179 
180 #=== create bad channel manager
181 mgr = TileBchCrest.TileBchMgr()
182 mgr.setLogLvl(logLevel)
183 mgr.initialize(schema, folderPath, folderTag, (run,lumi), warn, -2)
184 if iov or comment or warn<0:
185  blobReader = mgr.getBlobReader()
186 
187 #=== Dump the current isBad definition
189 if 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
197 if 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
206 if one_mod:
207  partname = modulename[:3]
208  mod = int(modulename[3:]) -1
209 
210 part_dict = {'AUX':0,'LBA':1,'LBC':2,'EBA':3,'EBC':4}
211 if partname in part_dict:
212  ros = part_dict[partname]
213  rosmin = ros
214  rosmax = ros+1
215 else:
216  ros = -1
217 
218 if mod >= 0:
219  modmin = mod
220  modmax = mod+1
221 elif mod < -1:
222  modmax = modmin
223 
224 if chan_n >= 0 and chan_n < TileCalibUtils.max_chan():
225  chanmin = chan_n
226  chanmax = chan_n+1
227 else:
228  if chanmin<0:
229  chanmin = 0
230  if chanmax<0:
231  chanmax = TileCalibUtils.max_chan()
232  else:
233  chanmax += 1
234 
235 if gain_n >= 0 and gain_n < TileCalibUtils.max_gain():
236  gainmin = gain_n
237  gainmax = gain_n+1
238 else:
239  gainmin = 0
240  gainmax = TileCalibUtils.max_gain()
241 
242 
243 #=== Filling the iovList
244 iovList = []
245 if 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)
333 else:
334  iovList.append((run,lumi))
335 
336 log.info( "\n" )
337 
338 
339 
342 dummy = [0]*48
343 barrel = [ 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]
347 extbar = [ 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 
352 ch2pmt = [ dummy, barrel, barrel, extbar, extbar ]
353 gname = [ "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 
363 pref = ""
364 for 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()
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename R::value_type > sorted(const R &r, PROJ proj={})
Helper function to create a sorted vector from an unsorted range.
ReadBchFromCrest.usage
def usage()
Definition: ReadBchFromCrest.py:14
TileCalibUtils::getMaxDrawer
static unsigned int getMaxDrawer(unsigned int ros)
Returns the maximal channel number for a given drawer.
Definition: TileCalibUtils.cxx:136
TileCalibUtils::badtiming_definition_chan
static unsigned int badtiming_definition_chan()
Python compatibility function.
Definition: TileCalibUtils.h:132
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
TileCalibUtils::bad_definition_chan
static unsigned int bad_definition_chan()
Python compatibility function.
Definition: TileCalibUtils.h:126
TileCalibUtils::max_gain
static unsigned int max_gain()
Python compatibility function.
Definition: TileCalibUtils.h:114
TileCalibUtils::definitions_draweridx
static unsigned int definitions_draweridx()
Python compatibility function.
Definition: TileCalibUtils.h:124
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:194
histSizes.list
def list(name, path='/')
Definition: histSizes.py:38
print
void print(char *figname, TCanvas *c1)
Definition: TRTCalib_StrawStatusPlots.cxx:26
TileCalibUtils::getDrawerString
static std::string getDrawerString(unsigned int ros, unsigned int drawer)
Return the drawer name, e.g.
Definition: TileCalibUtils.cxx:145
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
TileCalibUtils::max_chan
static unsigned int max_chan()
Python compatibility function.
Definition: TileCalibUtils.h:112
str
Definition: BTagTrackIpAccessor.cxx:11
python.CaloCondLogger.getLogger
def getLogger(name="CaloCond")
Definition: CaloCondLogger.py:16