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 UNIX time stamp given an input time string
191 return int(time.mktime(time.strptime(timeString,
"%Y-%m-%d %H:%M:%S")))
197 The interpretation of pointInTime depends on their type:
198 - tuple(int,int) : run and lbk number
199 - integer : Values are interpreted as unix time stamps
200 - string : time stamp of format 'yyyy-mm-dd hh:mm:ss'
206 if isinstance(pointInTime, str):
210 if isinstance(pointInTime, int):
212 validityKey = pointInTime * UNIX2COOL
215 validityKey =
int(time.time()) * UNIX2COOL
217 validityKey = cool.ValidityKeyMax
219 elif isinstance(pointInTime, tuple):
223 raise Exception(
"Unrecognized pointInTime type=%s" %
type(pointInTime))
224 return cool.ValidityKey(validityKey)
230 Returns cell subHash given partition,module,sample, and tower (TILE only)
233 raise Exception(
'getCellHash only available for TileCells.')
236 if part == 1
or part == 2:
238 elif part == 3
or part == 4:
239 if sample == 3
or (sample==1
and tower==9)
or (sample==2
and tower==8):
247 if section==0
or side==0
or module>63
or sample>3
or tower>15:
248 raise Exception(
'Non-physical cell specification')
251 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]
255 modOffset = [22,23,12,12,6,6]
261 return hash[sideOffset*16*4+tower*4+sample]+modOffset[sideOffset+2*(section-1)]*module
273 CaloBlobReader is a helper class, managing the details of COOL interactions
280 - db : db should be an open database connection
281 - folder: full folder path
282 - tag : The folder tag, e.g. \"000-00\"
285 CaloCondLogger.__init__(self,
"CaloBlobReader")
291 except Exception
as e:
292 self.log().critical( e )
296 validFolderTypes = (
"run-lumi",
"time")
300 raise Exception(
"Invalid folder type found: \'%s\'" % self.
__folderType)
312 Returns a CaloCondBlob object for the given system.
316 self.log().
debug(
"Validity key is %s", validityKey)
319 key = (systemId,validityKey)
323 channelId = cool.ChannelId(systemId)
324 obj = self.
__folder.findObject(validityKey, channelId, self.
__tag)
325 self.log().
debug(
"Fetching from DB: %s", obj)
326 blob = obj.payload()[0]
327 self.log().
debug(
"blob size: %d", blob.size())
331 blob = obj.payload()[0]
332 self.log().
debug(
"blob size: %d", blob.size())
335 flt = g.CaloCondBlobFlt.getInstance(blob)
337 except Exception
as e:
338 self.log().
error(
"Fetching of systemId=%i failed with exception %s",systemId,e)
345 Returns true if MultiVersion folder is connected
347 if self.
__folder.versioningMode()==cool.FolderVersioning.MULTI_VERSION:
363 Helper class that enables writing to Calo DB
367 def __init__(self, db, folderPath, caloBlobType=None,
368 isMultiVersionFolder=True, isRunLumiTimeStamp=True):
371 - db : db should be an open database connection
372 - folderPath: full folder path to create or update
376 CaloCondLogger.__init__(self,
"CaloBlobWriter")
382 folderMode = cool.FolderVersioning.MULTI_VERSION
383 if not isMultiVersionFolder:
384 folderMode = cool.FolderVersioning.SINGLE_VERSION
392 if self.
__db.existsFolder(folderPath):
395 modeInCool = self.
__folder.versioningMode()
396 if modeInCool!=folderMode:
397 str =
"Incompatible folder mode detected, COOL folder has type "
398 if modeInCool==cool.FolderVersioning.MULTI_VERSION:
405 payloadSpec = cool.RecordSpecification()
406 payloadSpec.extend(
'CaloCondBlob16M', cool.StorageType.Blob16M )
407 folderSpec = cool.FolderSpecification(folderMode, payloadSpec)
408 self.
__folder = db.createFolder(folderPath, folderSpec, folderDescr,
True)
409 except Exception
as e:
410 self.log().critical( e )
418 def register(self, since=(MINRUN,MINLBK), until=(MAXRUN,MAXLBK), tag=
""):
420 Registers the folder in the database.
421 - since: lower limit of IOV
422 - until: upper limit of IOV
423 - tag : The cool folder tag to write to
425 The interpretation of the 'since' and 'until' inputs depends on their type:
426 - tuple(int,int) : run and lbk number
427 - integer : Values are interpreted as unix time stamps
428 If since<0, current time is assumed
429 If until<0, infinity is assumed
430 - string : time stamp of format 'yyyy-mm-dd hh:mm:ss'
435 raise Exception(
"Inconsistent types: since=%s, until=%s" % (
type(since),
type(until)))
439 if self.
__folder.versioningMode()==cool.FolderVersioning.SINGLE_VERSION:
443 self.log().warning(
"Trying to store with tag \"%s\" to SINGLE_VERSION folder", tag )
444 self.log().warning(
"... resetting tag to \"\"!" )
450 if untilCool <= sinceCool:
451 raise Exception(
"Until(%i) <= Since(%i)" % (untilCool,sinceCool))
455 if isinstance(since, tuple):
456 iovString =
"[%i,%i] - [%i,%i]" % (since[0],since[1],until[0],until[1])
458 sinceInfo = time.localtime( sinceCool//UNIX2COOL )
459 untilInfo = time.localtime(
min(UNIXTMAX, (untilCool//UNIX2COOL)))
460 untilStr =
"<infinity>"
461 if untilCool<cool.ValidityKeyMax:
462 untilStr = time.asctime(untilInfo)
463 if (untilCool//UNIX2COOL)>UNIXTMAX:
464 untilStr =
" > "+untilStr
465 iovString =
"[%s] - [%s]" % (time.asctime(sinceInfo), untilStr)
472 self.log().
info(
"... with IOV : %s", iovString )
477 for chanNum
in chanList:
479 strout =
"cool channel=%4i" % chanNum
480 self.log().
debug(
"Registering %s %s", (strout, data))
481 channelId = cool.ChannelId(chanNum)
482 self.
__folder.storeObject(sinceCool, untilCool, data, channelId, folderTag, userTagOnly)
487 Returns a CaloCondBlob object of given system Id.
491 chanNum = cool.ChannelId(systemId)
496 spec = self.
__folder.payloadSpecification()
497 data = cool.Record( spec )
501 flt = g.CaloCondBlobFlt.getInstance(blob)
532 Resets blob size to zero
535 chanNum = cool.ChannelId(systemId)
538 spec = self.
__folder.payloadSpecification()
539 data = cool.Record( spec )
541 blob = data[
'CaloCondBlob16M']
543 except Exception
as e:
544 self.log().critical( e )