ATLAS Offline Software
Loading...
Searching...
No Matches
ReadCalibFromCrest.py
Go to the documentation of this file.
1#!/bin/env python
2
3# Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
4#
5# File: ReadCalibFromCrest.py
6# Sanya Solodkov <Sanya.Solodkov@cern.ch>, 2025-02-04
7#
8# Purpose: Read calibration constants from CREST DB or from JSON file
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 constants from various schemas / folders / tags")
17 print ("")
18 print ("-h, --help shows this help")
19 print ("-f, --folder= specify status folder to use f.i. /TILE/OFL02/CALIB/CIS/LIN ")
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 print or number of adcs to print with - sign, default is -2")
30 print ("-n, --nval= specify number of values to output, default is all")
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 ("-p, --prefix= print some prefix on every line ")
39 print ("-k, --keep= field numbers or channel numbers to ignore, e.g. '0,2,3,EBch0,EBch1,EBch12,EBch13,EBspD4ch18,EBspD4ch19,EBspC10ch4,EBspC10ch5' ")
40 print ("-o, --double print values with double precision")
41 print ("-s, --schema= specify name of input JSON file or CREST_SERVER_PATH")
42
43letters = "hr:l:s:t:f:n:b:e:m:N:X:c:a:g:p:dBCiIHPk:o:"
44keywords = ["help","run=","lumi=","schema=","tag=","folder=","module=","begin=","end=","chmin=","chmax=","gain=","adc=","chan=","nval=","prefix=","default","blob","hex","pmt","keep=","comment","iov","IOV","double"]
45
46try:
47 opts, extraparams = getopt.getopt(sys.argv[1:],letters,keywords)
48except getopt.GetoptError as err:
49 print (str(err))
50 usage()
51 sys.exit(2)
52
53# defaults
54run = 2147483647
55lumi = 0
56schema = 'CREST'
57folderPath = "/TILE/OFL02/CALIB/CIS/LIN"
58tag = "UPD4"
59nval = 0
60nadc = -1
61rosmin = 1
62rosmax = 5
63blob = False
64hexid = False
65pmt = False
66prefix = None
67modmin = 0
68modmax = 99999
69modulename="AUX-1"
70partname=""
71one_mod = False
72mod = -1
73ros = -1
74chan_n= -1
75chanmin = -1
76chanmax = -1
77gainmin = -1
78gainmax = -1
79begin = -1
80end = 2147483647
81iov = False
82iovonly = False
83IOVONLY = False
84comment = False
85keep=[]
86doubl = False
87
88for o, a in opts:
89 a = a.strip()
90 if o in ("-f","--folder"):
91 folderPath = a
92 elif o in ("-t","--tag"):
93 tag = a
94 elif o in ("-s","--schema"):
95 schema = a
96 elif o in ("-n","--nval"):
97 nval = 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 nadc = 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 ("-r","--run"):
130 run = int(a)
131 elif o in ("-l","--lumi"):
132 lumi = int(a)
133 elif o in ("-d","--default"):
134 rosmin = 0
135 elif o in ("-B","--blob"):
136 blob = True
137 elif o in ("-H","--hex"):
138 hexid = True
139 elif o in ("-P","--pmt"):
140 pmt = True
141 elif o in ("-p","--prefix"):
142 prefix = a
143 elif o in ("-k","--keep"):
144 keep = a.split(",")
145 elif o in ("-o","--double"):
146 doubl = True
147 elif o in ("-h","--help"):
148 usage()
149 sys.exit(2)
150 else:
151 raise RuntimeError("unhandled option")
152
153
154from TileCalibBlobPython import TileCalibCrest
155from TileCalibBlobObjs.Classes import TileCalibUtils, TileCalibType
156
157from TileCalibBlobPython.TileCalibLogger import getLogger
158log = getLogger("ReadCalibFrCrest")
159import logging
160logLevel=logging.DEBUG
161log.setLevel(logLevel)
162log1 = getLogger("TileCalibCrest")
163log1.setLevel(logLevel)
164
165#=== check ROS and module numbers
166if one_mod:
167 partname = modulename[:3]
168 mod = int(modulename[3:]) -1
169
170part_dict = {'AUX':0,'LBA':1,'LBC':2,'EBA':3,'EBC':4}
171if partname in part_dict:
172 ros = part_dict[partname]
173 rosmin = ros
174 rosmax = ros+1
175else:
176 ros = -1
177
178if mod >= 0:
179 modmin = mod
180 modmax = mod+1
181elif mod < -1:
182 modmax = modmin
183
184if iov:
185 run=end
186 lumi=0
187
188if tag.upper().endswith('HEAD'):
189 tag=tag.upper()
190if len(tag)==0 or tag.endswith('HEAD'):
191 folderPath=folderPath.replace('OFL02','ONL01')
192 log.info("tag is %s, using %s folder", tag if tag else 'empty', folderPath)
193 if tag=='HEAD':
194 tag=''
195
196folderTag = tag
197tag = tag.upper()
198tag1 = tag.split('_')[1][:4] if '_' in tag else tag[:4]
199if tag1 == "TILE" or tag1 == "CALO" or tag.startswith("TILE") or tag.startswith("CALO"):
200 folderPath=""
201if not os.path.isfile(schema):
202 log.info("Initializing folder %s with tag %s", folderPath, folderTag)
203
204blobReader = TileCalibCrest.TileBlobReaderCrest(schema,folderPath, folderTag, run, lumi,
205 TileCalibUtils.getDrawerIdx(max(rosmin,0),max(modmin,0)),
206 TileCalibUtils.getDrawerIdx(min(rosmax-1,4),max(0,min(modmax-1,TileCalibUtils.getMaxDrawer(min(rosmax-1,4))-1))))
207
208#=== get drawer with status at given run
209flt=None
210r=5
211d=0
214while not flt:
215 d-=1
216 if d<0:
217 r-=1
218 if r<0:
219 break
221 flt = blobReader.getDrawer(r, d, (run,lumi), True, False)
222if flt:
223 blobT=flt.getObjType()
224 blobV=flt.getObjVersion()
225 mchan=flt.getNChans()
226 mgain=flt.getNGains()
227 mval=flt.getObjSizeUint32()
228 log.info( "Blob type: %d Version: %d Nchannels: %d Ngains: %d Nval: %d", blobT,blobV,mchan,mgain,mval)
229 if nadc<-mgain:
230 nadc=-mgain
231 if nchan<mchan:
232 nchan=mchan
233 if ngain<mgain:
234 ngain=mgain
235else:
236 mgain=1
237if nadc==-1:
238 nadc=-ngain
239
240log.info("Comment: %s", blobReader.getComment((run,lumi)))
241
242if chan_n >= 0 and chan_n < nchan:
243 chanmin = chan_n
244 chanmax = chan_n+1
245else:
246 if chanmin<0:
247 chanmin = 0
248 if chanmax<0:
249 chanmax = nchan
250 else:
251 chanmax += 1
252
253if nadc >= 0 and nadc < ngain:
254 gainmin = nadc
255 gainmax = nadc+1
256else:
257 gainmin = 0
258 if nadc<0:
259 gainmax = -nadc
260 else:
261 gainmax = ngain
262
263
264#=== Filling the iovList
265iovList = []
266if iov:
267 if begin<0:
268 if iovonly or IOVONLY:
269 begin = end
270 else:
271 begin=0
272 iovList = blobReader.getIovs((begin,0),(end,0))
273
274 be=iovList[0][0]
275 en=iovList[-1][0]
276
277 if begin != be or end != en:
278 log.info( "" )
279 if be != begin:
280 log.info( "Changing begin run from %d to %d (start of IOV)", begin,be)
281 begin=be
282 if en != end:
283 if en>end:
284 log.info( "Changing end run from %d to %d (start of next IOV)", end,en)
285 else:
286 log.info( "Changing end run from %d to %d (start of last IOV)", end,en)
287 end=en
288 log.info( "%d IOVs in total", len(iovList))
289
290 #=== IOV only option
291 if iovonly or IOVONLY:
292 option = 1 if iovonly else 0
293 option += (2 if IOVONLY else 0)
294 blobReader.dumpIovs(iovList,rosmin,rosmax,modmin,modmax,option,(rosmin<=0),True)
295 sys.exit(0)
296else:
297 iovList.append((run,lumi))
298
299log.info( "\n" )
300
301
302
305dummy = [0]*48
306barrel = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
307 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
308 27, 26, 25, 30, 29, 28,-33,-32, 31, 36, 35, 34,
309 39, 38, 37, 42, 41, 40, 45,-44, 43, 48, 47, 46]
310extbar = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
311 13, 14, 15, 16, 17, 18,-19,-20, 21, 22, 23, 24,
312 -27,-26,-25,-31,-32,-28, 33, 29, 30,-36,-35, 34,
313 44, 38, 37, 43, 42, 41,-45,-39,-40,-48,-47,-46]
314
315ch2pmt = [ dummy, barrel, barrel, extbar, extbar ]
316gname=[]
317if mgain!=2:
318 for i in range(mgain+1):
319 gname+=[ "g "+str(i) ]
320else:
321 gname = [ "LG", "HG" ]
322
323#=== loop over all partitions,modules,channels
324oneModule = ((rosmax-rosmin==1) and (modmax-modmin==1) and iov)
325oldBlob = None
326pref = ""
327for iovs in iovList:
328 if iov:
329 pref = "(%i,%i) " % (iovs[0],iovs[1])
330 if prefix:
331 pref = prefix + " " + pref
332 if comment:
333 log.info( pref + str(blobReader.getComment(iovs)) )
334 if prefix and prefix.startswith("Write"):
335 comm = blobReader.getComment(iovs)
336 if ": " in comm:
337 comm = comm[comm.find(": ")+2:]
338 print ('%s --update --folder=%s --tag=%s --run=%i --lumi=%i --comment="%s"' % (prefix,folderPath,folderTag,iovs[0],iovs[1],comm))
339 miss=0
340 good=0
341 for ros in range(rosmin,rosmax):
342 for mod in range(modmin, min(modmax,TileCalibUtils.getMaxDrawer(ros))):
343 if hexid:
344 modName = "0x%x" % ((ros<<8)+mod)
345 else:
346 modName = TileCalibUtils.getDrawerString(ros,mod)
347 if modName in ['EBA39','EBA40','EBA41','EBA42','EBA55','EBA56','EBA57','EBA58',
348 'EBC39','EBC40','EBC41','EBC42','EBC55','EBC56','EBC57','EBC58' ]:
349 modSpec = 'EBspC10'
350 elif modName in ['EBA15','EBC18']:
351 modSpec = 'EBspD4'
352 elif modName in ['EBC29','EBC32','EBC34','EBC37']:
353 modSpec = 'EBspE4'
354 elif modName in ['EBA07', 'EBA25', 'EBA44', 'EBA53',
355 'EBC07', 'EBC25', 'EBC44', 'EBC53',
356 'EBC28', 'EBC31', 'EBC35', 'EBC38' ]:
357 modSpec = 'EBspE1'
358 elif modName in ['EBA08', 'EBA24', 'EBA43', 'EBA54',
359 'EBC08', 'EBC24', 'EBC43', 'EBC54' ]:
360 modSpec = 'EBMBTS'
361 else:
362 modSpec = modName
363 try:
364 if oneModule:
365 newBlob = blobReader.getBlob(ros, mod, iovs, False)
366 if oldBlob == newBlob:
367 log.info( f'{modName} in IOV {iovs} is identical to previous IOV')
368 continue
369 else:
370 if oldBlob is None:
371 log.info( f'Reading IOV {iovs} for module {modName}')
372 else:
373 log.info( f'{modName} was updated in IOV {iovs}')
374 oldBlob = newBlob
375 flt = blobReader.getDrawer(ros, mod,iovs, False, False)
376 if flt is None or isinstance(flt, (int)):
377 miss+=1
378 print ("%s is missing in DB" % modName)
379 else:
380 good+=1
381 if blob:
382 print ("%s Blob type: %d Version: %d Nchannels: %d Ngains: %d Nval: %d" % (modName, flt.getObjType(), flt.getObjVersion(), flt.getNChans(), flt.getNGains(), flt.getObjSizeUint32()))
383 typeName = TileCalibType.getClassName(flt.getObjType())[-3:]
384 mval0 = 0
385 mval = flt.getObjSizeUint32()
386 if nval<0 and -nval<=mval:
387 mval=-nval
388 mval0=mval-1
389 elif nval!=0 and nval<mval:
390 mval = nval
391 mchan=flt.getNChans()
392 mgain=flt.getNGains()
393 chmin = chanmin if chanmin<mchan else mchan
394 chmax = chanmax if chanmax<mchan else mchan
395 gnmin = gainmin if gainmin<mgain else mgain
396 gnmax = gainmax if gainmax<mgain else mgain
397 for chn in range(chmin,chmax):
398 for adc in range(gnmin,gnmax):
399 if pmt:
400 msg = "%s pm %02i ch %02i %s " % ( modName, abs(ch2pmt[ros][chn]), chn, gname[adc] )
401 else:
402 msg = "%s %2i %1i " % ( modName, chn, adc )
403 for val in range(mval0,mval):
404 if str(val) in keep or modName in keep or modSpec in keep or modName[:3] in keep or modName[:2] in keep \
405 or ("%sch%i"% (modName,chn)) in keep or ("%sch%i"% (modSpec,chn)) in keep or ("%sch%i"% (modName[:3],chn)) in keep or ("%sch%i"% (modName[:2],chn)) in keep \
406 or ("%sch%ig%i"% (modName,chn,adc)) in keep or ("%sch%ig%i"% (modSpec,chn,adc)) in keep or ("%sch%ig%i"% (modName[:3],chn,adc)) in keep or ("%sch%ig%i"% (modName[:2],chn,adc)) in keep:
407 msg += " keep "
408 else:
409 if typeName=='Int':
410 v = flt.getData(chn, adc, val)
411 if v>0xff:
412 msg += " 0x%x" % v
413 else:
414 msg += " %3d" % v
415 elif typeName=='Bch':
416 msg += " %d" % flt.getData(chn, adc, val)
417 elif doubl:
418 msg += " %s" % flt.getData(chn, adc, val)
419 else:
420 msg += " %f" % flt.getData(chn, adc, val)
421 print (pref+msg)
422 except Exception as e:
423 print (e)
424 if miss:
425 if iovs[0]!=2147483647:
426 print ("%3i drawers are present in DB for run %d lb %d" % (good,iovs[0],iovs[1]))
427 print ("%3i drawers are missing in DB for run %d lb %d" % (miss,iovs[0],iovs[1]))
428 else:
429 print ("%3i drawers are present in DB" % (good))
430 print ("%3i drawers are missing in DB" % (miss))
431 if good==0:
432 print ("Please, check that you are using correct schema and correct tag")
#define min(a, b)
Definition cfImp.cxx:40
#define max(a, b)
Definition cfImp.cxx:41
static std::string getClassName(TileCalibType::TYPE type)
Returns the class name.
static unsigned int max_gain()
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 getDrawerIdx(unsigned int ros, unsigned int drawer)
Returns a drawer hash.
static unsigned int getMaxDrawer(unsigned int ros)
Returns the maximal channel number for a given drawer.