ATLAS Offline Software
Loading...
Searching...
No Matches
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
15import getopt,sys
16
17def 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
29def 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
50def formatIOV(iov):
51 return (int(iov >> 32), int(iov & 0xFFFFFFFF))
52
53#def writeMergedIOV(fdout,outtag,ros,mod,bchDrawer,since,until):
54def 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
94if __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()
void print(char *figname, TCanvas *c1)
#define min(a, b)
Definition cfImp.cxx:40
Class providing the association between TileCal problems and status word bits.
Class holding bad channel problems.
static const TileCalibDrawerBch * getInstance(const coral::Blob &blob)
Returns a pointer to a const TileCalibDrawerBch.
static unsigned int max_gain()
Python compatibility function.
static std::string getDrawerString(unsigned int ros, unsigned int drawer)
Return the drawer name, e.g.
static unsigned int max_chan()
Python compatibility function.
static unsigned int getDrawerIdx(unsigned int ros, unsigned int drawer)
Returns a drawer hash.
static unsigned int getMaxDrawer(unsigned int ros)
Returns the maximal channel number for a given drawer.
showAdcProblems(mgr, ros, mod)
Definition BchCleanup.py:29
formatIOV(iov)
Definition BchCleanup.py:50
writeMergedIOV(ros, mod, since, until)
Definition BchCleanup.py:54