12 Python helper module for managing COOL DB connections and TileCalibBlobs.
16 from PyCool
import cool
17 import datetime, time, re, os
20 from urllib.request
import urlopen
23 from urllib2
import urlopen
26 from TileCalibBlobObjs.Classes
import TileCalibUtils, TileCalibDrawerCmt, \
27 TileCalibDrawerInt, TileCalibDrawerOfc, TileCalibDrawerBch, \
28 TileCalibDrawerFlt, TileCalibType
31 from TileCalibBlobPython.TileCalibLogger
import TileCalibLogger, getLogger
46 MAXRUN = cool.Int32Max
47 MAXLBK = cool.UInt32Max
48 UNIX2COOL = 1000000000
49 UNIXTMAX = cool.Int32Max
57 Return the run number of next run to be taken in the pit
60 urls = [
"http://atlas-service-db-runlist.web.cern.ch/atlas-service-db-runlist/cgi-bin/latestRun.py",
61 "http://pcata007.cern.ch/cgi-bin/getLastRunNumber.py",
62 "http://pcata007.cern.ch/latestRun"]
67 for line
in urlopen(url).readlines():
77 return max(run+1,222222)
83 Return the minimal run number of runs in prompt calibration loop
89 fin =
open(
"/afs/cern.ch/user/a/atlcond/scratch0/nemo/prod/web/calibruns.txt",
"r").
read().
split()
93 promptCalibRuns.append(
int(line) )
99 if len(promptCalibRuns)==0:
101 urls = [
"http://pcata007.cern.ch/cgi-bin/getBulkRunNumber.py",
102 "http://pcata007.cern.ch/latestRun"]
107 for line
in urlopen(url).readlines():
113 promptCalibRuns=[run]
118 if len(promptCalibRuns) >= 1:
119 promptCalibRuns.sort()
120 return promptCalibRuns[0]
128 Return name of top-level tag for 'Current' or 'CurrentES' or 'Next' or 'NextES' aliases
131 aliasfolder =
'/afs/cern.ch/atlas/conditions/poolcond/buffer/BestKnowledge'
133 falias =
open(
'%s/%s' % (aliasfolder, aliastype))
134 alias = falias.readline()
136 return alias.replace(
'\n',
'').
replace(
'*',
'')
139 aliasfolder = os.getcwd()+
'/BestKnowledge'
140 print(
"Looking for %s in %s" % (aliastype,aliasfolder))
142 falias =
open(
'%s/%s' % (aliasfolder, aliastype))
143 alias = falias.readline()
145 return alias.replace(
'\n',
'').
replace(
'*',
'')
147 return aliastype.upper()
153 Returns the common Tile prefix used for all COOL folders.
154 ofl = False ... single version folders
155 ofl = True ... multiversion folders
156 splitOnlInOflSchema = False ... offline only folders or
157 splitOnline folders in Online schema
158 splitOnlInOflSchema = True ... splitOnlineFolders in
162 if splitOnlInOflSchema:
163 return "/TILE/OFL02/"
165 return "/TILE/OFL01/"
167 return "/TILE/ONL01/"
173 Returns a list of all TILE folder prefixes
175 return [
"/TILE/ONL01/",
"/TILE/OFL01/",
"/TILE/OFL02/"]
181 Returns the run-lumi type folder description needed to read back the folder content
182 as a CondAttrListCollection in Athena.
184 desc =
'<timeStamp>'+type+
'</timeStamp>'
185 desc+=
'<addrHeader><address_header service_type="71" clid="1238547719" /></addrHeader>'
186 desc+=
'<typeName>CondAttrListCollection</typeName>'
192 type = re.compile(
".*<timeStamp>(.*)</timeStamp>.*").
search(folderDescr)
194 raise Exception(
"No folder type info found in \'%s\'" % folderDescr)
195 return type.groups()[0]
199 def openDb(db, instance, mode="READONLY", schema="COOLOFL_TILE", sqlfn="tileSqlite.db"):
201 Opens a COOL db connection.
202 - db: The DB type. The following names are recognized:
203 * SQLITE: Opens file mentioned in sqlfn parameter
204 * ORACLE or FRONTIER: Opens ORACLE DB, forces READONLY
205 - instance: One of valid instances - CONDBR2 OFLP200 COMP200 CMCP200
206 - mode: Can be READONLY (default), RECREATE or UPDATE
207 - schema: One of valid schemas - COOLONL_CALO COOLOFL_CALO COOLONL_LAR COOLOFL_LAR COOLONL_TILE COOLOFL_TILE
208 - sqlfn: Name of sqlite file if db is SQLITE
212 validDb = [
"SQLITE",
"ORACLE",
"FRONTIER"]
213 if db
not in validDb:
214 raise Exception(
"DB not valid: %s, valid DBs are: %s" % (db,validDb) )
215 elif db ==
"ORACLE" or db ==
"FRONTIER":
219 validInstance = [
"COMP200",
"CONDBR2",
"CMCP200",
"OFLP200"]
220 if instance
not in validInstance:
221 raise Exception(
"Instance not valid: %s, valid instance are: %s" % (instance,validInstance) )
224 validSchema = [
"COOLONL_TILE",
"COOLOFL_TILE"]
225 if schema
not in validSchema:
226 raise Exception(
"Schema not valid: %s, valid schemas are: %s" % (schema,validSchema) )
231 if mode==
"READONLY" and not os.path.exists(sqlfn):
232 raise Exception(
"Sqlite file %s does not exist" % (sqlfn) )
233 if (mode==
"RECREATE" or mode==
"UPDATE")
and not os.path.exists(os.path.dirname(sqlfn)):
234 dirn=os.path.dirname(sqlfn)
237 connStr=
"sqlite://X;schema=%s;dbname=%s" % (sqlfn,instance)
239 connStr=
'frontier://ATLF/()/;schema=ATLAS_%s;dbname=%s' % (schema,instance)
241 connStr=
'oracle://%s;schema=ATLAS_%s;dbname=%s' % (
'ATLAS_COOLPROD',schema,instance)
243 connStr=schema+
'/'+instance
251 Opens a COOL db connection.
252 - db: The DB type. The following names are recognized:
253 * ORACLE or FRONTIER: Opens ORACLE DB, forces READONLY
254 - schema: Full schema string for sqlite file, dbname will be extracted from this string
255 - folder: Fill folder path, schema string will be construced using folder name
259 if '/OFL' in folder.upper():
263 connStr += folder.strip(
'/').
split(
'/')[0].
upper()
264 dbn=schema.split(
'dbname=')
266 dbname=dbn[1].
split(
';')[0]
269 connStr +=
'/' + dbname
277 Opens a COOL db connection.
278 - connStr: The DB connection string
279 - mode: Can be READONLY (default), RECREATE or UPDATE
280 or ORACLE or FRONTIER if connStr is only short name of the database
284 splitname=connStr.split(
'/')
285 if (len(splitname)!=2):
289 instance=splitname[1]
291 connStr_new=
'oracle://%s;schema=ATLAS_%s;dbname=%s' % (
'ATLAS_COOLPROD',schema,instance)
293 connStr_new=
'frontier://ATLF/()/;schema=ATLAS_%s;dbname=%s' % (schema,instance)
296 dbSvc = cool.DatabaseSvcFactory.databaseService()
297 log.info(
"---------------------------------------------------------------------------------" )
298 log.info(
"-------------------------- TileCalibTools.openDbConn ----------------------------" )
299 log.info(
"- using COOL version %s", dbSvc.serviceVersion() )
300 log.info(
"- opening TileDb: %s",connStr_new )
301 log.info(
"- mode: %s", mode )
302 log.info(
"---------------------------------------------------------------------------------" )
305 if mode
in [
"READONLY",
"ORACLE",
"FRONTIER",
"",
None]:
308 db=dbSvc.openDatabase(connStr_new,
True)
309 except Exception
as e:
311 log.critical(
"Could not connect to %s" % connStr_new )
314 elif mode==
"RECREATE":
316 dbSvc.dropDatabase(connStr_new)
318 db = dbSvc.createDatabase(connStr_new)
319 except Exception
as e:
321 log.critical(
"Could not create database, giving up..." )
327 db=dbSvc.openDatabase(connStr_new,
False)
328 except Exception
as e:
330 log.warning(
"Could not connect to \'%s\', trying to create it....", connStr_new )
332 db=dbSvc.createDatabase(connStr_new)
333 except Exception
as e:
335 log.critical(
"Could not create database, giving up..." )
339 log.error(
"Mode \"%s\" not recognized", mode )
346 Returns COOL timeStamp build from run and lumi block numbers
348 return (
int(runNum)<<32) +
int(lbkNum)
354 Retruns UNIX time stamp given an input time string
356 return int(time.mktime(time.strptime(timeString,
"%Y-%m-%d %H:%M:%S")))
362 The interpretation of pointInTime depends on their type:
363 - tuple(int,int) : run and lbk number
364 - integer : Values are interpreted as unix time stamps
365 - string : time stamp of format 'yyyy-mm-dd hh:mm:ss'
371 if isinstance(pointInTime, str):
375 if isinstance(pointInTime, int):
377 validityKey = pointInTime * UNIX2COOL
380 validityKey =
int(time.time()) * UNIX2COOL
382 validityKey = cool.ValidityKeyMax
384 elif isinstance(pointInTime, tuple):
388 raise Exception(
"Unrecognized pointInTime type=%s" %
type(pointInTime))
389 return cool.ValidityKey(validityKey)
397 gTAG = globalTag.upper()
398 findTAG = (gTAG ==
"ANY" or gTAG ==
"FIRST" or gTAG ==
"LAST")
399 if globalTag.startswith(
"/")
or globalTag.startswith(
"TileO")
or globalTag.upper().startswith(
"CALO"):
401 log.warning(
"Using tag as-is for folder %s", folderPath)
402 elif '/TILE/ONL01' in folderPath:
403 log.info(
"Using empty tag for single-version folder %s", folderPath)
404 elif globalTag.startswith(
" "):
405 log.warning(
"Using empty tag for folder %s", folderPath)
408 log.warning(
"Using tag with empty suffix for folder %s", folderPath)
410 if folderPath.startswith(
'/CALO'):
411 dbname =
'COOLOFL_CALO' if folderPath.startswith(
'/CALO/Ofl')
else 'COOLONL_CALO'
413 dbname =
'COOLOFL_TILE'
414 schema=dbname+
'/CONDBR2'
415 if isinstance(db, str):
416 if 'OFLP200' in db
or 'MC' in db:
417 schema=dbname+
'/OFLP200'
418 if not globalTag.startswith(
"OFLCOND"):
419 if globalTag.startswith(
"RUN"):
420 globalTag=
'OFLCOND-'+globalTag
421 log.info(
"Using Simulation global tag \'%s\'", globalTag)
422 elif 'COMP200' in db
or 'RUN1' in db:
423 schema=dbname+
'/COMP200'
424 if globalTag!=
'UPD1' and globalTag!=
'UPD4' and (
'UPD1' in globalTag
or 'UPD4' in globalTag
or 'COND' not in globalTag):
426 log.info(
"Using suffix \'%s\' as it is", globalTag)
429 globalTag=
'COMCOND-BLKPA-RUN1-06'
430 log.info(
"Using RUN1 global tag \'%s\'", globalTag)
431 if schema == dbname+
'/CONDBR2':
432 if globalTag==
'CURRENT' or globalTag==
'UPD4' or globalTag==
'':
434 log.info(
"Resolved CURRENT globalTag to \'%s\'", globalTag)
435 elif globalTag==
'CURRENTES' or globalTag==
'UPD1':
437 log.info(
"Resolved CURRENT ES globalTag to \'%s\'", globalTag)
438 elif globalTag==
'NEXT':
440 log.info(
"Resolved NEXT globalTag to \'%s\'", globalTag)
441 elif globalTag==
'NEXTES':
443 log.info(
"Resolved NEXT ES globalTag to \'%s\'", globalTag)
444 globalTag=globalTag.replace(
'*',
'')
445 if not findTAG
and (
'UPD1' in globalTag
or 'UPD4' in globalTag
or 'COND' not in globalTag):
447 if tag.startswith(
'Calo')
and 'NoiseCell' not in tag:
449 log.info(
"Resolved localTag \'%s\' to folderTag \'%s\'", globalTag,tag)
451 if not isinstance(db, str):
453 folder = db.getFolder(folderPath)
457 tag = folder.resolveTag(globalTag)
458 log.info(
"Resolved globalTag \'%s\' to folderTag \'%s\'", globalTag,tag)
460 except Exception
as e:
462 log.warning(
"Using %s to resolve globalTag",schema)
465 folder = dbr.getFolder(folderPath)
469 tag = folder.resolveTag(globalTag)
471 log.info(
"Resolved globalTag \'%s\' to folderTag \'%s\'", globalTag,tag)
478 taglist=folder.listTags()
485 return 'tag-not-found'
490 return (
int(iov >> 32),
int(iov & 0xFFFFFFFF))
494 def copyFolder(dbr, dbw, folder, tagr, tagw, chanNum, pointInTime1, pointInTime2):
496 log.info(
"Copy channel %i", chanNum)
498 folderR = dbr.getFolder(folder)
499 folderW = dbw.getFolder(folder)
501 chansel = cool.ChannelSelection(chanNum)
508 objs = folderR.browseObjects(iov1,iov2,chansel)
511 objs = folderR.browseObjects(iov1,iov2,chansel,tagr)
512 while objs.goToNext():
513 obj=objs.currentRef()
514 sinceCool=obj.since()
517 untilCool=obj.until()
521 log.debug(
"Copy entry: [%i,%i] - [%i,%i]: %s", sinceTup[0],sinceTup[1],untilTup[0],untilTup[1], data)
522 folderW.storeObject(sinceCool, untilCool, data, chanNum, tagw, multiVersion)
536 TileCalibBlobWriterBase is a helper class, managing the details of
537 COOL interactions for the user of TileCalibBlobs.
541 def __init__(self, db, folderPath, calibDrawerType,
542 isMultiVersionFolder=True, isRunLumiTimeStamp=True):
545 - db : db should be an open database connection
546 - folderPath: full folder path to create or update
550 TileCalibLogger.__init__(self,
"TileBlobWriter")
556 folderMode = cool.FolderVersioning.MULTI_VERSION
557 if not isMultiVersionFolder:
558 folderMode = cool.FolderVersioning.SINGLE_VERSION
562 if not isRunLumiTimeStamp:
568 if self.
__db.existsFolder(folderPath):
571 modeInCool = self.
__folder.versioningMode()
572 if modeInCool!=folderMode:
573 str =
"Incompatible folder mode detected, COOL folder has type "
574 if modeInCool==cool.FolderVersioning.MULTI_VERSION:
581 payloadSpec = cool.RecordSpecification()
582 payloadSpec.extend(
'TileCalibBlob', cool.StorageType.Blob64k )
583 folderSpec = cool.FolderSpecification(folderMode, payloadSpec)
584 self.
__folder = db.createFolder(folderPath, folderSpec, folderDescr,
True)
585 except Exception
as e:
586 self.log().critical( e )
595 if calibDrawerType==
'Flt':
596 self.
__defVec = cppyy.gbl.std.vector(
'std::vector<float>')()
597 elif calibDrawerType==
'Bch' or calibDrawerType==
'Int':
598 self.
__defVec = cppyy.gbl.std.vector(
'std::vector<unsigned int>')()
600 raise Exception(
"Unknown calibDrawerType: %s" % calibDrawerType)
604 def register(self, since=(MINRUN,MINLBK), until=(MAXRUN,MAXLBK), tag=
"", option=0):
606 Registers the folder in the database.
607 - since: lower limit of IOV
608 - until: upper limit of IOV
609 - tag : The cool folder tag to write to
611 The interpretation of the 'since' and 'until' inputs depends on their type:
612 - tuple(int,int) : run and lbk number
613 - integer : Values are interpreted as unix time stamps
614 If since<0, current time is assumed
615 If until<0, infinity is assumed
616 - string : time stamp of format 'yyyy-mm-dd hh:mm:ss'
621 raise Exception(
"Inconsistent types: since=%s, until=%s" % (
type(since),
type(until)))
625 if self.
__folder.versioningMode()==cool.FolderVersioning.SINGLE_VERSION:
629 self.log().warning(
"Trying to store with tag \"%s\" to SINGLE_VERSION folder", tag )
630 self.log().warning(
"... resetting tag to \"\"!" )
636 if untilCool <= sinceCool:
637 raise Exception(
"Until(%i) <= Since(%i)" % (untilCool,sinceCool))
641 if isinstance(since, tuple):
642 iovString =
"[%i,%i] - [%i,%i]" % (since[0],since[1],until[0],until[1])
644 sinceInfo = time.localtime( sinceCool//UNIX2COOL )
645 untilInfo = time.localtime(
min(UNIXTMAX, (untilCool//UNIX2COOL)))
646 untilStr =
"<infinity>"
647 if untilCool<cool.ValidityKeyMax:
648 untilStr = time.asctime(untilInfo)
649 if (untilCool//UNIX2COOL)>UNIXTMAX:
650 untilStr =
" > "+untilStr
651 iovString =
"[%s] - [%s]" % (time.asctime(sinceInfo), untilStr)
658 onlyComment = (option<0)
659 noComment = (comment
is None)
or (comment ==
"None")
or (comment.startswith(
"None")
and comment.endswith(
"None"))
or (option>0)
661 self.log().
info(
"... with IOV : %s" , iovString )
664 self.log().
info(
"... WITHOUT comment field" )
666 self.log().
info(
"... with comment field: \"%s\"", self.
getComment() )
674 for chanNum
in chanList:
675 if chanNum==1000
and noComment:
678 strout =
"cool channel=%4i" % chanNum
679 self.log().
debug(
"Registering %s %s", strout, data)
680 channelId = cool.ChannelId(chanNum)
681 self.
__folder.storeObject(sinceCool, untilCool, data, channelId, folderTag, userTagOnly)
684 self.log().
info(
"... %d cool channels have been written in total", cnt )
686 self.log().
info(
"... 1 cool channel with comment field has been written" )
688 self.log().
info(
"... %d cool channels have been written in total (including comment field)", cnt )
693 Sets a general comment in the comment channel.
699 spec = self.
__folder.payloadSpecification()
700 data = cool.Record( spec )
702 blob = data[
'TileCalibBlob']
703 if isinstance(author,tuple)
and len(author)==3:
704 tm=time.mktime(datetime.datetime.strptime(author[2],
"%a %b %d %H:%M:%S %Y").timetuple())
708 except Exception
as e:
709 self.log().critical( e )
714 Returns the general comment (default if none is set)
720 return "<No general comment!>"
721 blob = data[
'TileCalibBlob']
724 return (cmt.getAuthor(),cmt.getComment(),cmt.getDate())
726 return cmt.getFullComment()
727 except Exception
as e:
728 self.log().critical( e )
731 def getDrawer(self, ros, drawer, calibDrawerTemplate=None):
733 Returns a TileCalibDrawer object of requested type
734 for the given ROS and drawer.
746 spec = self.
__folder.payloadSpecification()
747 data = cool.Record( spec )
749 blob = data[
'TileCalibBlob']
759 raise Exception(
"Invalid blob type requested: %s" % type )
762 if calibDrawerTemplate:
763 calibDrawer.clone(calibDrawerTemplate)
769 except Exception
as e:
770 self.log().critical( e )
776 Resets blob size to zero
782 spec = self.
__folder.payloadSpecification()
783 data = cool.Record( spec )
785 blob = data[
'TileCalibBlob']
787 except Exception
as e:
788 self.log().critical( e )
803 TileCalibBlobReader is a helper class, managing the details of COOL interactions for
804 the user of TileCalibBlobs.
811 - db : db should be an open database connection
812 - folder: full folder path
813 - tag : The folder tag, e.g. \"000-00\"
816 TileCalibLogger.__init__(self,
"TileBlobReader")
822 except Exception
as e:
823 self.log().critical( e )
827 validFolderTypes = (
"run-lumi",
"time")
831 raise Exception(
"Invalid folder type found: \'%s\'" % self.
__folderType)
843 Returns the general comment (default if none is set)
848 obj = self.
__folder.findObject(validityKey, chanNum, self.
__tag)
849 self.log().
debug(
"getComment:Fetching from DB: %s", obj)
850 blob = obj.payload()[0]
853 return (cmt.getAuthor(),cmt.getComment(),cmt.getDate())
855 return cmt.getFullComment()
857 return "<no comment found>"
862 Returns a default drawer number (among first 20 COOL channels) for any drawer in any partition
865 if drawer<=4
or drawer==12
or drawer>=20:
871 elif ros==1
or ros==2:
874 OffsetEBA = [ 0, 0, 0, 0, 0, 0, 3, 2,
875 0, 0, 0, 0, 7, 6, 5, 7,
876 7, 6, 6, 7, 0, 0, 0, 2,
877 3, 0, 0, 0, 0, 0, 0, 0,
878 0, 0, 0, 0, 0, 0, 1, 1,
879 1, 1, 2, 3, 0, 0, 0, 0,
880 0, 0, 0, 0, 3, 2, 1, 1,
881 1, 1, 0, 0, 0, 0, 0, 0]
882 drawer1 = 12 + OffsetEBA[drawer]
884 OffsetEBC = [ 0, 0, 0, 0, 0, 0, 3, 2,
885 0, 0, 0, 0, 7, 6, 6, 7,
886 7, 5, 6, 7, 0, 0, 0, 2,
887 3, 0, 0, 3, 4, 0, 3, 4,
888 0, 4, 3, 0, 4, 3, 1, 1,
889 1, 1, 2, 3, 0, 0, 0, 0,
890 0, 0, 0, 0, 3, 2, 1, 1,
891 1, 1, 0, 0, 0, 0, 0, 0]
892 drawer1 = 12 + OffsetEBC[drawer]
899 def getDrawer(self, ros, drawer, pointInTime, printError=True, useDefault=True):
901 Returns a TileCalibDrawer object for the given ROS and drawer.
905 self.log().
debug(
"Validity key is %s", validityKey)
909 key = (ros,drawer,validityKey)
914 obj = self.
__folder.findObject(validityKey, chanNum, self.
__tag)
915 self.log().
debug(
"Fetching from DB: %s", obj)
916 blob = obj.payload()[0]
917 self.log().
debug(
"blob size: %d", blob.size())
919 if not useDefault
and blob.size()==0:
921 while blob.size()==0:
923 if ros==0
and drawer==0:
924 raise Exception(
'No default available')
928 obj = self.
__folder.findObject(validityKey, chanNum, self.
__tag)
929 blob = obj.payload()[0]
933 blob = obj.payload()[0]
934 self.log().
debug(
"blob size: %d", blob.size())
940 if typeName==
'TileCalibDrawerFlt':
942 self.log().
debug(
"typeName = Flt " )
943 elif typeName==
'TileCalibDrawerInt':
945 self.log().
debug(
"typeName = Int " )
946 elif typeName==
'TileCalibDrawerBch':
948 self.log().
debug(
"typeName = Bch " )
949 elif typeName==
'TileCalibDrawerOfc':
951 self.log().
debug(
"typeName = Ofc " )
953 raise Exception(
"Invalid blob type requested: %s" % typeName )
955 except Exception
as e:
957 self.log().
error(
"TileCalibTools.getDrawer(): Fetching of ros=%i, drawer=%i failed with exception %s", ros,drawer,e)
963 Returns a TileCalibDrawer object for the given ROS and drawer.
967 self.log().
debug(
"Validity key is %s", validityKey)
971 key = (ros,drawer,validityKey)
976 obj = self.
__folder.findObject(validityKey, chanNum, self.
__tag)
977 self.log().
debug(
"Fetching from DB: %s", obj)
978 blob = obj.payload()[0]
979 self.log().
debug(
"blob size: %d", blob.size())
981 while blob.size()==0:
983 if ros==0
and drawer==0:
984 raise Exception(
'No default available')
988 obj = self.
__folder.findObject(validityKey, chanNum, self.
__tag)
989 blob = obj.payload()[0]
993 blob = obj.payload()[0]
994 self.log().
debug(
"blob size: %d", blob.size())
1000 if typeName==
'TileCalibDrawerFlt':
1002 self.log().
debug(
"typeName = Flt " )
1003 elif typeName==
'TileCalibDrawerInt':
1005 self.log().
debug(
"typeName = Int " )
1006 elif typeName==
'TileCalibDrawerBch':
1008 self.log().
debug(
"typeName = Bch " )
1009 elif typeName==
'TileCalibDrawerOfc':
1011 self.log().
debug(
"typeName = Ofc " )
1013 raise Exception(
"Invalid blob type requested: %s" % typeName )
1015 except Exception
as e:
1017 self.log().
error(
"TileCalibTools.getDefaultDrawer(): Fetching of ros=%i, drawer=%i failed with exception %s", ros,drawer,e)
1021 def getDBobjsWithinRange(self, ros, drawer, point1inTime=(0,0), point2inTime=(2147483647,4294967295), printError=
True):
1023 Returns all DB objects for the given ROS and drawer, within given validity range -- default: [0-Infty)
1024 Check getBlobsWithinRange for an example on how to loop over objects and check validity ranges.
1031 self.log().
debug(
"Validity key range is %s - %s", validityKey1,validityKey2)
1036 dbChanSel = cool.ChannelSelection(dbChanNum)
1038 objs = self.
__folder.browseObjects(validityKey1,validityKey2,dbChanSel,self.
__tag)
1039 except Exception
as e:
1041 self.log().
error(
"TileCalibTools.getDBobjsWithinRange(): Fetching of ros=%i, drawer=%i failed with exception %s", ros,drawer,e)
1046 def getIOVsWithinRange(self, ros, drawer, point1inTime=(0,0), point2inTime=(2147483647,4294967295), printError=
True):
1048 Returns list of IOVS for the given ROS and drawer, within given validity range -- default: [0-Infty)
1052 if (dbobjs
is None):
1053 log.warning(
"Warning: can not read IOVs for ros %d drawer %d from input DB file", ros,drawer )
1055 while dbobjs.goToNext():
1056 obj = dbobjs.currentRef()
1057 objsince = obj.since()
1058 sinceRun = objsince >> 32
1059 sinceLum = objsince & 0xFFFFFFFF
1060 since = (sinceRun, sinceLum)
1067 Returns all blob objects for the given ROS and drawer, within given validity range -- default: [0-Infty)
1068 Note: the blobs don't contain validity range info. Check method getDBobjsWithinRange()
1074 print (
"Validity keys range is %s - %s" % (validityKey1, validityKey2))
1075 self.log().
debug(
"Validity key range is %s - %s", validityKey1,validityKey2)
1082 while objs.goToNext():
1083 obj=objs.currentRef()
1084 sinceCool=obj.since()
1085 if sinceCool < validityKey1:
1086 sinceCool = validityKey1
1087 untilCool=obj.until()
1088 blob = obj.payload()[0]
1089 print (
"[%d,%d)-[%d,%d) - %s" % ((sinceCool>>32),(sinceCool&0xFFFFFFFF),(untilCool>>32),(untilCool&0xFFFFFFFF),blob))
1090 self.log().
debug(
"blob size: %d", blob.size())
1093 while blob.size()==0:
1095 if ros==0
and drawer==0:
1096 raise Exception(
'No default available')
1100 obj = self.
__folder.findObject(sinceCool, chanNum, self.
__tag)
1101 blob = obj.payload()[0]
1102 self.log().
debug(
"blob size: 0 --> default: %d", blob.size())
1111 if typeName==
'TileCalibDrawerFlt':
1113 self.log().
debug(
"typeName = Flt " )
1114 elif typeName==
'TileCalibDrawerInt':
1116 self.log().
debug(
"typeName = Int " )
1117 elif typeName==
'TileCalibDrawerBch':
1119 self.log().
debug(
"typeName = Bch " )
1120 elif typeName==
'TileCalibDrawerOfc':
1122 self.log().
debug(
"typeName = Ofc " )
1124 raise Exception(
"Invalid blob type requested: %s" % typeName )
1126 blobs.append( calibDrawer )
1133 Returns true if MultiVersion folder is connected
1135 if self.
__folder.versioningMode()==cool.FolderVersioning.MULTI_VERSION:
1151 This is a class capable of parsing TileCal conditions data stored in
1152 ASCII files. Both the single and multi-line formats are supported.
1156 def __init__(self, fileName, calibId, isSingleLineFormat=True):
1159 - fileName : input file name
1160 - isSingleLineFormat: if False, multi line format is assumed
1163 TileCalibLogger.__init__(self,
"TileASCIIParser")
1166 lines =
open(fileName,
"r").readlines()
1167 except Exception
as e:
1168 self.log().
error(
"TileCalibASCIIParser::ERROR: Problem opening input file:" )
1169 self.log().
error( e )
1173 fields = line.strip().
split()
1175 if not len(fields) :
1177 if fields[0].startswith(
"#"):
1185 if not isSingleLineFormat:
1186 raise Exception(
"Multiline format not implemented yet")
1190 raise Exception(
"%s is not calibId=%s" % (type,calibId))
1193 if not (frag.startswith(
'0x')
or frag.startswith(
'-0x')
or frag.startswith(
'h_')):
1194 raise Exception(
"Misformated fragment %s" % frag)
1195 if frag.startswith(
'0x')
or frag.startswith(
'-0x'):
1203 elif frag.startswith(
'h_'):
1204 part_dict = {
'LBA':1,
'LBC':2,
'EBA':3,
'EBC':4}
1205 partname =
str(frag[2:5])
1206 ros=part_dict[partname]
1207 mod =
int(frag[5:])-1
1208 if (chan.startswith(
'ch')):
1215 dictKey = (ros,mod,chn)
1220 dictKey = (
int(ros),
int(drawer),
int(channel))
1231 "Reorder the PMTs (SV: how to get that from region.py???)"
1232 "This takes ros [1-4], drawer [0-63], pmt [1-48]"
1234 PMT2chan_Special={1:0,2:1,3:2,4:3,5:4,6:5,7:6,8:7,9:8,10:9,
1235 11:10,12:11,13:12,14:13,15:14,16:15,17:16,18:17, 19:18, 20:19,
1236 21:20,22:21,23:22,24:23,27:24,26:25,25:26,31:27,32:28,28:29,
1237 33:30,29:31,30:32,36:33,35:34,34:35,44:36,38:37,37:38,43:39,42:40,
1238 41:41,45:42,39:43,40:44,48:45,47:46,46:47}
1241 PMT2chan_LB={1:0,2:1,3:2,4:3,5:4,6:5,7:6,8:7,9:8,10:9,
1242 11:10,12:11,13:12,14:13,15:14,16:15,17:16,18:17,19:18,20:19,
1243 21:20,22:21,23:22,24:23,27:24,26:25,25:26,30:27,29:28,28:29,
1244 33:30,32:31,31:32,36:33,35:34,34:35,39:36,38:37,37:38,42:39,41:40,
1245 40:41,45:42,44:43,43:44,48:45,47:46,46:47}
1248 PMT2chan_EB={1:0,2:1,3:2,4:3,5:4,6:5,7:6,8:7,9:8,10:9,
1249 11:10,12:11,13:12,14:13,15:14,16:15,17:16,18:17,19:18,20:19,
1250 21:20,22:21,23:22,24:23,25:24,26:25,27:26,28:27,31:28,32:29,
1251 33:30,29:31,30:32,35:33,36:34,34:35,44:36,38:37,37:38,43:39,42:40,
1252 41:41,39:42,40:43,45:44,46:45,47:46,48:47}
1255 chan = PMT2chan_LB[pmt]
1256 elif (ros == 3
and drawer == 14)
or (ros == 4
and drawer == 17):
1257 chan = PMT2chan_Special[pmt]
1259 chan = PMT2chan_EB[pmt]
1273 This is a class capable of parsing TileCal conditions data stored in
1274 ASCII files. This version of parser can be used when mutiple IOVs are
1275 given in the file. First column is (run,lumi) pair in this case
1279 def __init__(self, fileName, calibId="", readGain=True):
1282 - fileName : input file name
1283 - calibId : like Ped, Las, ... or (r,l) or (run,lumi) but can be empty string as well
1284 - readGain : if False, no gain field in input file
1287 TileCalibLogger.__init__(self,
"TileASCIIParser2")
1295 lines =
open(fileName,
"r").readlines()
1296 except Exception
as e:
1297 self.log().
error(
"TileCalibASCIIParser2::ERROR: Problem opening input file:" )
1298 self.log().
error( e )
1301 self.log().
info(
"Parsing file %s",fileName)
1303 self.log().
info(
"Looking for prefix %s",calibId)
1306 fields = line.strip().
split()
1308 if not len(fields) :
1310 if fields[0].startswith(
"#"):
1318 if str(chan)[0:2].lower() ==
"pm":
1328 iov=tuple(
int(i)
for i
in pref[1:-1].
split(
","))
1329 if len(iov)!=2
or pref[0]!=
"(" or pref[-1]!=
")":
1330 raise Exception(
"%s is not %s IOV" % (pref,calibId))
1332 raise Exception(
"%s is not calibId=%s" % (pref,calibId))
1336 if str(chan)[0:2].lower() ==
"pm":
1345 if frag.startswith(
'0x')
or frag.startswith(
'-0x'):
1352 elif (frag.startswith(
"AUX")
or
1353 frag.startswith(
"LBA")
or
1354 frag.startswith(
"LBC")
or
1355 frag.startswith(
"EBA")
or
1356 frag.startswith(
"EBC")
or
1357 frag.startswith(
"ALL")
or
1358 frag.startswith(
"XXX") ):
1359 part_dict = {
'AUX':0,
'LBA':1,
'LBC':2,
'EBA':3,
'EBC':4,
'ALL':5,
'XXX':-1}
1360 partname =
str(frag[0:3])
1361 ros=part_dict[partname]
1362 mod =
int(frag[3:])-1
1364 raise Exception(
"Unknown fragment %s" % frag)
1380 if mod<0
or mod>=64:
1394 allchannels=(chn==-1)
1409 for ros
in range(rosmin,rosmax):
1410 for mod
in range(modmin,modmax):
1411 for chn
in range(chnmin,chnmax):
1412 if allchannels
or self.
channel2PMT(ros,mod,chn)>0:
1413 for adc
in range (adcmin,adcmax):
1414 dictKey = (ros,mod,chn,adc)
1424 def getData(self, ros, drawer, channel, adc, iov=(MAXRUN,MAXLBK)):
1425 dictKey = (
int(ros),
int(drawer),
int(channel),
int(adc))
1428 before= [i
for i
in sorted(data)
if i[0] <= iov ]
1430 data = before[-1][1]
1442 "Convert channel numbet to PMT number, negative for disconnected channels"
1443 "This takes ros [1-4], drawer [0-63], chan [0-47]"
1445 chan2PMT_LB=[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
1446 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1447 27, 26, 25, 30, 29, 28,-33,-32, 31, 36, 35, 34,
1448 39, 38, 37, 42, 41, 40, 45,-44, 43, 48, 47, 46 ]
1450 chan2PMT_EB=[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
1451 13, 14, 15, 16, 17, 18,-19,-20, 21, 22, 23, 24,
1452 -27,-26,-25,-31,-32,-28, 33, 29, 30,-36,-35, 34,
1453 44, 38, 37, 43, 42, 41,-45,-39,-40,-48,-47,-46 ]
1455 chan2PMT_Sp=[ -1, -2, -3, -4, 5, 6, 7, 8, 9, 10, 11, 12,
1456 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1457 -27,-26,-25,-31,-32,-28, 33, 29, 30,-36,-35, 34,
1458 44, 38, 37, 43, 42, 41,-45,-39,-40,-48,-47,-46 ]
1461 pmt = chan2PMT_LB[chan]
1462 elif (ros == 3
and drawer == 14)
or (ros == 4
and drawer == 17):
1463 pmt = chan2PMT_Sp[chan]
1465 pmt = chan2PMT_EB[chan]
1471 "Convert PMT number to channel numbet"
1472 "This takes partition (LBA,LBC,EBA,EBC) and pmt [1-48]"
1474 chan2PMT_LB=[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
1475 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1476 27, 26, 25, 30, 29, 28, 33, 32, 31, 36, 35, 34,
1477 39, 38, 37, 42, 41, 40, 45, 44, 43, 48, 47, 46 ]
1479 chan2PMT_EB=[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
1480 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1481 27, 26, 25, 31, 32, 28, 33, 29, 30, 36, 35, 34,
1482 44, 38, 37, 43, 42, 41, 45, 39, 40, 48, 47, 46 ]
1488 if str(partition)[0].
upper() ==
"E":
1489 chan = chan2PMT_EB.index(pm)
1491 chan = chan2PMT_LB.index(pm)
1504 This is a class capable of parsing TileCal conditions data stored in
1512 - fileName : input file name
1513 - calibId : like Trip, ...
1516 TileCalibLogger.__init__(self,
"TileASCIIParser3")
1519 lines =
open(fileName,
"r").readlines()
1520 except Exception
as e:
1521 self.log().
error(
"TileCalibASCIIParser3::ERROR: Problem opening input file:" )
1522 self.log().
error( e )
1526 fields = line.strip().
split()
1528 if not len(fields) :
1530 if fields[0].startswith(
"#"):
1540 raise Exception(
"%s is not calibId=%s" % (type, calibId))
1543 if not (frag.startswith(
'0x')
or frag.startswith(
'-0x')):
1544 raise Exception(
"Misformated fragment %s" % frag)
1554 dictKey = (ros, mod)
1559 dictKey = (
int(ros),
int(drawer))