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 - connStr: The DB connection string
253 - mode: Can be READONLY (default), RECREATE or UPDATE
254 or ORACLE or FRONTIER if connStr is only short name of the database
258 splitname=connStr.split(
'/')
259 if (len(splitname)!=2):
263 instance=splitname[1]
265 connStr_new=
'oracle://%s;schema=ATLAS_%s;dbname=%s' % (
'ATLAS_COOLPROD',schema,instance)
267 connStr_new=
'frontier://ATLF/()/;schema=ATLAS_%s;dbname=%s' % (schema,instance)
270 dbSvc = cool.DatabaseSvcFactory.databaseService()
271 log.info(
"---------------------------------------------------------------------------------" )
272 log.info(
"-------------------------- TileCalibTools.openDbConn ----------------------------" )
273 log.info(
"- using COOL version %s", dbSvc.serviceVersion() )
274 log.info(
"- opening TileDb: %s",connStr_new )
275 log.info(
"- mode: %s", mode )
276 log.info(
"---------------------------------------------------------------------------------" )
279 if mode
in [
"READONLY",
"ORACLE",
"FRONTIER",
"",
None]:
282 db=dbSvc.openDatabase(connStr_new,
True)
283 except Exception
as e:
285 log.critical(
"Could not connect to %s" % connStr_new )
288 elif mode==
"RECREATE":
290 dbSvc.dropDatabase(connStr_new)
292 db = dbSvc.createDatabase(connStr_new)
293 except Exception
as e:
295 log.critical(
"Could not create database, giving up..." )
301 db=dbSvc.openDatabase(connStr_new,
False)
302 except Exception
as e:
304 log.warning(
"Could not connect to \'%s\', trying to create it....", connStr_new )
306 db=dbSvc.createDatabase(connStr_new)
307 except Exception
as e:
309 log.critical(
"Could not create database, giving up..." )
313 log.error(
"Mode \"%s\" not recognized", mode )
320 Returns COOL timeStamp build from run and lumi block numbers
322 return (
int(runNum)<<32) +
int(lbkNum)
328 Retruns UNIX time stamp given an input time string
330 return int(time.mktime(time.strptime(timeString,
"%Y-%m-%d %H:%M:%S")))
336 The interpretation of pointInTime depends on their type:
337 - tuple(int,int) : run and lbk number
338 - integer : Values are interpreted as unix time stamps
339 - string : time stamp of format 'yyyy-mm-dd hh:mm:ss'
345 if isinstance(pointInTime, str):
349 if isinstance(pointInTime, int):
351 validityKey = pointInTime * UNIX2COOL
354 validityKey =
int(time.time()) * UNIX2COOL
356 validityKey = cool.ValidityKeyMax
358 elif isinstance(pointInTime, tuple):
362 raise Exception(
"Unrecognized pointInTime type=%s" %
type(pointInTime))
363 return cool.ValidityKey(validityKey)
371 if globalTag.startswith(
"/")
or globalTag.startswith(
"TileO")
or globalTag.startswith(
"CALO"):
373 log.warning(
"Using tag as-is for folder %s", folderPath)
374 elif '/TILE/ONL01' in folderPath:
375 log.info(
"Using empty tag for single-version folder %s", folderPath)
376 elif globalTag.startswith(
" "):
377 log.warning(
"Using empty tag for folder %s", folderPath)
380 log.warning(
"Using tag with empty suffix for folder %s", folderPath)
382 if folderPath.startswith(
'/CALO'):
383 dbname =
'COOLOFL_CALO' if folderPath.startswith(
'/CALO/Ofl')
else 'COOLONL_CALO'
385 dbname =
'COOLOFL_TILE'
386 schema=dbname+
'/CONDBR2'
387 if isinstance(db, str):
388 if 'OFLP200' in db
or 'MC' in db:
389 schema=dbname+
'/OFLP200'
390 if not globalTag.startswith(
"OFLCOND"):
391 if globalTag.startswith(
"RUN"):
392 globalTag=
'OFLCOND-'+globalTag
393 log.info(
"Using Simulation global tag \'%s\'", globalTag)
394 elif 'COMP200' in db
or 'RUN1' in db:
395 schema=dbname+
'/COMP200'
396 if globalTag!=
'UPD1' and globalTag!=
'UPD4' and (
'UPD1' in globalTag
or 'UPD4' in globalTag
or 'COND' not in globalTag):
397 log.info(
"Using suffix \'%s\' as it is", globalTag)
399 globalTag=
'COMCOND-BLKPA-RUN1-06'
400 log.info(
"Using RUN1 global tag \'%s\'", globalTag)
401 if schema == dbname+
'/CONDBR2':
402 if globalTag==
'CURRENT' or globalTag==
'UPD4' or globalTag==
'':
404 log.info(
"Resolved CURRENT globalTag to \'%s\'", globalTag)
405 elif globalTag==
'CURRENTES' or globalTag==
'UPD1':
407 log.info(
"Resolved CURRENT ES globalTag to \'%s\'", globalTag)
408 elif globalTag==
'NEXT':
410 log.info(
"Resolved NEXT globalTag to \'%s\'", globalTag)
411 elif globalTag==
'NEXTES':
413 log.info(
"Resolved NEXT ES globalTag to \'%s\'", globalTag)
414 globalTag=globalTag.replace(
'*',
'')
415 if 'UPD1' in globalTag
or 'UPD4' in globalTag
or 'COND' not in globalTag:
417 if tag.startswith(
'Calo'):
419 log.info(
"Resolved localTag \'%s\' to folderTag \'%s\'", globalTag,tag)
421 if not isinstance(db, str):
423 folder = db.getFolder(folderPath)
424 tag = folder.resolveTag(globalTag)
425 log.info(
"Resolved globalTag \'%s\' to folderTag \'%s\'", globalTag,tag)
427 except Exception
as e:
429 log.warning(
"Using %s to resolve globalTag",schema)
432 folder = dbr.getFolder(folderPath)
433 tag = folder.resolveTag(globalTag)
435 log.info(
"Resolved globalTag \'%s\' to folderTag \'%s\'", globalTag,tag)
442 return (
int(iov >> 32),
int(iov & 0xFFFFFFFF))
446 def copyFolder(dbr, dbw, folder, tagr, tagw, chanNum, pointInTime1, pointInTime2):
448 log.info(
"Copy channel %i", chanNum)
450 folderR = dbr.getFolder(folder)
451 folderW = dbw.getFolder(folder)
453 chansel = cool.ChannelSelection(chanNum)
460 objs = folderR.browseObjects(iov1,iov2,chansel)
463 objs = folderR.browseObjects(iov1,iov2,chansel,tagr)
464 while objs.goToNext():
465 obj=objs.currentRef()
466 sinceCool=obj.since()
469 untilCool=obj.until()
473 log.debug(
"Copy entry: [%i,%i] - [%i,%i]: %s", sinceTup[0],sinceTup[1],untilTup[0],untilTup[1], data)
474 folderW.storeObject(sinceCool, untilCool, data, chanNum, tagw, multiVersion)
488 TileCalibBlobWriterBase is a helper class, managing the details of
489 COOL interactions for the user of TileCalibBlobs.
493 def __init__(self, db, folderPath, calibDrawerType,
494 isMultiVersionFolder=True, isRunLumiTimeStamp=True):
497 - db : db should be an open database connection
498 - folderPath: full folder path to create or update
502 TileCalibLogger.__init__(self,
"TileBlobWriter")
508 folderMode = cool.FolderVersioning.MULTI_VERSION
509 if not isMultiVersionFolder:
510 folderMode = cool.FolderVersioning.SINGLE_VERSION
514 if not isRunLumiTimeStamp:
520 if self.
__db.existsFolder(folderPath):
523 modeInCool = self.
__folder.versioningMode()
524 if modeInCool!=folderMode:
525 str =
"Incompatible folder mode detected, COOL folder has type "
526 if modeInCool==cool.FolderVersioning.MULTI_VERSION:
533 payloadSpec = cool.RecordSpecification()
534 payloadSpec.extend(
'TileCalibBlob', cool.StorageType.Blob64k )
535 folderSpec = cool.FolderSpecification(folderMode, payloadSpec)
536 self.
__folder = db.createFolder(folderPath, folderSpec, folderDescr,
True)
537 except Exception
as e:
538 self.log().critical( e )
547 if calibDrawerType==
'Flt':
548 self.
__defVec = cppyy.gbl.std.vector(
'std::vector<float>')()
549 elif calibDrawerType==
'Bch' or calibDrawerType==
'Int':
550 self.
__defVec = cppyy.gbl.std.vector(
'std::vector<unsigned int>')()
552 raise Exception(
"Unknown calibDrawerType: %s" % calibDrawerType)
556 def register(self, since=(MINRUN,MINLBK), until=(MAXRUN,MAXLBK), tag=
"", option=0):
558 Registers the folder in the database.
559 - since: lower limit of IOV
560 - until: upper limit of IOV
561 - tag : The cool folder tag to write to
563 The interpretation of the 'since' and 'until' inputs depends on their type:
564 - tuple(int,int) : run and lbk number
565 - integer : Values are interpreted as unix time stamps
566 If since<0, current time is assumed
567 If until<0, infinity is assumed
568 - string : time stamp of format 'yyyy-mm-dd hh:mm:ss'
573 raise Exception(
"Inconsistent types: since=%s, until=%s" % (
type(since),
type(until)))
577 if self.
__folder.versioningMode()==cool.FolderVersioning.SINGLE_VERSION:
581 self.log().warning(
"Trying to store with tag \"%s\" to SINGLE_VERSION folder", tag )
582 self.log().warning(
"... resetting tag to \"\"!" )
588 if untilCool <= sinceCool:
589 raise Exception(
"Until(%i) <= Since(%i)" % (untilCool,sinceCool))
593 if isinstance(since, tuple):
594 iovString =
"[%i,%i] - [%i,%i]" % (since[0],since[1],until[0],until[1])
596 sinceInfo = time.localtime( sinceCool//UNIX2COOL )
597 untilInfo = time.localtime(
min(UNIXTMAX, (untilCool//UNIX2COOL)))
598 untilStr =
"<infinity>"
599 if untilCool<cool.ValidityKeyMax:
600 untilStr = time.asctime(untilInfo)
601 if (untilCool//UNIX2COOL)>UNIXTMAX:
602 untilStr =
" > "+untilStr
603 iovString =
"[%s] - [%s]" % (time.asctime(sinceInfo), untilStr)
610 onlyComment = (option<0)
611 noComment = (comment
is None)
or (comment ==
"None")
or (comment.startswith(
"None")
and comment.endswith(
"None"))
or (option>0)
613 self.log().
info(
"... with IOV : %s" , iovString )
616 self.log().
info(
"... WITHOUT comment field" )
618 self.log().
info(
"... with comment field: \"%s\"", self.
getComment() )
626 for chanNum
in chanList:
627 if chanNum==1000
and noComment:
630 strout =
"cool channel=%4i" % chanNum
631 self.log().
debug(
"Registering %s %s", strout, data)
632 channelId = cool.ChannelId(chanNum)
633 self.
__folder.storeObject(sinceCool, untilCool, data, channelId, folderTag, userTagOnly)
636 self.log().
info(
"... %d cool channels have been written in total", cnt )
638 self.log().
info(
"... 1 cool channel with comment field has been written" )
640 self.log().
info(
"... %d cool channels have been written in total (including comment field)", cnt )
645 Sets a general comment in the comment channel.
651 spec = self.
__folder.payloadSpecification()
652 data = cool.Record( spec )
654 blob = data[
'TileCalibBlob']
655 if isinstance(author,tuple)
and len(author)==3:
656 tm=time.mktime(datetime.datetime.strptime(author[2],
"%a %b %d %H:%M:%S %Y").timetuple())
660 except Exception
as e:
661 self.log().critical( e )
666 Returns the general comment (default if none is set)
672 return "<No general comment!>"
673 blob = data[
'TileCalibBlob']
676 return (cmt.getAuthor(),cmt.getComment(),cmt.getDate())
678 return cmt.getFullComment()
679 except Exception
as e:
680 self.log().critical( e )
683 def getDrawer(self, ros, drawer, calibDrawerTemplate=None):
685 Returns a TileCalibDrawer object of requested type
686 for the given ROS and drawer.
698 spec = self.
__folder.payloadSpecification()
699 data = cool.Record( spec )
701 blob = data[
'TileCalibBlob']
711 raise Exception(
"Invalid blob type requested: %s" % type )
714 if calibDrawerTemplate:
715 calibDrawer.clone(calibDrawerTemplate)
721 except Exception
as e:
722 self.log().critical( e )
728 Resets blob size to zero
734 spec = self.
__folder.payloadSpecification()
735 data = cool.Record( spec )
737 blob = data[
'TileCalibBlob']
739 except Exception
as e:
740 self.log().critical( e )
755 TileCalibBlobReader is a helper class, managing the details of COOL interactions for
756 the user of TileCalibBlobs.
763 - db : db should be an open database connection
764 - folder: full folder path
765 - tag : The folder tag, e.g. \"000-00\"
768 TileCalibLogger.__init__(self,
"TileBlobReader")
774 except Exception
as e:
775 self.log().critical( e )
779 validFolderTypes = (
"run-lumi",
"time")
783 raise Exception(
"Invalid folder type found: \'%s\'" % self.
__folderType)
795 Returns the general comment (default if none is set)
800 obj = self.
__folder.findObject(validityKey, chanNum, self.
__tag)
801 self.log().
debug(
"getComment:Fetching from DB: %s", obj)
802 blob = obj.payload()[0]
805 return (cmt.getAuthor(),cmt.getComment(),cmt.getDate())
807 return cmt.getFullComment()
809 return "<no comment found>"
814 Returns a default drawer number (among first 20 COOL channels) for any drawer in any partition
817 if drawer<=4
or drawer==12
or drawer>=20:
823 elif ros==1
or ros==2:
826 OffsetEBA = [ 0, 0, 0, 0, 0, 0, 3, 2,
827 0, 0, 0, 0, 7, 6, 5, 7,
828 7, 6, 6, 7, 0, 0, 0, 2,
829 3, 0, 0, 0, 0, 0, 0, 0,
830 0, 0, 0, 0, 0, 0, 1, 1,
831 1, 1, 2, 3, 0, 0, 0, 0,
832 0, 0, 0, 0, 3, 2, 1, 1,
833 1, 1, 0, 0, 0, 0, 0, 0]
834 drawer1 = 12 + OffsetEBA[drawer]
836 OffsetEBC = [ 0, 0, 0, 0, 0, 0, 3, 2,
837 0, 0, 0, 0, 7, 6, 6, 7,
838 7, 5, 6, 7, 0, 0, 0, 2,
839 3, 0, 0, 3, 4, 0, 3, 4,
840 0, 4, 3, 0, 4, 3, 1, 1,
841 1, 1, 2, 3, 0, 0, 0, 0,
842 0, 0, 0, 0, 3, 2, 1, 1,
843 1, 1, 0, 0, 0, 0, 0, 0]
844 drawer1 = 12 + OffsetEBC[drawer]
851 def getDrawer(self, ros, drawer, pointInTime, printError=True, useDefault=True):
853 Returns a TileCalibDrawer object for the given ROS and drawer.
857 self.log().
debug(
"Validity key is %s", validityKey)
861 key = (ros,drawer,validityKey)
866 obj = self.
__folder.findObject(validityKey, chanNum, self.
__tag)
867 self.log().
debug(
"Fetching from DB: %s", obj)
868 blob = obj.payload()[0]
869 self.log().
debug(
"blob size: %d", blob.size())
871 if not useDefault
and blob.size()==0:
873 while blob.size()==0:
875 if ros==0
and drawer==0:
876 raise Exception(
'No default available')
880 obj = self.
__folder.findObject(validityKey, chanNum, self.
__tag)
881 blob = obj.payload()[0]
885 blob = obj.payload()[0]
886 self.log().
debug(
"blob size: %d", blob.size())
892 if typeName==
'TileCalibDrawerFlt':
894 self.log().
debug(
"typeName = Flt " )
895 elif typeName==
'TileCalibDrawerInt':
897 self.log().
debug(
"typeName = Int " )
898 elif typeName==
'TileCalibDrawerBch':
900 self.log().
debug(
"typeName = Bch " )
901 elif typeName==
'TileCalibDrawerOfc':
903 self.log().
debug(
"typeName = Ofc " )
905 raise Exception(
"Invalid blob type requested: %s" % typeName )
907 except Exception
as e:
909 self.log().
error(
"TileCalibTools.getDrawer(): Fetching of ros=%i, drawer=%i failed with exception %s", ros,drawer,e)
915 Returns a TileCalibDrawer object for the given ROS and drawer.
919 self.log().
debug(
"Validity key is %s", validityKey)
923 key = (ros,drawer,validityKey)
928 obj = self.
__folder.findObject(validityKey, chanNum, self.
__tag)
929 self.log().
debug(
"Fetching from DB: %s", obj)
930 blob = obj.payload()[0]
931 self.log().
debug(
"blob size: %d", blob.size())
933 while blob.size()==0:
935 if ros==0
and drawer==0:
936 raise Exception(
'No default available')
940 obj = self.
__folder.findObject(validityKey, chanNum, self.
__tag)
941 blob = obj.payload()[0]
945 blob = obj.payload()[0]
946 self.log().
debug(
"blob size: %d", blob.size())
952 if typeName==
'TileCalibDrawerFlt':
954 self.log().
debug(
"typeName = Flt " )
955 elif typeName==
'TileCalibDrawerInt':
957 self.log().
debug(
"typeName = Int " )
958 elif typeName==
'TileCalibDrawerBch':
960 self.log().
debug(
"typeName = Bch " )
961 elif typeName==
'TileCalibDrawerOfc':
963 self.log().
debug(
"typeName = Ofc " )
965 raise Exception(
"Invalid blob type requested: %s" % typeName )
967 except Exception
as e:
969 self.log().
error(
"TileCalibTools.getDefaultDrawer(): Fetching of ros=%i, drawer=%i failed with exception %s", ros,drawer,e)
973 def getDBobjsWithinRange(self, ros, drawer, point1inTime=(0,0), point2inTime=(2147483647,4294967295), printError=
True):
975 Returns all DB objects for the given ROS and drawer, within given validity range -- default: [0-Infty)
976 Check getBlobsWithinRange for an example on how to loop over objects and check validity ranges.
983 self.log().
debug(
"Validity key range is %s - %s", validityKey1,validityKey2)
988 dbChanSel = cool.ChannelSelection(dbChanNum)
990 objs = self.
__folder.browseObjects(validityKey1,validityKey2,dbChanSel,self.
__tag)
991 except Exception
as e:
993 self.log().
error(
"TileCalibTools.getDBobjsWithinRange(): Fetching of ros=%i, drawer=%i failed with exception %s", ros,drawer,e)
998 def getIOVsWithinRange(self, ros, drawer, point1inTime=(0,0), point2inTime=(2147483647,4294967295), printError=
True):
1000 Returns list of IOVS for the given ROS and drawer, within given validity range -- default: [0-Infty)
1004 if (dbobjs
is None):
1005 log.warning(
"Warning: can not read IOVs for ros %d drawer %d from input DB file", ros,drawer )
1007 while dbobjs.goToNext():
1008 obj = dbobjs.currentRef()
1009 objsince = obj.since()
1010 sinceRun = objsince >> 32
1011 sinceLum = objsince & 0xFFFFFFFF
1012 since = (sinceRun, sinceLum)
1019 Returns all blob objects for the given ROS and drawer, within given validity range -- default: [0-Infty)
1020 Note: the blobs don't contain validity range info. Check method getDBobjsWithinRange()
1026 print (
"Validity keys range is %s - %s" % (validityKey1, validityKey2))
1027 self.log().
debug(
"Validity key range is %s - %s", validityKey1,validityKey2)
1034 while objs.goToNext():
1035 obj=objs.currentRef()
1036 sinceCool=obj.since()
1037 if sinceCool < validityKey1:
1038 sinceCool = validityKey1
1039 untilCool=obj.until()
1040 blob = obj.payload()[0]
1041 print (
"[%d,%d)-[%d,%d) - %s" % ((sinceCool>>32),(sinceCool&0xFFFFFFFF),(untilCool>>32),(untilCool&0xFFFFFFFF),blob))
1042 self.log().
debug(
"blob size: %d", blob.size())
1045 while blob.size()==0:
1047 if ros==0
and drawer==0:
1048 raise Exception(
'No default available')
1052 obj = self.
__folder.findObject(sinceCool, chanNum, self.
__tag)
1053 blob = obj.payload()[0]
1054 self.log().
debug(
"blob size: 0 --> default: %d", blob.size())
1063 if typeName==
'TileCalibDrawerFlt':
1065 self.log().
debug(
"typeName = Flt " )
1066 elif typeName==
'TileCalibDrawerInt':
1068 self.log().
debug(
"typeName = Int " )
1069 elif typeName==
'TileCalibDrawerBch':
1071 self.log().
debug(
"typeName = Bch " )
1072 elif typeName==
'TileCalibDrawerOfc':
1074 self.log().
debug(
"typeName = Ofc " )
1076 raise Exception(
"Invalid blob type requested: %s" % typeName )
1078 blobs.append( calibDrawer )
1085 Returns true if MultiVersion folder is connected
1087 if self.
__folder.versioningMode()==cool.FolderVersioning.MULTI_VERSION:
1103 This is a class capable of parsing TileCal conditions data stored in
1104 ASCII files. Both the single and multi-line formats are supported.
1108 def __init__(self, fileName, calibId, isSingleLineFormat=True):
1111 - fileName : input file name
1112 - isSingleLineFormat: if False, multi line format is assumed
1115 TileCalibLogger.__init__(self,
"TileASCIIParser")
1118 lines =
open(fileName,
"r").readlines()
1119 except Exception
as e:
1120 self.log().
error(
"TileCalibASCIIParser::ERROR: Problem opening input file:" )
1121 self.log().
error( e )
1125 fields = line.strip().
split()
1127 if not len(fields) :
1129 if fields[0].startswith(
"#"):
1137 if not isSingleLineFormat:
1138 raise Exception(
"Multiline format not implemented yet")
1142 raise Exception(
"%s is not calibId=%s" % (type,calibId))
1145 if not (frag.startswith(
'0x')
or frag.startswith(
'-0x')
or frag.startswith(
'h_')):
1146 raise Exception(
"Misformated fragment %s" % frag)
1147 if frag.startswith(
'0x')
or frag.startswith(
'-0x'):
1155 elif frag.startswith(
'h_'):
1156 part_dict = {
'LBA':1,
'LBC':2,
'EBA':3,
'EBC':4}
1157 partname =
str(frag[2:5])
1158 ros=part_dict[partname]
1159 mod =
int(frag[5:])-1
1160 if (chan.startswith(
'ch')):
1167 dictKey = (ros,mod,chn)
1172 dictKey = (
int(ros),
int(drawer),
int(channel))
1183 "Reorder the PMTs (SV: how to get that from region.py???)"
1184 "This takes ros [1-4], drawer [0-63], pmt [1-48]"
1186 PMT2chan_Special={1:0,2:1,3:2,4:3,5:4,6:5,7:6,8:7,9:8,10:9,
1187 11:10,12:11,13:12,14:13,15:14,16:15,17:16,18:17, 19:18, 20:19,
1188 21:20,22:21,23:22,24:23,27:24,26:25,25:26,31:27,32:28,28:29,
1189 33:30,29:31,30:32,36:33,35:34,34:35,44:36,38:37,37:38,43:39,42:40,
1190 41:41,45:42,39:43,40:44,48:45,47:46,46:47}
1193 PMT2chan_LB={1:0,2:1,3:2,4:3,5:4,6:5,7:6,8:7,9:8,10:9,
1194 11:10,12:11,13:12,14:13,15:14,16:15,17:16,18:17,19:18,20:19,
1195 21:20,22:21,23:22,24:23,27:24,26:25,25:26,30:27,29:28,28:29,
1196 33:30,32:31,31:32,36:33,35:34,34:35,39:36,38:37,37:38,42:39,41:40,
1197 40:41,45:42,44:43,43:44,48:45,47:46,46:47}
1200 PMT2chan_EB={1:0,2:1,3:2,4:3,5:4,6:5,7:6,8:7,9:8,10:9,
1201 11:10,12:11,13:12,14:13,15:14,16:15,17:16,18:17,19:18,20:19,
1202 21:20,22:21,23:22,24:23,25:24,26:25,27:26,28:27,31:28,32:29,
1203 33:30,29:31,30:32,35:33,36:34,34:35,44:36,38:37,37:38,43:39,42:40,
1204 41:41,39:42,40:43,45:44,46:45,47:46,48:47}
1207 chan = PMT2chan_LB[pmt]
1208 elif (ros == 3
and drawer == 14)
or (ros == 4
and drawer == 17):
1209 chan = PMT2chan_Special[pmt]
1211 chan = PMT2chan_EB[pmt]
1225 This is a class capable of parsing TileCal conditions data stored in
1226 ASCII files. This version of parser can be used when mutiple IOVs are
1227 given in the file. First column is (run,lumi) pair in this case
1231 def __init__(self, fileName, calibId="", readGain=True):
1234 - fileName : input file name
1235 - calibId : like Ped, Las, ... or (r,l) or (run,lumi) but can be empty string as well
1236 - readGain : if False, no gain field in input file
1239 TileCalibLogger.__init__(self,
"TileASCIIParser2")
1247 lines =
open(fileName,
"r").readlines()
1248 except Exception
as e:
1249 self.log().
error(
"TileCalibASCIIParser2::ERROR: Problem opening input file:" )
1250 self.log().
error( e )
1253 self.log().
info(
"Parsing file %s",fileName)
1255 self.log().
info(
"Looking for prefix %s",calibId)
1258 fields = line.strip().
split()
1260 if not len(fields) :
1262 if fields[0].startswith(
"#"):
1270 if str(chan)[0:2].lower() ==
"pm":
1280 iov=tuple(
int(i)
for i
in pref[1:-1].
split(
","))
1281 if len(iov)!=2
or pref[0]!=
"(" or pref[-1]!=
")":
1282 raise Exception(
"%s is not %s IOV" % (pref,calibId))
1284 raise Exception(
"%s is not calibId=%s" % (pref,calibId))
1288 if str(chan)[0:2].lower() ==
"pm":
1297 if frag.startswith(
'0x')
or frag.startswith(
'-0x'):
1304 elif (frag.startswith(
"AUX")
or
1305 frag.startswith(
"LBA")
or
1306 frag.startswith(
"LBC")
or
1307 frag.startswith(
"EBA")
or
1308 frag.startswith(
"EBC")
or
1309 frag.startswith(
"ALL")
or
1310 frag.startswith(
"XXX") ):
1311 part_dict = {
'AUX':0,
'LBA':1,
'LBC':2,
'EBA':3,
'EBC':4,
'ALL':5,
'XXX':-1}
1312 partname =
str(frag[0:3])
1313 ros=part_dict[partname]
1314 mod =
int(frag[3:])-1
1316 raise Exception(
"Unknown fragment %s" % frag)
1332 if mod<0
or mod>=64:
1346 allchannels=(chn==-1)
1361 for ros
in range(rosmin,rosmax):
1362 for mod
in range(modmin,modmax):
1363 for chn
in range(chnmin,chnmax):
1364 if allchannels
or self.
channel2PMT(ros,mod,chn)>0:
1365 for adc
in range (adcmin,adcmax):
1366 dictKey = (ros,mod,chn,adc)
1376 def getData(self, ros, drawer, channel, adc, iov=(MAXRUN,MAXLBK)):
1377 dictKey = (
int(ros),
int(drawer),
int(channel),
int(adc))
1380 before= [i
for i
in sorted(data)
if i[0] <= iov ]
1382 data = before[-1][1]
1394 "Convert channel numbet to PMT number, negative for disconnected channels"
1395 "This takes ros [1-4], drawer [0-63], chan [0-47]"
1397 chan2PMT_LB=[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
1398 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1399 27, 26, 25, 30, 29, 28,-33,-32, 31, 36, 35, 34,
1400 39, 38, 37, 42, 41, 40, 45,-44, 43, 48, 47, 46 ]
1402 chan2PMT_EB=[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
1403 13, 14, 15, 16, 17, 18,-19,-20, 21, 22, 23, 24,
1404 -27,-26,-25,-31,-32,-28, 33, 29, 30,-36,-35, 34,
1405 44, 38, 37, 43, 42, 41,-45,-39,-40,-48,-47,-46 ]
1407 chan2PMT_Sp=[ -1, -2, -3, -4, 5, 6, 7, 8, 9, 10, 11, 12,
1408 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1409 -27,-26,-25,-31,-32,-28, 33, 29, 30,-36,-35, 34,
1410 44, 38, 37, 43, 42, 41,-45,-39,-40,-48,-47,-46 ]
1413 pmt = chan2PMT_LB[chan]
1414 elif (ros == 3
and drawer == 14)
or (ros == 4
and drawer == 17):
1415 pmt = chan2PMT_Sp[chan]
1417 pmt = chan2PMT_EB[chan]
1423 "Convert PMT number to channel numbet"
1424 "This takes partition (LBA,LBC,EBA,EBC) and pmt [1-48]"
1426 chan2PMT_LB=[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
1427 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1428 27, 26, 25, 30, 29, 28, 33, 32, 31, 36, 35, 34,
1429 39, 38, 37, 42, 41, 40, 45, 44, 43, 48, 47, 46 ]
1431 chan2PMT_EB=[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
1432 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1433 27, 26, 25, 31, 32, 28, 33, 29, 30, 36, 35, 34,
1434 44, 38, 37, 43, 42, 41, 45, 39, 40, 48, 47, 46 ]
1440 if str(partition)[0].
upper() ==
"E":
1441 chan = chan2PMT_EB.index(pm)
1443 chan = chan2PMT_LB.index(pm)
1456 This is a class capable of parsing TileCal conditions data stored in
1464 - fileName : input file name
1465 - calibId : like Trip, ...
1468 TileCalibLogger.__init__(self,
"TileASCIIParser3")
1471 lines =
open(fileName,
"r").readlines()
1472 except Exception
as e:
1473 self.log().
error(
"TileCalibASCIIParser3::ERROR: Problem opening input file:" )
1474 self.log().
error( e )
1478 fields = line.strip().
split()
1480 if not len(fields) :
1482 if fields[0].startswith(
"#"):
1492 raise Exception(
"%s is not calibId=%s" % (type, calibId))
1495 if not (frag.startswith(
'0x')
or frag.startswith(
'-0x')):
1496 raise Exception(
"Misformated fragment %s" % frag)
1506 dictKey = (ros, mod)
1511 dictKey = (
int(ros),
int(drawer))