ATLAS Offline Software
Loading...
Searching...
No Matches
WriteBchToCrest.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# WriteBchToCrest.py
6# Sanya Solodkov <Sanya.Solodkov@cern.ch>, 2025-10-30
7
8import getopt,sys,os,bisect
9os.environ['TERM'] = 'linux'
10
11def usage():
12 print ("Usage: ", sys.argv[0]," [OPTION] ... ")
13 print ("Update TileCal bad channels in COOL")
14 print ("")
15 print ("-h, --help shows this help")
16 print ("-f, --folder= specify folder to use, default is /TILE/OFL02/STATUS/ADC")
17 print ("-t, --tag= specify tag to use, default is RUN2-HLT-UPD1-00")
18 print ("-r, --run= specify run number, default is 0")
19 print ("-l, --lumi= specify lumi block number, default is 0")
20 print ("-b, --begin= specify run number of first iov in multi-iov mode, by default uses very first iov")
21 print ("-e, --end= specify run number of last iov in multi-iov mode, by default uses latest iov")
22 print ("-L, --endlumi= specify lumi block number for last iov in multi-iov mode, default is 0")
23 print ("-A, --adjust in multi-iov mode adjust iov boundaries to nearest iov available in DB, default is False")
24 print ("-M, --module= specify module to use in multi-IOV update, default is all")
25 #print ("-m, --mode= specify update mode: 1 or 2; if not set - choosen automatically, depending on schema")
26 print ("-c, --comment= specify comment which should be written to DB, in multi-iov mode it is appended to old comment")
27 print ("-C, --Comment= specify comment which should be written to DB, in mutli-iov mode it overwrites old comment")
28 print ("-U, --user= specify username for comment")
29 print ("-x, --execfile= specify python file which should be executed, default is bch.py")
30 print ("-i, --inschema= specify name of input JSON file or CREST_SERVER_PATH")
31 print ("-o, --outschema= specify name of output JSON file, default is tileCalib.json")
32 print ("-n, --online write additional file with online bad channel status")
33 print ("-p, --upd4 write additional file with CURRENT UPD4 tag")
34 print ("-v, --verbose verbose mode")
35 print ("-s, --schema= specify input/output schema to use when both input and output schemas are the same")
36 #print ("-S, --server= specify server - ORACLE or FRONTIER, default is FRONTIER")
37 #print ("-u --update set this flag if output file should be updated, otherwise it'll be recreated")
38
39letters = "hr:l:b:e:L:AM:m:S:s:i:o:t:f:x:c:C:U:npvu"
40keywords = ["help","run=","lumi=","begin=","end=","endlumi=","adjust","module=","mode=","server=","schema=","inschema=","outschema=","tag=","folder=","execfile=","comment=","Comment=","user=","online","upd4","verbose","update"]
41
42try:
43 opts, extraparams = getopt.getopt(sys.argv[1:], letters, keywords)
44except getopt.GetoptError as err:
45 print (str(err))
46 usage()
47 sys.exit(2)
48
49# defaults
50run = -1
51lumi = 0
52mode = 0
53server = ''
54schema = 'tileCalib.json'
55oraSchema = 'CREST'
56inSchema = oraSchema
57outSchema = schema
58folderPath = "/TILE/OFL02/STATUS/ADC"
59onlSuffix = None
60curSuffix = None
61tag = "UPD1"
62execFile = "bch.py"
63comment = ""
64Comment = None
65verbose = False
66update = False
67iov = False
68beg = 0
69end = 2147483647
70endlumi = 0
71moduleList = ['ALL']
72adjust = False
73
74try:
75 user=os.getlogin()
76except Exception:
77 user="UnknownUser"
78
79for o, a in opts:
80 a = a.strip()
81 if o in ("-f","--folder"):
82 folderPath = a
83 elif o in ("-t","--tag"):
84 tag = a
85 elif o in ("-S","--server"):
86 server = a
87 elif o in ("-s","--schema"):
88 schema = a
89 inSchema = a
90 outSchema = a
91 elif o in ("-i","--inschema"):
92 inSchema = a
93 elif o in ("-o","--outschema"):
94 outSchema = a
95 elif o in ("-n","--online"):
96 onlSuffix = True
97 elif o in ("-p","--upd4"):
98 curSuffix = True
99 elif o in ("-u","--update"):
100 update = True
101 elif o in ("-r","--run"):
102 run = int(a)
103 elif o in ("-l","--lumi"):
104 lumi = int(a)
105 elif o in ("-b","--begin"):
106 beg = int(a)
107 iov = True
108 elif o in ("-e","--end"):
109 end = int(a)
110 iov = True
111 elif o in ("-L","--endlumi"):
112 endlumi = int(a)
113 elif o in ("-A","--adjust"):
114 adjust = True
115 elif o in ("-M","--module"):
116 moduleList = a.split(",")
117 elif o in ("-m","--mode"):
118 mode = int(a)
119 elif o in ("-x","--execfile"):
120 execFile = a
121 elif o in ("-c","--comment"):
122 comment = a
123 elif o in ("-C","--Comment"):
124 Comment = a
125 comment = a
126 elif o in ("-U","--user"):
127 user = a
128 elif o in ("-v","--verbose"):
129 verbose = True
130 elif o in ("-h","--help"):
131 usage()
132 sys.exit(2)
133 else:
134 raise RuntimeError("unhandeled option")
135
136onl=("/TILE/ONL01" in folderPath)
137if not len(outSchema):
138 outSchema = schema
139else:
140 schema = outSchema
141if not len(inSchema):
142 inSchema = schema
143update = update or (inSchema==outSchema)
144
145from TileCalibBlobPython import TileCalibCrest
146from TileCalibBlobPython import TileCalibTools
147from TileCalibBlobPython import TileBchCrest
148from TileCalibBlobObjs.Classes import TileBchPrbs, TileBchDecoder
149
150if iov and end >= TileCalibCrest.MAXRUN:
151 end = TileCalibCrest.MAXRUN
152 endlumi = TileCalibCrest.MAXLBK
153until = (TileCalibCrest.MAXRUN,TileCalibCrest.MAXLBK)
154
155from TileCalibBlobPython.TileCalibLogger import getLogger
156log = getLogger("WriteBchToCrest")
157import logging
158logLevel=logging.DEBUG
159log.setLevel(logLevel)
160
161if tag.upper().endswith('HEAD'):
162 tag=tag.upper()
163if len(tag)==0 or tag.endswith('HEAD'):
164 folderPath='/TILE/ONL01/STATUS/ADC'
165 log.info("tag is %s, using %s folder", tag if tag else 'empty', folderPath)
166 tag='TILEONL01STATUSADC-HEAD'
167
168folderTag = tag
169if folderTag.upper().startswith("TILE") or folderTag.upper().startswith("CALO"):
170 folderPath=""
171log.info("Initializing bad channels from %s folder %s with tag %s", inSchema, folderPath, folderTag)
172
173iovList = []
174iovUntil = []
175blobReader = TileCalibCrest.TileBlobReaderCrest(inSchema, folderPath, folderTag, max(run,beg), lumi, 0, 0)
176if folderPath and not (folderTag.upper().startswith("TILE") or folderTag.upper().startswith("CALO")):
177 folderTag = blobReader.getFolderTag(folderPath,None,folderTag)
178if iov:
179 #=== filling the iovList
180 log.info( "Looking for IOVs" )
181 iovList = blobReader.getIovs()
182 iovList+=[until]
183
184 since=(beg,lumi)
185 ib=bisect.bisect(iovList,since)-1
186 if ib<0:
187 ib=0
188 if iovList[ib] != since:
189 if adjust:
190 since = iovList[ib]
191 log.info( "Moving beginning of first IOV with new bad channels from (%d,%d) to (%d,%d)", beg,lumi,since[0],since[1])
192 else:
193 iovList[ib] = since
194 log.info( "Creating new IOV starting from (%d,%d) with new bad channels", beg,lumi)
195
196 if end<0:
197 ie=ib+1
198 if ie>=len(iovList):
199 ie=ib
200 until=iovList[ie]
201 log.info( "Next IOV without new bad channels starts from (%d,%d)", until[0],until[1])
202 else:
203 until=(end,endlumi)
204 ie=bisect.bisect_left(iovList,until)
205 if ie>=len(iovList):
206 ie=len(iovList)-1
207
208 if iovList[ie] != until:
209 if adjust:
210 until=iovList[ie]
211 log.info( "Moving end of last IOV from (%d,%d) to (%d,%d)", end,endlumi,until[0],until[1])
212 else:
213 log.info( "Keeping end of last IOV at (%d,%d) - new IOV is shorter than IOV in input DB", end,endlumi)
214 iovList[ie] = until
215
216
217 iovList = iovList[ib:ie]
218 iovUntil = iovList[1:] + [until]
219 begin = since
220 run = since[0]
221 lumi = since[1]
222 log.info( "IOVs: %s", str(iovList) )
223
224 log.info( "%d IOVs in total, end of last IOV is %s", ie-ib,str(until))
225
226else:
227 #=== set run number
228 if run<0:
229 lumi=0
230 if "UPD4" in folderTag:
231 run=TileCalibTools.getPromptCalibRunNumber()
232 log.warning( "Run number is not specified, using minimal run number in calibration loop %d", run )
233 else:
234 run=TileCalibTools.getLastRunNumber()
235 log.warning( "Run number is not specified, using current run number %d", run )
236 if run<0:
237 log.error( "Bad run number" )
238 sys.exit(2)
239
240 since = (run, lumi)
241 iovList = [since]
242 iovUntil = [until]
243 begin=since
244
245 log.info("Initializing for run %d, lumiblock %d", run,lumi)
246
247#=== create bad channel manager
248log.info("")
249comments = []
250mgrWriters = []
251nvalUpdated = []
252commentsSplit = []
253for since in iovList:
254 comm=blobReader.getComment(since)
255 #log.info("Comment: %s", comm)
256 comments+=[comm]
257 nvalUpdated += [0]
258 commentsSplit+=[blobReader.getComment(since,True)]
259 mgr = TileBchCrest.TileBchMgr()
260 mgr.setLogLvl(logLevel)
261 mgr.initialize(inSchema, folderPath, folderTag, since)
262 mgrWriters += [mgr]
263log.info("")
264
265#=== Tuples of empty channels
266emptyChannelLongBarrel = (30, 31, 43)
267emptyChannelExtendedBarrel = (18, 19, 24, 25, 26, 27, 28, 29, 33, 34, 42, 43, 44, 45, 46, 47)
268
269# remember: addAdcProblem(ros, module, channel, adc), where:
270# ros = 1 LBA
271# ros = 2 LBC
272# ros = 3 EBA
273# ros = 4 EBC
274# module = 0 - 63
275# channel = 0 - 47
276# adc: 0 = low gain, 1 = high gain.
277
278#=== print bad channels
279if verbose and not iov:
280 log.info("============================================================== ")
281 log.info("bad channels before update")
282 mgr.listBadAdcs()
283
284#=== Add problems with mgr.addAdcProblem(ros, drawer, channel, adc, problem)
285#=== Remove problems with mgr.delAdcProblem(ros, drawer, channel, adc, problem)
286
287
288if len(execFile):
289 log.info("Masking new bad channels, including file %s", execFile )
290
291 #=== loop over all IOVs
292 for io,since in enumerate(iovList):
293
294 until=iovUntil[io]
295 if since==until:
296 continue # nothing to do
297
298 log.info( "Updating IOV %s - %s", str(since), str(until) )
299 mgr = mgrWriters[io]
300
301 try:
302 exec(compile(open(execFile).read(),execFile,'exec'))
303 if len(comment)==0:
304 log.error( "Comment string is not provided, please put comment='bla-bla-bla' line in %s", execFile )
305 sys.exit(2)
306 except Exception as e:
307 log.error( e )
308 log.error( "Problem reading include file %s", execFile )
309 sys.exit(2)
310
311 #=== print bad channels
312 if verbose:
313 log.info("============================================================== ")
314 log.info("bad channels after update")
315 mgr.listBadAdcs()
316
317 #====================== Write new bad channel list =================
318
319 #=== commit changes
320 if Comment is not None:
321 comment = Comment
322 author = user
323 else:
324 if comment=="None":
325 comment = comments[io]
326 elif iov and comments[io] not in comment:
327 comment += " // " + comments[io]
328 if io>0 and since!=until and 'ALL' not in moduleList:
329 author=commentsSplit[io]
330 for m in moduleList:
331 if m in comments[io]:
332 author=user
333 break
334 else:
335 author=user
336 mgr.commitToDb(outSchema, folderPath, folderTag, (TileBchDecoder.BitPat_onl01 if onl else TileBchDecoder.BitPat_ofl01), author, comment, since, moduleList)
337
338
339since = iovList[0]
340until = (TileCalibCrest.MAXRUN,TileCalibCrest.MAXLBK)
341
342if curSuffix and not onl:
343
344 if len(comment) == 0:
345 comment=blobReader.getComment(since)
346 if comment.find("): ") > -1:
347 comment = comment[(comment.find("): ")) + 3:]
348
349 log.info("")
350 log.info("============================================================== ")
351 log.info("")
352 log.info("creating DB with CURRENT UPD4 tag")
353
354 folderTagUPD4 = blobReader.getFolderTag(folderPath, None, "UPD4" )
355 if folderTagUPD4 == folderTag:
356 log.warning("CURRENT UPD4 tag %s is identical to the tag in DB which was created already", folderTagUPD4)
357 folderTagUPD4 = blobReader.getFolderTag(folderPath, None, "UPD1" )
358 log.warning("Additional UPD1 DB with tag %s will be created instead", folderTagUPD4 )
359
360 mgr.updateFromDb(inSchema, folderPath, folderTagUPD4, since, 0)
361
362 #=== commit changes
363 mgr.commitToDb(outSchema, folderPath, folderTagUPD4, TileBchDecoder.BitPat_ofl01, user, comment, since, moduleList)
364
365
366if onlSuffix and not onl:
367
368 if len(comment)==0:
369 comment = blobReader.getComment(since)
370 if comment.find("): ") > -1:
371 comment = comment[(comment.find("): ")) + 3:]
372
373 log.info("")
374 log.info("============================================================== ")
375 log.info("")
376 log.info("creating DB with ONLINE status")
377
378 #--- create online bad channel manager
379 folderOnl = "/TILE/ONL01/STATUS/ADC"
380 folderTagOnl = "TILEONL01STATUSADC-HEAD"
381
382 mgrOnl = TileBchCrest.TileBchMgr()
383 mgrOnl.setLogLvl(logLevel)
384 mgrOnl.initialize(inSchema, folderOnl, folderTagOnl, since)
385
386 #=== print online channel status
387 if verbose:
388 log.info("============================================================== ")
389 log.info("online channel status BEFORE update")
390 mgrOnl.listBadAdcs()
391
392 #=== synchronize
393 for ros in range(1, 5):
394 for mod in range(0, 64):
395 for chn in range(0, 48):
396 statlo = mgr.getAdcStatus(ros, mod, chn, 0)
397 stathi = mgr.getAdcStatus(ros, mod, chn, 1)
398
399 # remove all trigger problems first
400 for prb in [TileBchPrbs.TrigGeneralMask,
401 TileBchPrbs.TrigNoGain,
402 TileBchPrbs.TrigHalfGain,
403 TileBchPrbs.TrigNoisy]:
404 mgrOnl.delAdcProblem(ros, mod, chn, 0, prb)
405 mgrOnl.delAdcProblem(ros, mod, chn, 1, prb)
406 # and now set new trigger problems (if any)
407 if not statlo.isGood():
408 prbs = statlo.getPrbs()
409 for prb in prbs:
410 if prb in [TileBchPrbs.TrigGeneralMask,
411 TileBchPrbs.TrigNoGain,
412 TileBchPrbs.TrigHalfGain,
413 TileBchPrbs.TrigNoisy]:
414 mgrOnl.addAdcProblem(ros, mod, chn, 0, prb)
415 mgrOnl.addAdcProblem(ros, mod, chn, 1, prb)
416
417 #--- add IgnoreInHlt if either of the ADCs has isBad
418 #--- add OnlineGeneralMaskAdc if the ADCs has isBad
419 if statlo.isBad() and stathi.isBad():
420 mgrOnl.addAdcProblem(ros, mod, chn, 0, TileBchPrbs.IgnoredInHlt)
421 mgrOnl.addAdcProblem(ros, mod, chn, 0, TileBchPrbs.OnlineGeneralMaskAdc)
422 mgrOnl.addAdcProblem(ros, mod, chn, 1, TileBchPrbs.IgnoredInHlt)
423 mgrOnl.addAdcProblem(ros, mod, chn, 1, TileBchPrbs.OnlineGeneralMaskAdc)
424 elif statlo.isBad():
425 mgrOnl.addAdcProblem(ros, mod, chn, 0, TileBchPrbs.IgnoredInHlt)
426 mgrOnl.addAdcProblem(ros, mod, chn, 0, TileBchPrbs.OnlineGeneralMaskAdc)
427 mgrOnl.addAdcProblem(ros, mod, chn, 1, TileBchPrbs.IgnoredInHlt)
428 mgrOnl.delAdcProblem(ros, mod, chn, 1, TileBchPrbs.OnlineGeneralMaskAdc)
429 elif stathi.isBad():
430 mgrOnl.addAdcProblem(ros, mod, chn, 0, TileBchPrbs.IgnoredInHlt)
431 mgrOnl.delAdcProblem(ros, mod, chn, 0, TileBchPrbs.OnlineGeneralMaskAdc)
432 mgrOnl.addAdcProblem(ros, mod, chn, 1, TileBchPrbs.IgnoredInHlt)
433 mgrOnl.addAdcProblem(ros, mod, chn, 1, TileBchPrbs.OnlineGeneralMaskAdc)
434 else:
435 #--- delete IgnoreInHlt and OnlineGeneralMaskAdc if both ADCs are not Bad
436 mgrOnl.delAdcProblem(ros, mod, chn, 0, TileBchPrbs.IgnoredInHlt)
437 mgrOnl.delAdcProblem(ros, mod, chn, 0, TileBchPrbs.OnlineGeneralMaskAdc)
438 mgrOnl.delAdcProblem(ros, mod, chn, 1, TileBchPrbs.IgnoredInHlt)
439 mgrOnl.delAdcProblem(ros, mod, chn, 1, TileBchPrbs.OnlineGeneralMaskAdc)
440
441 #--- add OnlineBadTiming if either of the ADCs has isBadTiming
442 if statlo.isBadTiming() or stathi.isBadTiming():
443 mgrOnl.addAdcProblem(ros, mod, chn, 0, TileBchPrbs.OnlineBadTiming)
444 mgrOnl.addAdcProblem(ros, mod, chn, 1, TileBchPrbs.OnlineBadTiming)
445 else:
446 #--- delete OnlineBadTiming if the both ADCs has not isBadTiming
447 mgrOnl.delAdcProblem(ros, mod, chn, 0, TileBchPrbs.OnlineBadTiming)
448 mgrOnl.delAdcProblem(ros, mod, chn, 1, TileBchPrbs.OnlineBadTiming)
449
450 #--- add OnlineTimingDmuBcOffsetPos if either of the ADCs has isTimingDmuBcOffsetPos
451 if statlo.isTimingDmuBcOffsetPos() or stathi.isTimingDmuBcOffsetPos():
452 mgrOnl.addAdcProblem(ros, mod, chn, 0, TileBchPrbs.OnlineTimingDmuBcOffsetPos)
453 mgrOnl.addAdcProblem(ros, mod, chn, 1, TileBchPrbs.OnlineTimingDmuBcOffsetPos)
454 else:
455 #--- delete OnlineTimingDmuBcOffsetPos if the both ADCs has not isTimingDmuBcOffsetPos
456 mgrOnl.delAdcProblem(ros, mod, chn, 0, TileBchPrbs.OnlineTimingDmuBcOffsetPos)
457 mgrOnl.delAdcProblem(ros, mod, chn, 1, TileBchPrbs.OnlineTimingDmuBcOffsetPos)
458
459 #--- add OnlineTimingDmuBcOffsetNeg if either of the ADCs has isTimingDmuBcOffsetNeg
460 if statlo.isTimingDmuBcOffsetNeg() or stathi.isTimingDmuBcOffsetNeg():
461 mgrOnl.addAdcProblem(ros, mod, chn, 0, TileBchPrbs.OnlineTimingDmuBcOffsetNeg)
462 mgrOnl.addAdcProblem(ros, mod, chn, 1, TileBchPrbs.OnlineTimingDmuBcOffsetNeg)
463 else:
464 #--- delete OnlineTimingDmuBcOffsetNeg if the both ADCs has not isTimingDmuBcOffsetNeg
465 mgrOnl.delAdcProblem(ros, mod, chn, 0, TileBchPrbs.OnlineTimingDmuBcOffsetNeg)
466 mgrOnl.delAdcProblem(ros, mod, chn, 1, TileBchPrbs.OnlineTimingDmuBcOffsetNeg)
467
468 #--- add OnlineWrongBCID if either of the ADCs has isWrongBCID
469 if statlo.isWrongBCID() or stathi.isWrongBCID():
470 mgrOnl.addAdcProblem(ros, mod, chn, 0, TileBchPrbs.OnlineWrongBCID)
471 mgrOnl.addAdcProblem(ros, mod, chn, 1, TileBchPrbs.OnlineWrongBCID)
472 else:
473 #--- delete OnlineWrongBCID if the both ADCs has not isWrongBCID
474 mgrOnl.delAdcProblem(ros, mod, chn, 0, TileBchPrbs.OnlineWrongBCID)
475 mgrOnl.delAdcProblem(ros, mod, chn, 1, TileBchPrbs.OnlineWrongBCID)
476
477
478 #=== print online channel status
479 if verbose:
480 log.info("online channel status AFTER update")
481 mgrOnl.listBadAdcs()
482
483 #=== commit changes
484 mgrOnl.commitToDb(outSchema, folderOnl, folderTagOnl, TileBchDecoder.BitPat_onl01, user, comment, since, moduleList)
#define max(a, b)
Definition cfImp.cxx:41
IovVectorMap_t read(const Folder &theFolder, const SelectionCriterion &choice, const unsigned int limit=10)