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