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