8 Python helper module for managing COOL DB connections and CaloCondBlobs.
13 from PyCool
import cool
19 from CaloCondBlobAlgs.CaloCondLogger
import CaloCondLogger, getLogger
25 MAXRUN = cool.Int32Max
26 MAXLBK = cool.UInt32Max
27 UNIX2COOL = 1000000000
28 UNIXTMAX = cool.Int32Max
34 Returns the common Calo prefix used for all COOL folders
42 Returns the run-lumi type folder description needed to read back the folder content
43 as a CondAttrListCollection in Athena.
45 desc =
'<timeStamp>run-lumi</timeStamp>'
46 desc+=
'<addrHeader><address_header service_type="71" clid="1238547719" /></addrHeader>'
47 desc+=
'<typeName>CondAttrListCollection</typeName>'
53 type = re.compile(
".*<timeStamp>(.*)</timeStamp>.*").
search(folderDescr)
55 raise Exception(
"No folder type info found in \'%s\'" % folderDescr)
56 return type.groups()[0]
60 def openDb(db, instance, mode="READONLY", schema="COOLOFL_CALO", sqlfn="caloSqlite.db"):
62 Opens a COOL db connection.
63 - db: The DB type. The following names are recognized:
64 * SQLITE: Opens file mentioned in sqlfn parameter
65 * ORACLE or FRONTIER: Opens ORACLE DB, forces READONLY
66 - instance: One of valid instances - CONDBR2 OFLP200 COMP200 CMCP200
67 - mode: Can be READONLY (default), RECREATE or UPDATE
68 - schema: One of valid schemas - COOLONL_CALO COOLOFL_CALO COOLONL_LAR COOLOFL_LAR COOLONL_TILE COOLOFL_TILE
69 - sqlfn: Name of sqlite file if db is SQLITE
73 validDb = [
"SQLITE",
"ORACLE",
"FRONTIER"]
75 raise Exception(
"DB not valid: %s, valid DBs are: %s" % (db,validDb) )
76 elif db ==
"ORACLE" or db ==
"FRONTIER":
80 validInstance = [
"COMP200",
"CONDBR2",
"CMCP200",
"OFLP200"]
81 if instance
not in validInstance:
82 raise Exception(
"Instance not valid: %s, valid instance are: %s" % (instance,validInstance) )
85 validSchema = [
"COOLONL_CALO",
"COOLOFL_CALO",
"COOLONL_LAR",
"COOLOFL_LAR",
"COOLONL_TILE",
"COOLOFL_TILE"]
86 if schema
not in validSchema:
87 raise Exception(
"Schema not valid: %s, valid schemas are: %s" % (schema,validSchema) )
92 if mode==
"READONLY" and not os.path.exists(sqlfn):
93 raise Exception(
"Sqlite file %s does not exist" % (sqlfn) )
94 if (mode==
"RECREATE" or mode==
"UPDATE")
and not os.path.exists(os.path.dirname(sqlfn)):
95 dirn=os.path.dirname(sqlfn)
98 connStr=
"sqlite://X;schema=%s;dbname=%s" % (sqlfn,instance)
100 connStr=
'frontier://ATLF/()/;schema=ATLAS_%s;dbname=%s' % (schema,instance)
102 connStr=
'oracle://%s;schema=ATLAS_%s;dbname=%s' % (
'ATLAS_COOLPROD',schema,instance)
104 connStr=schema+
'/'+instance
112 Opens a COOL db connection.
113 - connStr: The DB connection string
114 - mode: Can be READONLY (default), RECREATE or UPDATE
115 or ORACLE or FRONTIER if connStr is only short name of the database
119 splitname=connStr.split(
'/')
120 if (len(splitname)!=2):
124 instance=splitname[1]
126 connStr_new=
'oracle://%s;schema=ATLAS_%s;dbname=%s' % (
'ATLAS_COOLPROD',schema,instance)
128 connStr_new=
'frontier://ATLF/()/;schema=ATLAS_%s;dbname=%s' % (schema,instance)
131 dbSvc = cool.DatabaseSvcFactory.databaseService()
132 log.info(
"---------------------------------------------------------------------------------" )
133 log.info(
"-------------------------- CaloCondTools.openDbConn -----------------------------" )
134 log.info(
"- using COOL version %s", dbSvc.serviceVersion() )
135 log.info(
"- opening CaloDb: %s",connStr_new )
136 log.info(
"- mode: %s", mode )
137 log.info(
"---------------------------------------------------------------------------------" )
140 if mode
in [
"READONLY",
"ORACLE",
"FRONTIER",
"",
None]:
143 db=dbSvc.openDatabase(connStr_new,
True)
144 except Exception
as e:
146 log.critical(
"Could not connect to %s" % connStr_new )
149 elif mode==
"RECREATE":
151 dbSvc.dropDatabase(connStr_new)
153 db = dbSvc.createDatabase(connStr_new)
154 except Exception
as e:
156 log.critical(
"Could not create database, giving up..." )
162 db=dbSvc.openDatabase(connStr_new,
False)
163 except Exception
as e:
165 log.warning(
"Could not connect to \'%s\', trying to create it....", connStr_new )
167 db=dbSvc.createDatabase(connStr_new)
168 except Exception
as e:
170 log.critical(
"Could not create database, giving up..." )
174 log.error(
"Mode \"%s\" not recognized", mode )
181 Returns COOL timeStamp build from run and lumi block numbers
183 return (
int(runNum)<<32) +
int(lbkNum)
189 Returns run and lumi block numbers from COOL timeStamp
191 return (
int(iov >> 32),
int(iov & 0xFFFFFFFF))
197 Returns UNIX time stamp given an input time string
199 return int(time.mktime(time.strptime(timeString,
"%Y-%m-%d %H:%M:%S")))
205 The interpretation of pointInTime depends on their type:
206 - tuple(int,int) : run and lbk number
207 - integer : Values are interpreted as unix time stamps
208 - string : time stamp of format 'yyyy-mm-dd hh:mm:ss'
214 if isinstance(pointInTime, str):
218 if isinstance(pointInTime, int):
220 validityKey = pointInTime * UNIX2COOL
223 validityKey =
int(time.time()) * UNIX2COOL
225 validityKey = cool.ValidityKeyMax
227 elif isinstance(pointInTime, tuple):
231 raise Exception(
"Unrecognized pointInTime type=%s" %
type(pointInTime))
232 return cool.ValidityKey(validityKey)
238 Returns cell subHash given partition,module,sample, and tower (TILE only)
241 raise Exception(
'getCellHash only available for TileCells.')
244 if part == 1
or part == 2:
246 elif part == 3
or part == 4:
247 if sample == 3
or (sample==1
and tower==9)
or (sample==2
and tower==8):
255 if section==0
or side==0
or module>63
or sample>3
or tower>15:
256 raise Exception(
'Non-physical cell specification')
259 hash = [0, 1, -1, -1, 2, 3, -1, -1, 4, 5, 6, -1, 7, 8, -1, -1, 9, 10, 11, -1, 12, 13, -1, -1, 14, 15, 16, -1, 17, 18, -1, -1, 19, 20, 4416, -1, 21, 4417, -1, -1, -1, 2880, 2881, 4418, 2882, 2883, -1, 4419, 2884, 2885, 2886, -1, 2887, 2888, -1, 4420, 2889, 2890, -1, -1, 2891, -1, -1, 4421, 1408, 1409, 1410, -1, 1411, 1412, -1, -1, 1413, 1414, 1415, -1, 1416, 1417, -1, -1, 1418, 1419, 1420, -1, 1421, 1422, -1, -1, 1423, 1424, 1425, -1, 1426, 1427, -1, -1, 1428, 1429, 4800, -1, 1430, 4801, -1, -1, -1, 3648, 3649, 4802, 3650, 3651, -1, 4803, 3652, 3653, 3654, -1, 3655, 3656, -1, 4804, 3657, 3658, -1, -1, 3659, -1, -1, 4805]
263 modOffset = [22,23,12,12,6,6]
269 return hash[sideOffset*16*4+tower*4+sample]+modOffset[sideOffset+2*(section-1)]*module
281 CaloBlobReader is a helper class, managing the details of COOL interactions
288 - db : db should be an open database connection
289 - folder: full folder path
290 - tag : The folder tag, e.g. \"000-00\"
293 CaloCondLogger.__init__(self,
"CaloBlobReader")
299 except Exception
as e:
300 self.log().critical( e )
304 validFolderTypes = (
"run-lumi",
"time")
308 raise Exception(
"Invalid folder type found: \'%s\'" % self.
__folderType)
320 Returns a CaloCondBlob object for the given system.
324 self.log().
debug(
"Validity key is %s", validityKey)
327 key = (systemId,validityKey)
331 channelId = cool.ChannelId(systemId)
332 obj = self.
__folder.findObject(validityKey, channelId, self.
__tag)
333 self.log().
debug(
"Fetching from DB: %s", obj)
334 blob = obj.payload()[0]
335 self.log().
debug(
"blob size: %d", blob.size())
339 blob = obj.payload()[0]
340 self.log().
debug(
"blob size: %d", blob.size())
343 flt = g.CaloCondBlobFlt.getInstance(blob)
345 except Exception
as e:
346 self.log().
error(
"Fetching of systemId=%i failed with exception %s",systemId,e)
350 def getDBobjsWithinRange(self, chan, point1inTime=(0,0), point2inTime=(2147483647,4294967295), printError=
True):
352 Returns all DB objects for the given COOL channel, within given validity range -- default: [0-Infinity)
359 self.log().
debug(
"Validity key range is %s - %s", validityKey1,validityKey2)
363 dbChanSel = cool.ChannelSelection(chan)
365 objs = self.
__folder.browseObjects(validityKey1,validityKey2,dbChanSel,self.
__tag)
366 except Exception
as e:
368 self.log().
error(
"CaloCondTools.getDBobjsWithinRange(): Fetching of COOL_chan=%i failed with exception %s", chan,e)
375 Returns true if MultiVersion folder is connected
377 if self.
__folder.versioningMode()==cool.FolderVersioning.MULTI_VERSION:
393 Helper class that enables writing to Calo DB
397 def __init__(self, db, folderPath, caloBlobType=None,
398 isMultiVersionFolder=True, isRunLumiTimeStamp=True):
401 - db : db should be an open database connection
402 - folderPath: full folder path to create or update
406 CaloCondLogger.__init__(self,
"CaloBlobWriter")
412 folderMode = cool.FolderVersioning.MULTI_VERSION
413 if not isMultiVersionFolder:
414 folderMode = cool.FolderVersioning.SINGLE_VERSION
422 if self.
__db.existsFolder(folderPath):
425 modeInCool = self.
__folder.versioningMode()
426 if modeInCool!=folderMode:
427 str =
"Incompatible folder mode detected, COOL folder has type "
428 if modeInCool==cool.FolderVersioning.MULTI_VERSION:
435 payloadSpec = cool.RecordSpecification()
436 payloadSpec.extend(
'CaloCondBlob16M', cool.StorageType.Blob16M )
437 folderSpec = cool.FolderSpecification(folderMode, payloadSpec)
438 self.
__folder = db.createFolder(folderPath, folderSpec, folderDescr,
True)
439 except Exception
as e:
440 self.log().critical( e )
448 def register(self, since=(MINRUN,MINLBK), until=(MAXRUN,MAXLBK), tag=
""):
450 Registers the folder in the database.
451 - since: lower limit of IOV
452 - until: upper limit of IOV
453 - tag : The cool folder tag to write to
455 The interpretation of the 'since' and 'until' inputs depends on their type:
456 - tuple(int,int) : run and lbk number
457 - integer : Values are interpreted as unix time stamps
458 If since<0, current time is assumed
459 If until<0, infinity is assumed
460 - string : time stamp of format 'yyyy-mm-dd hh:mm:ss'
465 raise Exception(
"Inconsistent types: since=%s, until=%s" % (
type(since),
type(until)))
469 if self.
__folder.versioningMode()==cool.FolderVersioning.SINGLE_VERSION:
473 self.log().warning(
"Trying to store with tag \"%s\" to SINGLE_VERSION folder", tag )
474 self.log().warning(
"... resetting tag to \"\"!" )
480 if untilCool <= sinceCool:
481 raise Exception(
"Until(%i) <= Since(%i)" % (untilCool,sinceCool))
485 if isinstance(since, tuple):
486 iovString =
"[%i,%i] - [%i,%i]" % (since[0],since[1],until[0],until[1])
488 sinceInfo = time.localtime( sinceCool//UNIX2COOL )
489 untilInfo = time.localtime(
min(UNIXTMAX, (untilCool//UNIX2COOL)))
490 untilStr =
"<infinity>"
491 if untilCool<cool.ValidityKeyMax:
492 untilStr = time.asctime(untilInfo)
493 if (untilCool//UNIX2COOL)>UNIXTMAX:
494 untilStr =
" > "+untilStr
495 iovString =
"[%s] - [%s]" % (time.asctime(sinceInfo), untilStr)
502 self.log().
info(
"... with IOV : %s", iovString )
507 for chanNum
in chanList:
509 strout =
"cool channel=%4i" % chanNum
510 self.log().
debug(
"Registering %s %s", (strout, data))
511 channelId = cool.ChannelId(chanNum)
512 self.
__folder.storeObject(sinceCool, untilCool, data, channelId, folderTag, userTagOnly)
517 Returns a CaloCondBlob object of given system Id.
521 chanNum = cool.ChannelId(systemId)
526 spec = self.
__folder.payloadSpecification()
527 data = cool.Record( spec )
531 flt = g.CaloCondBlobFlt.getInstance(blob)
562 Resets blob size to zero
565 chanNum = cool.ChannelId(systemId)
568 spec = self.
__folder.payloadSpecification()
569 data = cool.Record( spec )
571 blob = data[
'CaloCondBlob16M']
573 except Exception
as e:
574 self.log().critical( e )