11 Python module for managing TileCal ADC status words.
17 from TileCalibBlobObjs.Classes
import TileBchStatus, TileCalibUtils, \
18 TileBchPrbs, TileBchDecoder
19 from TileCalibBlobPython
import TileCalibTools
20 from TileCalibBlobPython.TileCalibTools
import MINRUN, MINLBK, MAXRUN, MAXLBK
21 from TileCalibBlobPython.TileCalibLogger
import TileCalibLogger
27 This class manages updates to the Tile Calorimeter bad channel database.
28 The usual mode of operation should start with initializing this manager
29 with a current set of bad channels from an existing database.
30 The status of individual ADCs can then be modified using the setAdcStatus,
31 updateFromFile or updateFromDb methods.
32 In a final step, the changes are commited to the database using the commit
39 TileCalibLogger.__init__(self,
"TileBchMgr")
53 Private function, calculating the index of a given ADC
54 for the internal cache.
59 def __updateFromDb(self, db, folderPath, tag, runLumi, fillTable=1, ros=-1, module=-1):
61 Updates the internal bad channel cache with the content
62 found in the database. An open database instance (db) has to
63 be provided. Tag and runNum are used to locate the set of
64 bad channels to be read from the database.
70 raise Exception (
"DB not open: ", db.databaseId())
71 except Exception
as e:
72 self.log().critical( e )
80 self.log().
info(
"Updating dictionary from \'%s\'", db.databaseName())
81 self.log().
info(
"... using tag \'%s\', run-lumi=%s", tag,runLumi)
83 self.
__comment = reader.getComment(runLumi)
87 rosmin = ros
if ros>=0
else 0
89 for ros
in range(rosmin,rosmax):
90 modmin = module
if module>=0
else 0
92 for mod
in range(modmin,modmax):
93 bch = reader.getDrawer(ros, mod, runLumi,
False)
96 self.log().warning(
"Missing IOV in condDB: ros=%i mod=%i runLumi=%s", ros,mod,runLumi)
102 adcBits = bch.getData(chn,adc,0)
104 chnBits = bch.getData(chn, 2,0)
109 elif fillTable==1
or fillTable==-1:
111 elif fillTable==2
or fillTable==-2:
116 status1 =
TileBchStatus( bchDecoder.decode(chnBits,adcBits) )
124 def updateFromDb(self, db, folderPath, tag, runLumi, fillTable=1, mode=None, ros=-1, module=-1):
127 self.
__updateFromDb(db, folderPath, tag, runLumi, fillTable, ros, module)
130 def initialize(self, db, folderPath, tag="", runLumi=(MAXRUN,MAXLBK-1), mode=
None, ros=-1, module=-1):
132 Initializes the internal bad channel cache. Any changes applied to the
133 cache previous to calling this function are lost. Typically this function
134 is called once in the beginning to initialize the cache with a set of
135 current bad channels.
137 self.log().
info(
"Initializing from database, resetting all changes!")
159 self.log().
info(
"Updating TileBchStatus::isBad() definition from DB")
162 self.log().
info(
"No TileBchStatus::isBad() definition found in DB, using defaults")
167 self.log().
info(
"Updating TileBchStatus::isBadTiming() definition from DB")
170 self.log().
info(
"No TileBchStatus::isBadTiming() definition found in DB, using defaults")
178 Get TileBchStatus for a given ADC.
185 Set TileBchStatus for a given ADC.
192 Returns a dictionary with { problemEnum : 'Description'}
196 if not status.isGood():
197 prbs = status.getPrbs()
205 Expects a list of TileBchPrbs::PrbS as input
215 Sets a specific problem
224 Removes a specific problem
233 convert module name to ros,drawer
236 part_dict = {
'LBA':1,
'LBC':2,
'EBA':3,
'EBC':4}
237 partname =
str(module[0:3])
238 ros = part_dict[partname]
239 drawer =
int(module[3:])-1
242 if drawer<0
or drawer>63:
243 self.log().critical(
"Invalid module name %s" % module )
251 Get TileBchStatus for a given ADC.
259 Set TileBchStatus for a given ADC.
267 Returns a dictionary with { problemEnum : 'Description'}
272 if not status.isGood():
273 prbs = status.getPrbs()
281 Expects a list of TileBchPrbs::PrbS as input
292 Sets a specific problem
302 Removes a specific problem
312 Print a formatted list of all ADCs with problems.
314 self.log().
info(
"==============================================================")
315 self.log().
info(
" Current list of affected ADCs " )
316 self.log().
info(
"==============================================================")
317 for ros
in range(rosBeg,rosEnd):
321 chnName =
"channel %2i" % chn
327 for prbCode
in sorted(prbs.keys()):
328 prbDesc = prbs[prbCode]
329 msg =
"%s %s %s %2i (%s)" % (modName,chnName,gainName,prbCode,prbDesc)
330 self.log().
info( msg )
334 self.log().
info(
"==============================================================")
340 - if nothing changed : 0
341 - if something changed and complete drawer is now good : -1
342 - if something changed but drawer is not completely good: >0
354 if not newStatus.isGood():
356 if diffCnt>0
and allGood:
363 Updates the internal bad channel cache with the content
364 found in the file. The layout of the file has to follow the
365 TileConditions ASCII file layout.
367 NGO: change this at some point. In a file, not the status word (which
368 depends on the bit pattern version) should be encoded, but the individual problems (enums).
369 For this we need one line per ADC... this requires some modification in the reader.
372 dict = parser.getDict()
373 self.log().
info(
"Updating dictionary from file with %i entries", len(dict))
374 self.log().
info(
"... filename: %s", fileName )
375 for key, stat
in list(dict.items()):
383 statInt =
int(stat[adc])
390 status += TileBchPrbs.IgnoredInHlt
392 status +=
int(stat[adc])
396 def commitToDb(self, db, folderPath, tag, bitPatVer, author, comment,
397 since, until=(MAXRUN,MAXLBK), untilCmt=
None, moduleList=[]):
399 Commits the differences compared to the set of bad channels read in with the
400 initialze function to the provided database.
401 - author : author name (string)
402 - comment : a comment (string)
403 - sinceRun, sinceLbk : start of IOV for which bad channels are valid
404 - untilRun, untilLbk : end of IOV for which bad channels are valid
409 raise Exception (
"DB not open: ", db.databaseId())
410 except Exception
as e:
415 if len(comment)
or isinstance(author,tuple):
416 writer.setComment(author, comment)
420 if moduleList!=[
'CMT']:
421 if since != (MINRUN,MINLBK):
422 justBefore =
list(since)
423 if justBefore[1]>MINLBK:
424 justBefore[1] = justBefore[1]-1
426 justBefore[0] = justBefore[0]-1
427 justBefore[1] = MAXLBK
428 justBefore = tuple(justBefore)
430 self.log().
info(
"Reading db state just before %s, i.e. at %s", since,justBefore)
433 self.log().
info(
"Using previous bad channel list from input DB")
434 self.log().
info(
"And comparing it with new list of bad channels")
438 multiVersion = reader.folderIsMultiVersion()
439 self.log().
info(
"Filling db from %s, resetting old status cache",
list(since))
443 self.log().
info(
"Committing changes to DB \'%s\'", db.databaseId())
444 self.log().
info(
"... using tag \'%s\' and [run,lumi] range: [%i,%i] - [%i,%i]",
445 tag,since[0],since[1],until[0],until[1])
446 if isinstance(author,tuple)
and len(author)==3:
447 self.log().
info(
"... author : \'%s\'", author[0] )
448 self.log().
info(
"... comment: \'%s\'", author[1] )
450 self.log().
info(
"... author : \'%s\'", author )
451 self.log().
info(
"... comment: \'%s\'", comment )
454 loGainDefVec = cppyy.gbl.std.vector(
'unsigned int')()
455 loGainDefVec.push_back(0)
456 hiGainDefVec = cppyy.gbl.std.vector(
'unsigned int')()
457 hiGainDefVec.push_back(0)
458 comChnDefVec = cppyy.gbl.std.vector(
'unsigned int')()
459 comChnDefVec.push_back(0)
460 defVec = cppyy.gbl.std.vector(
'std::vector<unsigned int>')()
461 defVec.push_back(loGainDefVec)
462 defVec.push_back(hiGainDefVec)
463 defVec.push_back(comChnDefVec)
471 if nChange == 0
and (len(moduleList)==0
or modName
not in moduleList
or 'ALL' not in moduleList):
476 self.log().
info(
"Drawer %s reset to GOOD", modName)
477 if modName
not in comment
and (
"ONL" not in folderPath
or "syncALL" not in comment):
479 self.log().
error(
"Comment string - '%s' - doesn't contain drawer %s", comment,modName)
480 writer.zeroBlob(ros,mod)
483 self.log().
info(
"Applying %2i changes to drawer %s", nChange,modName)
484 if modName
not in comment
and (
"ONL" not in folderPath
or "syncALL" not in comment):
486 self.log().
error(
"Comment string - '%s' - doesn't contain drawer %s", comment,modName)
487 drawer = writer.getDrawer(ros,mod)
491 wordsLo = bchDecoder.encode(self.
getAdcStatus(ros,mod,chn,0))
495 wordsHi = bchDecoder.encode(self.
getAdcStatus(ros,mod,chn,1))
496 chBits = wordsHi[0] | chBits
499 drawer.setData(chn,0,0, loBits)
500 drawer.setData(chn,1,0, hiBits)
501 drawer.setData(chn,2,0, chBits)
503 if wordsLo[0] != chBits:
504 self.log().
info(
"Drawer %s ch %2d - sync LG status with HG ", modName,chn)
507 if wordsHi[0] != chBits:
508 self.log().
info(
"Drawer %s ch %2d - sync HG status with LG ", modName,chn)
513 if nUpdates>0
or moduleList==[
'CMT']:
515 self.log().
info(
"Attempting to register %i modified drawers..." , nUpdates)
516 if untilCmt
is not None and untilCmt!=until:
517 if moduleList!=[
'CMT']
and until>since:
518 writer.register(since,until,tag,1)
520 writer.register(since,untilCmt,tag,-1)
522 writer.register(since,until,tag)
524 self.log().
error(
"Aborting update due to errors in comment string")
526 self.log().warning(
"No drawer modifications detected, ignoring commit request")
532 Returns bad status definition
538 Returns bad time status definition