ATLAS Offline Software
BchCleanup.py
Go to the documentation of this file.
1 #!/bin/env python
2 
3 # Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
4 #
5 # File: BchCleanup.py
6 # Package: TileCalibBlobPython
7 # Purpose: Clean up BCH folders from an input bch-input-sqlite.db file. Output saved to output sqlite.db file.
8 # Too many reads from input file, so we avoid reading from the DB. Oracle DB tag to be cleaned
9 # must be copied into input sqlite.db file beforehand, using AtlCoolCopy.
10 #
11 # Guilherme Lima - 2013-08-07
12 #
13 # WARNING: options explained in usage() have not been tested!!! Probably they WON'T work as expected!!
14 
15 import getopt,sys
16 
17 def usage():
18  print ("Usage: ",sys.argv[0]," [OPTION] ... ")
19  print ("""Uses bch-input-sqlite.db file as input, joins adjacent IOVs with same contents, keeping the
20  comments from the earliest one. Results written to bch-output-sqlite.db""")
21  print ("")
22  print ("-h, --help shows this help")
23  print ("-f, --folder= specify status folder to use ONL01, OFL01 or OFL02 ")
24  print ("-t, --tag= specify tag to use, f.i. UPD1 or UPD4")
25  print ("-o, --outtag= specify output tag to be used for cleaned up result, f.i. UPD4-99")
26  print ("-i, --instance= specify DB instance (CONDBR2 or COMP200 or OFLP200)")
27  print ("")
28 
29 def showAdcProblems(mgr,ros,mod):
30  modName = TileCalibUtils.getDrawerString(ros,mod)
31  for chn in range(TileCalibUtils.max_chan()):
32  for adc in range(TileCalibUtils.max_gain()):
33 
34  stat = mgr.getAdcStatus(ros,mod,chn,adc)
35  prbs = mgr.getAdcProblems(ros,mod,chn,adc)
36  if len(prbs):
37  msg = "%s %2i %1i " % (modName,chn,adc)
38  for prbCode in sorted(prbs.keys()):
39  prbDesc = prbs[prbCode]
40  msg += " %5i (%s)" % (prbCode,prbDesc)
41  if stat.isBad():
42  msg += " => BAD"
43  elif stat.isAffected():
44  msg += " => Affected"
45  elif stat.isGood():
46  msg += " => good"
47  log.debug(msg)
48 
49 
50 def formatIOV(iov):
51  return (int(iov >> 32), int(iov & 0xFFFFFFFF))
52 
53 #def writeMergedIOV(fdout,outtag,ros,mod,bchDrawer,since,until):
54 def writeMergedIOV(ros,mod,since,until):
55  """ Writes out blob into folder fdout, at channel related to
56  ros,mod and with validity range given by since,until
57  """
58  log.info("Writing merged IOV: [%i,%i]-[%i,%i)", (since>>32),(since&0xffffffff),(until>>32),(until&0xffffffff))
59 
60  chanNum = TileCalibUtils.getDrawerIdx(ros,mod)
61  #iov1 = TileCalibTools.getCoolValidityKey(since,False)
62  #iov2 = TileCalibTools.getCoolValidityKey(until,False)
63 
64  #chid=obj.channelId()
65 
66 
75 
76  #fdout.storeObject(since, until, blob, chanNum, outtag, True)
77 
78  runSince = since>>32
79  lumSince = since&0xffffffff
80  runUntil = until>>32
81  lumUntil = until&0xffffffff
82 
83  #.. fix IOVs [r1,l1]-[r2,MAXLBK] --> [r1,l1]-[r2+1,0]
84  if lumUntil == 4294967295 and runUntil != 2147483647:
85  runUntil += 1
86  lumUntil = 0
87 
88  msg = 'AtlCoolCopy \"%s\" \"%s\" -folder /TILE/OFL02/STATUS/ADC -tag %s -rls %i %i -rlu %i %i -alliov -outtag %s -ch %i -nrls %i %i -nrlu %i %i' % (ischema,oschema,folderTag,runSince,lumSince,runSince,lumSince+1,outtagFull,chanNum,runSince,lumSince,runUntil,lumUntil)
89  print(msg)
90 
91 
92 
93 
94 if __name__ == "__main__":
95 
96  letters = "ht:f:o:i"
97  keywords = ["help","tag=","folder=","outtag=","instance="]
98  try:
99  opts, extraparams = getopt.getopt(sys.argv[1:],letters,keywords)
100  except getopt.GetoptError as err:
101  print (str(err))
102  usage()
103  sys.exit(2)
104 
105  # defaults
106  instance='OFLP200'
107  folderPath = "/TILE/OFL02/STATUS/ADC"
108  tag = "OFLCOND-MC16-SDR-28"
109  outtag = "test"
110 
111  print ('opts:',opts)
112  for o, a in opts:
113  a = a.strip()
114  if o in ("-f","--folder"):
115  folderPath = "/TILE/%s/STATUS/ADC" % a
116  elif o in ("-t","--tag"):
117  tag = a
118  elif o in ("-o","--outtag"):
119  outtag = a
120  elif o in ("-i","--instance"):
121  instance = a
122  #elif o in ("-s","--schema"):
123  # schema = a
124  #elif o in ("-r","--run"):
125  # run = int(a)
126  #elif o in ("-l","--lumi"):
127  # lumi = int(a)
128  elif o in ("-h","--help"):
129  usage()
130  sys.exit(2)
131  else:
132  raise RuntimeError("unhandled option")
133 
134 
135  from TileCalibBlobPython.TileCalibLogger import getLogger
136  log = getLogger("BchCleanup")
137  import logging
138  log.setLevel(logging.INFO)
139 
140  ischema = 'sqlite://;schema=bch-input-sqlite.db;dbname='+instance
141  oschema = 'sqlite://;schema=bch-output-sqlite.db;dbname='+instance
142  log.info("ischema=%s",ischema)
143  log.info("oschema=%s", oschema)
144 
145 
146  from TileCalibBlobPython import TileCalibTools
147  from TileCalibBlobPython import TileBchTools
148  from TileCalibBlobObjs.Classes import TileCalibUtils, TileBchDecoder, \
149  TileCalibDrawerBch, TileBchStatus
150 
151  #=== open databases
152  idb = TileCalibTools.openDbConn(ischema,'READONLY')
153  #odb = TileCalibTools.openDbConn(oschema,'RECREATE')
154 
155  #-- Workout folderTag
156  folderTag = TileCalibTools.getFolderTag(idb if 'CONDBR2' in ischema else ischema, folderPath, tag)
157 
158  #-- Blob I/O classes
159  blobReader = TileCalibTools.TileBlobReader(idb,folderPath, folderTag)
160  #blobWriter = TileCalibTools.TileBlobWriter(odb,folderPath, 'Bch', True) # arg4: False:ONL, True:OFL, default=True
161  #blobWriter.setComment("lima","Cleanup of bad channels folder, by merging adjacent folders when identical")
162 
163  outtagFull = 'TileOfl02StatusAdc-'+outtag
164  #outFolder = odb.getFolder(folderPath)
165 
166  #-- initialize BchMgr from input DB
167  log.info("Input folder for cleaning: %s with tag %s", folderPath, folderTag)
168 
169 
177  msg = 'AtlCoolCopy \"%s\" \"%s\" -folder /TILE/OFL02/STATUS/ADC -tag %s -outtag %s -ch1 0 -ch2 19 -create' % (ischema,oschema,folderTag,outtagFull)
178  print(msg)
179 
180 
181  #=== Loop over DB contents
182 
183  #=== get the channel status (if it is bad and will be masked)
184  #=== the channel status depends on the definition of isBad stored
185  #=== in the database drawer 1, channel 0
186  #=== isAffected = has a problem not included in isBad definition
187  #=== isGood = has no problem at all
188 
189  rosinput = int(sys.argv[1]) if len(sys.argv)>1 else 0
190  log.info("rosinput=%i", rosinput)
191  if rosinput==0:
192  rosmin=1
193  rosmax=5
194  else:
195  rosmin=rosinput
196  rosmax=rosinput+1
197 
198  for ros in range(rosmin,rosmax):
199  for mod in range(0, min(64,TileCalibUtils.getMaxDrawer(ros))):
200 
202  log.info(40*'='+" ros %d, drawer %s", ros, modName)
203 
204  dbobjs = blobReader.getDBobjsWithinRange(ros, mod)
205  if dbobjs is None:
206  raise Exception("No DB objects retrieved for ros=%d mod=%d (%s)" % (ros,mod,modName))
207 
208  #print ("# IOVs: %d - will try to print container below..." % len(dbobjs))
209  #print (dbobjs)
210 
211  #.. keep track of validity range of identical and adjacent sets of conditions
212  mergedSince = mergedUntil = None
213 
214  iovCounter = 0
215  objPrev = obj = None
216  blobPrev = blob = None
217  calibDrawerPrev = calibDrawer = None
218  runPrev = run = -1
219  lumPrev = lum = -1
220 
221  #.. Loop over dbobjs
222  while dbobjs.goToNext():
223  iovCounter += 1
224  objPrev = obj
225  blobPrev = blob
226  calibDrawerPrev = calibDrawer
227  runPrev = run
228  lumPrev = lum
229 
230  obj = dbobjs.currentRef()
231  objsince = obj.since()
232  objuntil = obj.until()
233 
234  #.. initialize mergedSince,mergeUntil, which keep track of validity range of last set of identical conditions
235  if mergedSince is None and mergedUntil is None:
236  mergedSince = objsince
237  mergedUntil = objuntil
238 
239  run = objsince >> 32
240  lum = objsince & 0xFFFFFFFF
241  blob = obj.payload()[0]
242 
243  calibDrawer = None
244 
245  if iovCounter%10 == 0:
246  log.info("Heartbeat %d: blob size=%d - [%d,%d]-[%d,%d)",
247  iovCounter, blob.size(), run, lum, (objuntil>>32), (objuntil&0xFFFFFFFF) )
248  else:
249  log.debug("blob size=%d - [%d,%d]-[%d,%d)",
250  blob.size(), run, lum, (objuntil>>32), (objuntil&0xFFFFFFFF))
251 
252  if blob.size() == 596:
253  try:
254  calibDrawer = TileCalibDrawerBch.getInstance(blob)
255  except Exception as err:
256  log.error("ros=%i mod=%i last read: runPrev=%i lumPrev=%i\n %s",
257  ros, mod, runPrev, lumPrev, str(err))
258 
259  if calibDrawer is None:
260  #.. Non-existent, zero-sized or invalid blobs
261  if calibDrawerPrev is None:
262  # push upper limit to current IOV's upper limit
263  mergedUntil = objuntil
264  if blob is None:
265  log.warning( "extending IOV due to non-existent blob!!!" )
266  elif blob.size()==0:
267  log.info( "extending IOV due to zero-size blob!!!" )
268  else:
269  log.warning( "extending IOV due to invalid-size blob!!!" )
270  continue
271 
272  else:
273  # non-identical blobs: write previous blob with new saved validity range...
274  log.info("types: %s %s", type(blob), type(calibDrawerPrev))
275  #writeMergedIOV(outFolder, outtagFull, ros, mod, calibDrawerPrev, mergedSince, mergedUntil)
276  writeMergedIOV(ros, mod, mergedSince, mergedUntil)
277  # ...and then start a new IOV based on current blob's validity range
278  mergedSince = objsince
279  mergedUntil = objuntil
280  tempRunLum = "Starting new IOV at: [%d,%d]" % (mergedSince>>32, mergedSince&0xffffffff)
281  if blob is None:
282  log.warning( "%s (non-existent blob!!!)", tempRunLum )
283  elif blob.size()==0:
284  log.info( "%s (zero-size blob!!!)", tempRunLum )
285  else:
286  log.warning( "%s (invalid-size blob!!!)", tempRunLum )
287  continue
288 
289  #.. Only good calibDrawers reach here
290 
291  bchDecoder = TileBchDecoder(calibDrawer.getBitPatternVersion())
292 
293  #=== create bad channel manager
294  mgr = TileBchTools.TileBchMgr()
295  mgr.setLogLvl(logging.ERROR)
296  mgr.initialize(idb, folderPath, folderTag, (run,lum))
297  log.debug("TileBchMgr initialized.")
298 
299  #.. for first IOV, print status summary
300  if objPrev is None:
301  showAdcProblems(mgr,ros,mod)
302 
303  #.. comparing current and previous blobs ===============
304  identical = True
305 
306  if objPrev is not None:
307  if calibDrawerPrev is None:
308  identical = False
309  else:
310  sizelo = calibDrawerPrev.getObjSizeByte()//4
311  sizehi = calibDrawer.getObjSizeByte()//4
312  if (sizelo != sizehi):
313  log.error("Object sizes are different for ROS %s (%s %s) drawer %s", ros, sizelo, sizehi, modName)
314 
315  typelo = calibDrawerPrev.getObjType()
316  typehi = calibDrawer.getObjType()
317  #ov = flt.getObjVersion()
318  #no = flt.getNObjs()
319  #nc = flt.getNChans()
320  #ng = flt.getNGains()
321 
322  if (typelo != typehi):
323  log.error("Object types %s %s are different", typelo, typehi)
324  sys.exit()
325 
326  #=== get all problems of this module
327  #showAdcProblems(mgr,ros,mod)
328 
329  #.. check for identical conditions
330  for chn in range(TileCalibUtils.max_chan()):
331  # chnName = " %2i" % chn
332  #if identical:
333  for adc in range(TileCalibUtils.max_gain()):
334  #if identical:
335  for ind in range(1): # 4 values per channel/adc
336 
337  #=== build status from both adc and channel bits
338  adcBits = calibDrawer.getData(chn, adc, ind)
339  chnBits = calibDrawer.getData(chn, 2, ind)
340  status = TileBchStatus( bchDecoder.decode(chnBits,adcBits) )
341 
342  adcBits = calibDrawerPrev.getData(chn, adc, ind)
343  chnBits = calibDrawerPrev.getData(chn, 2, ind)
344  statusPrev = TileBchStatus( bchDecoder.decode(chnBits,adcBits) )
345 
346  adclo = calibDrawerPrev.getData(chn, adc, ind)
347  adchi = calibDrawer.getData(chn, adc, ind)
348  chnlo = calibDrawerPrev.getData(chn, 2, ind)
349  chnhi = calibDrawer.getData(chn, 2, ind)
350  diff = adclo - adchi + chnlo - chnhi
351 
352  if not (status==statusPrev):
353  identical = False
354  log.info("chn=%i adc=%i ind=%i - vlo=%i, vhi=%i, diffs=%i %i", chn, adc, ind, adclo+chnlo, adchi+chnhi, adclo-adchi, chnlo-chnhi)
355  #break
356 
357  #.. at this point, merge if obj is identical to objPrev
358  if identical is True:
359  # push upper limit to current IOV's upper limit
360  mergedUntil = objuntil
361  else:
362  showAdcProblems(mgr,ros,mod)
363  # non-identical blobs: write previous blob with new saved validity range...
364  log.info("types: %s %s", type(blob), type(calibDrawerPrev))
365  writeMergedIOV(ros, mod, mergedSince, mergedUntil)
366  #writeMergedIOV(outFolder,outtagFull,ros,mod,calibDrawerPrev,mergedSince,mergedUntil)
367  # ...and then start a new IOV based on current blob's validity range
368  mergedSince = objsince
369  mergedUntil = objuntil
370  log.info("Starting new IOV at: [%d,%d]",
371  mergedSince>>32, mergedSince&0xffffffff)
372 
373  #.. end of loop over dbobjs
374 
375  if objuntil == 0x7fffffffffffffff:
376  log.info("Writing last IOV: calling writeMergedIOV by hand...")
377  #writeMergedIOV(outFolder,outtagFull,ros,mod,calibDrawerPrev,mergedSince,mergedUntil)
378  writeMergedIOV(ros,mod,mergedSince,mergedUntil)
379 
380  #=== print all bad channels
381  #log.info("listing bad channels")
382  #mgr.listBadAdcs()
383 
384  #from TileCalibBlobPython.TileCalibTools import MINRUN, MINLBK, MAXRUN, MAXLBK
385  #blobWriter.register((MINRUN,MINLBK),(MAXRUN,MAXLBK),folderTag)
386 
387  #=== close DB
388  idb.closeDatabase()
BchCleanup.usage
def usage()
Definition: BchCleanup.py:17
python.Classes.TileBchDecoder
TileBchDecoder
Definition: TileCalib/TileCalibBlobObjs/python/Classes.py:13
TileCalibUtils::getMaxDrawer
static unsigned int getMaxDrawer(unsigned int ros)
Returns the maximal channel number for a given drawer.
Definition: TileCalibUtils.cxx:136
TileCalibDrawerBch::getInstance
static const TileCalibDrawerBch * getInstance(const coral::Blob &blob)
Returns a pointer to a const TileCalibDrawerBch.
Definition: TileCalibDrawerBch.cxx:28
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
BchCleanup.writeMergedIOV
def writeMergedIOV(ros, mod, since, until)
Definition: BchCleanup.py:54
TileCalibUtils::max_gain
static unsigned int max_gain()
Python compatibility function.
Definition: TileCalibUtils.h:114
BchCleanup.showAdcProblems
def showAdcProblems(mgr, ros, mod)
Definition: BchCleanup.py:29
plotBeamSpotVxVal.range
range
Definition: plotBeamSpotVxVal.py:195
DerivationFramework::TriggerMatchingUtils::sorted
std::vector< typename T::value_type > sorted(T begin, T end)
Helper function to create a sorted vector from an unsorted one.
min
#define min(a, b)
Definition: cfImp.cxx:40
BchCleanup.formatIOV
def formatIOV(iov)
Definition: BchCleanup.py:50
TileCalibUtils::getDrawerString
static std::string getDrawerString(unsigned int ros, unsigned int drawer)
Return the drawer name, e.g.
Definition: TileCalibUtils.cxx:145
python.Classes.TileBchStatus
TileBchStatus
Definition: TileCalib/TileCalibBlobObjs/python/Classes.py:16
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
TileCalibUtils::max_chan
static unsigned int max_chan()
Python compatibility function.
Definition: TileCalibUtils.h:112
Muon::print
std::string print(const MuPatSegment &)
Definition: MuonTrackSteering.cxx:28
str
Definition: BTagTrackIpAccessor.cxx:11
TileCalibUtils::getDrawerIdx
static unsigned int getDrawerIdx(unsigned int ros, unsigned int drawer)
Returns a drawer hash.
Definition: TileCalibUtils.cxx:60
python.CaloCondLogger.getLogger
def getLogger(name="CaloCond")
Definition: CaloCondLogger.py:16