8 Python module for managing TileCal ADC status words.
14 from PyCool
import cool
15 Blob = cppyy.gbl.coral.Blob
19 from TileCalibBlobObjs.Classes
import TileBchStatus, TileCalibUtils, \
20 TileBchPrbs, TileBchDecoder
21 from TileCalibBlobPython.TileCalibCrest
import MINRUN, MINLBK, MAXRUN, MAXLBK, \
22 TileBlobReaderCrest, TileBlobWriterCrest
23 from TileCalibBlobPython.TileCalibLogger
import TileCalibLogger
24 from TileCalibBlobPython.TileCalibTools
import TileASCIIParser
30 This class manages updates to the Tile Calorimeter bad channel database.
31 The usual mode of operation should start with initializing this manager
32 with a current set of bad channels from an existing database.
33 The status of individual ADCs can then be modified using the setAdcStatus,
34 updateFromFile or updateFromDb methods.
35 In a final step, the changes are commited to the database using the commit
42 TileCalibLogger.__init__(self,
"TileBchMgr")
59 Private function, calculating the index of a given ADC
60 for the internal cache.
65 def __updateFromDb(self, db, folderPath, tag, runLumi, fillTable=1, ros=-1, module=-1):
67 Updates the internal bad channel cache with the content
68 found in the database. Server connection string or file name (db) has to
69 be provided. Tag and runLumi are used to locate the set of
70 bad channels to be read from the database.
75 if folderPath
is None:
76 folderPath = self.__folderPath
81 self.log().critical(
"Database is not defined" )
86 self.
__reader = TileBlobReaderCrest(db,folderPath,tag,runLumi[0],runLumi[1])
91 self.
__reader.getIovs(runLumi,(runLumi[0],runLumi[1]+1))
97 rosmin = ros
if ros>=0
else 0
99 for ros
in range(rosmin,rosmax):
100 modmin = module
if module>=0
else 0
102 for mod
in range(modmin,modmax):
103 bch = self.
__reader.getDrawer(ros, mod, runLumi,
False)
106 self.log().warning(
"Missing IOV in condDB: ros=%i mod=%i runLumi=%s", ros,mod,runLumi)
112 adcBits = bch.getData(chn,adc,0)
114 chnBits = bch.getData(chn, 2,0)
119 elif fillTable==1
or fillTable==-1:
121 elif fillTable==2
or fillTable==-2:
126 status1 =
TileBchStatus( bchDecoder.decode(chnBits,adcBits) )
138 def updateFromDb(self, db, folderPath, tag, runLumi, fillTable=1, mode=None, ros=-1, module=-1):
141 self.
__updateFromDb(db, folderPath, tag, runLumi, fillTable, ros, module)
144 def initialize(self, db, folderPath, tag="", runLumi=(MAXRUN,MAXLBK-1), mode=
None, ros=-1, module=-1):
146 Initializes the internal bad channel cache. Any changes applied to the
147 cache previous to calling this function are lost. Typically this function
148 is called once in the beginning to initialize the cache with a set of
149 current bad channels.
151 self.log().
info(
"Initializing from database, resetting all changes!")
173 self.log().
info(
"Updating TileBchStatus::isBad() definition from DB")
176 self.log().
info(
"No TileBchStatus::isBad() definition found in DB, using defaults")
181 self.log().
info(
"Updating TileBchStatus::isBadTiming() definition from DB")
184 self.log().
info(
"No TileBchStatus::isBadTiming() definition found in DB, using defaults")
191 Get TileBchStatus for a given ADC.
198 Set TileBchStatus for a given ADC.
205 Returns a dictionary with { problemEnum : 'Description'}
209 if not status.isGood():
210 prbs = status.getPrbs()
218 Expects a list of TileBchPrbs::PrbS as input
228 Sets a specific problem
237 Removes a specific problem
246 convert module name to ros,drawer
249 part_dict = {
'LBA':1,
'LBC':2,
'EBA':3,
'EBC':4}
250 partname =
str(module[0:3])
251 ros = part_dict[partname]
252 drawer =
int(module[3:])-1
255 if drawer<0
or drawer>63:
256 self.log().critical(
"Invalid module name %s" % module )
264 Get TileBchStatus for a given ADC.
272 Set TileBchStatus for a given ADC.
280 Returns a dictionary with { problemEnum : 'Description'}
285 if not status.isGood():
286 prbs = status.getPrbs()
294 Expects a list of TileBchPrbs::PrbS as input
305 Sets a specific problem
315 Removes a specific problem
325 Print a formatted list of all ADCs with problems.
327 self.log().
info(
"==============================================================")
328 self.log().
info(
" Current list of affected ADCs " )
329 self.log().
info(
"==============================================================")
330 for ros
in range(rosBeg,rosEnd):
334 chnName =
"channel %2i" % chn
340 for prbCode
in sorted(prbs.keys()):
341 prbDesc = prbs[prbCode]
342 msg =
"%s %s %s %2i (%s)" % (modName,chnName,gainName,prbCode,prbDesc)
343 self.log().
info( msg )
347 self.log().
info(
"==============================================================")
353 - if nothing changed : 0
354 - if something changed and complete drawer is now good : -1
355 - if something changed but drawer is not completely good: >0
367 if not newStatus.isGood():
369 if diffCnt>0
and allGood:
376 Updates the internal bad channel cache with the content
377 found in the file. The layout of the file has to follow the
378 TileConditions ASCII file layout.
380 NGO: change this at some point. In a file, not the status word (which
381 depends on the bit pattern version) should be encoded, but the individual problems (enums).
382 For this we need one line per ADC... this requires some modification in the reader.
384 parser = TileASCIIParser(fileName,
'Bch')
385 dict = parser.getDict()
386 self.log().
info(
"Updating dictionary from file with %i entries", len(dict))
387 self.log().
info(
"... filename: %s", fileName )
388 for key, stat
in list(dict.items()):
396 statInt =
int(stat[adc])
403 status += TileBchPrbs.IgnoredInHlt
405 status +=
int(stat[adc])
409 def commitToDb(self, db, folderPath, tag, bitPatVer, author, comment,
410 since, moduleList=[]):
412 Commits the differences compared to the set of bad channels read in with the
413 initialze function to the provided database.
414 - author : author name (string)
415 - comment : a comment (string)
416 - sinceRun, sinceLbk : start of IOV for which bad channels are valid
419 writer = TileBlobWriterCrest(db,folderPath,
'Bch')
420 if len(comment)
or isinstance(author,tuple):
421 writer.setComment(author, comment)
425 if moduleList!=[
'CMT']:
426 if since != (MINRUN,MINLBK):
427 justBefore =
list(since)
428 if justBefore[1]>MINLBK:
429 justBefore[1] = justBefore[1]-1
431 justBefore[0] = justBefore[0]-1
432 justBefore[1] = MAXLBK
433 justBefore = tuple(justBefore)
435 self.log().
info(
"Reading db state just before %s, i.e. at %s", since,justBefore)
438 self.log().
info(
"Using previous bad channel list from input DB")
439 self.log().
info(
"And comparing it with new list of bad channels")
441 self.log().
info(
"Filling db from %s, resetting old status cache",
list(since))
445 self.log().
info(
"Committing changes to DB \'%s\'", db)
446 self.log().
info(
"... using tag \'%s\' and [run,lumi] [%i,%i]",
447 tag,since[0],since[1])
448 if isinstance(author,tuple)
and len(author)==3:
449 self.log().
info(
"... author : \'%s\'", author[0] )
450 self.log().
info(
"... comment: \'%s\'", author[1] )
452 self.log().
info(
"... author : \'%s\'", author )
453 self.log().
info(
"... comment: \'%s\'", comment )
456 loGainDefVec = cppyy.gbl.std.vector(
'unsigned int')()
457 loGainDefVec.push_back(0)
458 hiGainDefVec = cppyy.gbl.std.vector(
'unsigned int')()
459 hiGainDefVec.push_back(0)
460 comChnDefVec = cppyy.gbl.std.vector(
'unsigned int')()
461 comChnDefVec.push_back(0)
462 defVec = cppyy.gbl.std.vector(
'std::vector<unsigned int>')()
463 defVec.push_back(loGainDefVec)
464 defVec.push_back(hiGainDefVec)
465 defVec.push_back(comChnDefVec)
474 if (modName
in moduleList
or 'ALL' in moduleList):
476 drawerR = self.
__reader.getDrawer(ros, mod,
None,
False,
False)
478 writer.getDrawer(ros,mod,drawerR)
480 writer.zeroBlob(ros,mod)
484 self.log().
info(
"Drawer %s reset to GOOD", modName)
485 if modName
not in comment
and (
"ONL" not in folderPath
or "syncALL" not in comment):
487 self.log().
error(
"Comment string - '%s' - doesn't contain drawer %s", comment,modName)
488 writer.zeroBlob(ros,mod)
491 self.log().
info(
"Applying %2i changes to drawer %s", nChange,modName)
492 if modName
not in comment
and (
"ONL" not in folderPath
or "syncALL" not in comment):
494 self.log().
error(
"Comment string - '%s' - doesn't contain drawer %s", comment,modName)
495 drawer = writer.getDrawer(ros,mod)
499 wordsLo = bchDecoder.encode(self.
getAdcStatus(ros,mod,chn,0))
503 wordsHi = bchDecoder.encode(self.
getAdcStatus(ros,mod,chn,1))
504 chBits = wordsHi[0] | chBits
507 drawer.setData(chn,0,0, loBits)
508 drawer.setData(chn,1,0, hiBits)
509 drawer.setData(chn,2,0, chBits)
511 if wordsLo[0] != chBits:
512 self.log().
info(
"Drawer %s ch %2d - sync LG status with HG ", modName,chn)
515 if wordsHi[0] != chBits:
516 self.log().
info(
"Drawer %s ch %2d - sync HG status with LG ", modName,chn)
521 if nUpdates>0
or moduleList==[
'CMT']:
523 self.log().
info(
"Attempting to register %i modified drawers..." , nUpdates)
524 writer.register(since,tag)
526 self.log().
error(
"Aborting update due to errors in comment string")
528 self.log().warning(
"No drawer modifications detected, ignoring commit request")
534 Returns bad status definition
540 Returns bad time status definition