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
27 from TileCalibBlobObjs.Classes
import TileCalibUtils, TileCalibDrawerCmt, \
28 TileCalibDrawerInt, TileCalibDrawerOfc, TileCalibDrawerBch, \
29 TileCalibDrawerFlt, TileCalibType
32 from TileCalibBlobPython.TileCalibLogger
import TileCalibLogger, getLogger
47 MAXRUN = cool.Int32Max
48 MAXLBK = cool.UInt32Max
49 UNIX2COOL = 1000000000
50 UNIXTMAX = cool.Int32Max
58 Return the run number of next run to be taken in the pit
61 urls = [
"http://atlas-service-db-runlist.web.cern.ch/atlas-service-db-runlist/cgi-bin/latestRun.py",
62 "http://pcata007.cern.ch/cgi-bin/getLastRunNumber.py",
63 "http://pcata007.cern.ch/latestRun"]
68 for line
in urlopen(url).readlines():
78 return max(run+1,222222)
84 Return the minimal run number of runs in prompt calibration loop
90 fin =
open(
"/afs/cern.ch/user/a/atlcond/scratch0/nemo/prod/web/calibruns.txt",
"r").
read().
split()
94 promptCalibRuns.append(
int(line) )
100 if len(promptCalibRuns)==0:
102 urls = [
"http://pcata007.cern.ch/cgi-bin/getBulkRunNumber.py",
103 "http://pcata007.cern.ch/latestRun"]
108 for line
in urlopen(url).readlines():
114 promptCalibRuns=[run]
119 if len(promptCalibRuns) >= 1:
120 promptCalibRuns.sort()
121 return promptCalibRuns[0]
129 Return name of top-level tag for 'Current' or 'CurrentES' or 'Next' or 'NextES' aliases
132 aliasfolder =
'/afs/cern.ch/atlas/conditions/poolcond/buffer/BestKnowledge'
134 falias =
open(
'%s/%s' % (aliasfolder, aliastype))
135 alias = falias.readline()
137 return alias.replace(
'\n',
'').
replace(
'*',
'')
140 aliasfolder = os.getcwd()+
'/BestKnowledge'
141 print(
"Looking for %s in %s" % (aliastype,aliasfolder))
143 falias =
open(
'%s/%s' % (aliasfolder, aliastype))
144 alias = falias.readline()
146 return alias.replace(
'\n',
'').
replace(
'*',
'')
148 return aliastype.upper()
154 Returns the common Tile prefix used for all COOL folders.
155 ofl = False ... single version folders
156 ofl = True ... multiversion folders
157 splitOnlInOflSchema = False ... offline only folders or
158 splitOnline folders in Online schema
159 splitOnlInOflSchema = True ... splitOnlineFolders in
163 if splitOnlInOflSchema:
164 return "/TILE/OFL02/"
166 return "/TILE/OFL01/"
168 return "/TILE/ONL01/"
174 Returns a list of all TILE folder prefixes
176 return [
"/TILE/ONL01/",
"/TILE/OFL01/",
"/TILE/OFL02/"]
182 Returns the run-lumi type folder description needed to read back the folder content
183 as a CondAttrListCollection in Athena.
185 desc =
'<timeStamp>'+type+
'</timeStamp>'
186 desc+=
'<addrHeader><address_header service_type="71" clid="1238547719" /></addrHeader>'
187 desc+=
'<typeName>CondAttrListCollection</typeName>'
193 type = re.compile(
".*<timeStamp>(.*)</timeStamp>.*").
search(folderDescr)
195 raise Exception(
"No folder type info found in \'%s\'" % folderDescr)
196 return type.groups()[0]
200 def openDb(db, instance, mode="READONLY", schema="COOLOFL_TILE", sqlfn="tileSqlite.db"):
202 Opens a COOL db connection.
203 - db: The DB type. The following names are recognized:
204 * SQLITE: Opens file mentioned in sqlfn parameter
205 * ORACLE or FRONTIER: Opens ORACLE DB, forces READONLY
206 - instance: One of valid instances - CONDBR2 OFLP200 COMP200 CMCP200
207 - mode: Can be READONLY (default), RECREATE or UPDATE
208 - schema: One of valid schemas - COOLONL_CALO COOLOFL_CALO COOLONL_LAR COOLOFL_LAR COOLONL_TILE COOLOFL_TILE
209 - sqlfn: Name of sqlite file if db is SQLITE
213 validDb = [
"SQLITE",
"ORACLE",
"FRONTIER"]
214 if db
not in validDb:
215 raise Exception(
"DB not valid: %s, valid DBs are: %s" % (db,validDb) )
216 elif db ==
"ORACLE" or db ==
"FRONTIER":
220 validInstance = [
"COMP200",
"CONDBR2",
"CMCP200",
"OFLP200"]
221 if instance
not in validInstance:
222 raise Exception(
"Instance not valid: %s, valid instance are: %s" % (instance,validInstance) )
225 validSchema = [
"COOLONL_TILE",
"COOLOFL_TILE"]
226 if schema
not in validSchema:
227 raise Exception(
"Schema not valid: %s, valid schemas are: %s" % (schema,validSchema) )
232 if mode==
"READONLY" and not os.path.exists(sqlfn):
233 raise Exception(
"Sqlite file %s does not exist" % (sqlfn) )
234 if (mode==
"RECREATE" or mode==
"UPDATE")
and not os.path.exists(os.path.dirname(sqlfn)):
235 dirn=os.path.dirname(sqlfn)
238 connStr=
"sqlite://X;schema=%s;dbname=%s" % (sqlfn,instance)
240 connStr=
'frontier://ATLF/()/;schema=ATLAS_%s;dbname=%s' % (schema,instance)
242 connStr=
'oracle://%s;schema=ATLAS_%s;dbname=%s' % (
'ATLAS_COOLPROD',schema,instance)
244 connStr=schema+
'/'+instance
252 Opens a COOL db connection.
253 - connStr: The DB connection string
254 - mode: Can be READONLY (default), RECREATE or UPDATE
255 or ORACLE or FRONTIER if connStr is only short name of the database
259 splitname=connStr.split(
'/')
260 if (len(splitname)!=2):
264 instance=splitname[1]
266 connStr_new=
'oracle://%s;schema=ATLAS_%s;dbname=%s' % (
'ATLAS_COOLPROD',schema,instance)
268 connStr_new=
'frontier://ATLF/()/;schema=ATLAS_%s;dbname=%s' % (schema,instance)
271 dbSvc = cool.DatabaseSvcFactory.databaseService()
272 log.info(
"---------------------------------------------------------------------------------" )
273 log.info(
"-------------------------- TileCalibTools.openDbConn ----------------------------" )
274 log.info(
"- using COOL version %s", dbSvc.serviceVersion() )
275 log.info(
"- opening TileDb: %s",connStr_new )
276 log.info(
"- mode: %s", mode )
277 log.info(
"---------------------------------------------------------------------------------" )
280 if mode
in [
"READONLY",
"ORACLE",
"FRONTIER",
"",
None]:
283 db=dbSvc.openDatabase(connStr_new,
True)
284 except Exception
as e:
286 log.critical(
"Could not connect to %s" % connStr_new )
289 elif mode==
"RECREATE":
291 dbSvc.dropDatabase(connStr_new)
293 db = dbSvc.createDatabase(connStr_new)
294 except Exception
as e:
296 log.critical(
"Could not create database, giving up..." )
302 db=dbSvc.openDatabase(connStr_new,
False)
303 except Exception
as e:
305 log.warning(
"Could not connect to \'%s\', trying to create it....", connStr_new )
307 db=dbSvc.createDatabase(connStr_new)
308 except Exception
as e:
310 log.critical(
"Could not create database, giving up..." )
314 log.error(
"Mode \"%s\" not recognized", mode )
321 Returns COOL timeStamp build from run and lumi block numbers
323 return (
int(runNum)<<32) +
int(lbkNum)
329 Retruns UNIX time stamp given an input time string
331 return int(time.mktime(time.strptime(timeString,
"%Y-%m-%d %H:%M:%S")))
337 The interpretation of pointInTime depends on their type:
338 - tuple(int,int) : run and lbk number
339 - integer : Values are interpreted as unix time stamps
340 - string : time stamp of format 'yyyy-mm-dd hh:mm:ss'
346 if isinstance(pointInTime, str):
350 if isinstance(pointInTime, int):
352 validityKey = pointInTime * UNIX2COOL
355 validityKey =
int(time.time()) * UNIX2COOL
357 validityKey = cool.ValidityKeyMax
359 elif isinstance(pointInTime, tuple):
363 raise Exception(
"Unrecognized pointInTime type=%s" %
type(pointInTime))
364 return cool.ValidityKey(validityKey)
372 if globalTag.startswith(
"/")
or globalTag.startswith(
"TileO")
or globalTag.startswith(
"CALO"):
374 log.warning(
"Using tag as-is for folder %s", folderPath)
375 elif '/TILE/ONL01' in folderPath:
376 log.info(
"Using empty tag for single-version folder %s", folderPath)
377 elif globalTag.startswith(
" "):
378 log.warning(
"Using empty tag for folder %s", folderPath)
381 log.warning(
"Using tag with empty suffix for folder %s", folderPath)
383 if folderPath.startswith(
'/CALO'):
384 dbname =
'COOLOFL_CALO' if folderPath.startswith(
'/CALO/Ofl')
else 'COOLONL_CALO'
386 dbname =
'COOLOFL_TILE'
387 schema=dbname+
'/CONDBR2'
388 if isinstance(db, six.string_types):
389 if 'OFLP200' in db
or 'MC' in db:
390 schema=dbname+
'/OFLP200'
391 if not globalTag.startswith(
"OFLCOND"):
392 if globalTag.startswith(
"RUN"):
393 globalTag=
'OFLCOND-'+globalTag
394 log.info(
"Using Simulation global tag \'%s\'", globalTag)
395 elif 'COMP200' in db
or 'RUN1' in db:
396 schema=dbname+
'/COMP200'
397 if globalTag!=
'UPD1' and globalTag!=
'UPD4' and (
'UPD1' in globalTag
or 'UPD4' in globalTag
or 'COND' not in globalTag):
398 log.info(
"Using suffix \'%s\' as it is", globalTag)
400 globalTag=
'COMCOND-BLKPA-RUN1-06'
401 log.info(
"Using RUN1 global tag \'%s\'", globalTag)
402 if schema == dbname+
'/CONDBR2':
403 if globalTag==
'CURRENT' or globalTag==
'UPD4' or globalTag==
'':
405 log.info(
"Resolved CURRENT globalTag to \'%s\'", globalTag)
406 elif globalTag==
'CURRENTES' or globalTag==
'UPD1':
408 log.info(
"Resolved CURRENT ES globalTag to \'%s\'", globalTag)
409 elif globalTag==
'NEXT':
411 log.info(
"Resolved NEXT globalTag to \'%s\'", globalTag)
412 elif globalTag==
'NEXTES':
414 log.info(
"Resolved NEXT ES globalTag to \'%s\'", globalTag)
415 globalTag=globalTag.replace(
'*',
'')
416 if 'UPD1' in globalTag
or 'UPD4' in globalTag
or 'COND' not in globalTag:
418 if tag.startswith(
'Calo'):
420 log.info(
"Resolved localTag \'%s\' to folderTag \'%s\'", globalTag,tag)
422 if not isinstance(db, six.string_types):
424 folder = db.getFolder(folderPath)
425 tag = folder.resolveTag(globalTag)
426 log.info(
"Resolved globalTag \'%s\' to folderTag \'%s\'", globalTag,tag)
428 except Exception
as e:
430 log.warning(
"Using %s to resolve globalTag",schema)
433 folder = dbr.getFolder(folderPath)
434 tag = folder.resolveTag(globalTag)
436 log.info(
"Resolved globalTag \'%s\' to folderTag \'%s\'", globalTag,tag)
443 return (
int(iov >> 32),
int(iov & 0xFFFFFFFF))
447 def copyFolder(dbr, dbw, folder, tagr, tagw, chanNum, pointInTime1, pointInTime2):
449 log.info(
"Copy channel %i", chanNum)
451 folderR = dbr.getFolder(folder)
452 folderW = dbw.getFolder(folder)
454 chansel = cool.ChannelSelection(chanNum)
461 objs = folderR.browseObjects(iov1,iov2,chansel)
464 objs = folderR.browseObjects(iov1,iov2,chansel,tagr)
465 while objs.goToNext():
466 obj=objs.currentRef()
467 sinceCool=obj.since()
470 untilCool=obj.until()
474 log.debug(
"Copy entry: [%i,%i] - [%i,%i]: %s", sinceTup[0],sinceTup[1],untilTup[0],untilTup[1], data)
475 folderW.storeObject(sinceCool, untilCool, data, chanNum, tagw, multiVersion)
489 TileCalibBlobWriterBase is a helper class, managing the details of
490 COOL interactions for the user of TileCalibBlobs.
494 def __init__(self, db, folderPath, calibDrawerType,
495 isMultiVersionFolder=True, isRunLumiTimeStamp=True):
498 - db : db should be an open database connection
499 - folderPath: full folder path to create or update
503 TileCalibLogger.__init__(self,
"TileBlobWriter")
509 folderMode = cool.FolderVersioning.MULTI_VERSION
510 if not isMultiVersionFolder:
511 folderMode = cool.FolderVersioning.SINGLE_VERSION
515 if not isRunLumiTimeStamp:
521 if self.
__db.existsFolder(folderPath):
524 modeInCool = self.
__folder.versioningMode()
525 if modeInCool!=folderMode:
526 str =
"Incompatible folder mode detected, COOL folder has type "
527 if modeInCool==cool.FolderVersioning.MULTI_VERSION:
534 payloadSpec = cool.RecordSpecification()
535 payloadSpec.extend(
'TileCalibBlob', cool.StorageType.Blob64k )
536 folderSpec = cool.FolderSpecification(folderMode, payloadSpec)
537 self.
__folder = db.createFolder(folderPath, folderSpec, folderDescr,
True)
538 except Exception
as e:
539 self.log().critical( e )
548 if calibDrawerType==
'Flt':
549 self.
__defVec = cppyy.gbl.std.vector(
'std::vector<float>')()
550 elif calibDrawerType==
'Bch' or calibDrawerType==
'Int':
551 self.
__defVec = cppyy.gbl.std.vector(
'std::vector<unsigned int>')()
553 raise Exception(
"Unknown calibDrawerType: %s" % calibDrawerType)
557 def register(self, since=(MINRUN,MINLBK), until=(MAXRUN,MAXLBK), tag=
"", option=0):
559 Registers the folder in the database.
560 - since: lower limit of IOV
561 - until: upper limit of IOV
562 - tag : The cool folder tag to write to
564 The interpretation of the 'since' and 'until' inputs depends on their type:
565 - tuple(int,int) : run and lbk number
566 - integer : Values are interpreted as unix time stamps
567 If since<0, current time is assumed
568 If until<0, infinity is assumed
569 - string : time stamp of format 'yyyy-mm-dd hh:mm:ss'
574 raise Exception(
"Inconsistent types: since=%s, until=%s" % (
type(since),
type(until)))
578 if self.
__folder.versioningMode()==cool.FolderVersioning.SINGLE_VERSION:
582 self.log().warning(
"Trying to store with tag \"%s\" to SINGLE_VERSION folder", tag )
583 self.log().warning(
"... resetting tag to \"\"!" )
589 if untilCool <= sinceCool:
590 raise Exception(
"Until(%i) <= Since(%i)" % (untilCool,sinceCool))
594 if isinstance(since, tuple):
595 iovString =
"[%i,%i] - [%i,%i]" % (since[0],since[1],until[0],until[1])
597 sinceInfo = time.localtime( sinceCool//UNIX2COOL )
598 untilInfo = time.localtime(
min(UNIXTMAX, (untilCool//UNIX2COOL)))
599 untilStr =
"<infinity>"
600 if untilCool<cool.ValidityKeyMax:
601 untilStr = time.asctime(untilInfo)
602 if (untilCool//UNIX2COOL)>UNIXTMAX:
603 untilStr =
" > "+untilStr
604 iovString =
"[%s] - [%s]" % (time.asctime(sinceInfo), untilStr)
611 onlyComment = (option<0)
612 noComment = (comment
is None)
or (comment ==
"None")
or (comment.startswith(
"None")
and comment.endswith(
"None"))
or (option>0)
614 self.log().
info(
"... with IOV : %s" , iovString )
617 self.log().
info(
"... WITHOUT comment field" )
619 self.log().
info(
"... with comment field: \"%s\"", self.
getComment() )
627 for chanNum
in chanList:
628 if chanNum==1000
and noComment:
631 strout =
"cool channel=%4i" % chanNum
632 self.log().
debug(
"Registering %s %s", strout, data)
633 channelId = cool.ChannelId(chanNum)
634 self.
__folder.storeObject(sinceCool, untilCool, data, channelId, folderTag, userTagOnly)
637 self.log().
info(
"... %d cool channels have been written in total", cnt )
639 self.log().
info(
"... 1 cool channel with comment field has been written" )
641 self.log().
info(
"... %d cool channels have been written in total (including comment field)", cnt )
646 Sets a general comment in the comment channel.
652 spec = self.
__folder.payloadSpecification()
653 data = cool.Record( spec )
655 blob = data[
'TileCalibBlob']
656 if isinstance(author,tuple)
and len(author)==3:
657 tm=time.mktime(datetime.datetime.strptime(author[2],
"%a %b %d %H:%M:%S %Y").timetuple())
661 except Exception
as e:
662 self.log().critical( e )
667 Returns the general comment (default if none is set)
673 return "<No general comment!>"
674 blob = data[
'TileCalibBlob']
677 return (cmt.getAuthor(),cmt.getComment(),cmt.getDate())
679 return cmt.getFullComment()
680 except Exception
as e:
681 self.log().critical( e )
684 def getDrawer(self, ros, drawer, calibDrawerTemplate=None):
686 Returns a TileCalibDrawer object of requested type
687 for the given ROS and drawer.
699 spec = self.
__folder.payloadSpecification()
700 data = cool.Record( spec )
702 blob = data[
'TileCalibBlob']
712 raise Exception(
"Invalid blob type requested: %s" % type )
715 if calibDrawerTemplate:
716 calibDrawer.clone(calibDrawerTemplate)
722 except Exception
as e:
723 self.log().critical( e )
729 Resets blob size to zero
735 spec = self.
__folder.payloadSpecification()
736 data = cool.Record( spec )
738 blob = data[
'TileCalibBlob']
740 except Exception
as e:
741 self.log().critical( e )
756 TileCalibBlobReader is a helper class, managing the details of COOL interactions for
757 the user of TileCalibBlobs.
764 - db : db should be an open database connection
765 - folder: full folder path
766 - tag : The folder tag, e.g. \"000-00\"
769 TileCalibLogger.__init__(self,
"TileBlobReader")
775 except Exception
as e:
776 self.log().critical( e )
780 validFolderTypes = (
"run-lumi",
"time")
784 raise Exception(
"Invalid folder type found: \'%s\'" % self.
__folderType)
796 Returns the general comment (default if none is set)
801 obj = self.
__folder.findObject(validityKey, chanNum, self.
__tag)
802 self.log().
debug(
"getComment:Fetching from DB: %s", obj)
803 blob = obj.payload()[0]
806 return (cmt.getAuthor(),cmt.getComment(),cmt.getDate())
808 return cmt.getFullComment()
810 return "<no comment found>"
815 Returns a default drawer number (among first 20 COOL channels) for any drawer in any partition
818 if drawer<=4
or drawer==12
or drawer>=20:
824 elif ros==1
or ros==2:
827 OffsetEBA = [ 0, 0, 0, 0, 0, 0, 3, 2,
828 0, 0, 0, 0, 7, 6, 5, 7,
829 7, 6, 6, 7, 0, 0, 0, 2,
830 3, 0, 0, 0, 0, 0, 0, 0,
831 0, 0, 0, 0, 0, 0, 1, 1,
832 1, 1, 2, 3, 0, 0, 0, 0,
833 0, 0, 0, 0, 3, 2, 1, 1,
834 1, 1, 0, 0, 0, 0, 0, 0]
835 drawer1 = 12 + OffsetEBA[drawer]
837 OffsetEBC = [ 0, 0, 0, 0, 0, 0, 3, 2,
838 0, 0, 0, 0, 7, 6, 6, 7,
839 7, 5, 6, 7, 0, 0, 0, 2,
840 3, 0, 0, 3, 4, 0, 3, 4,
841 0, 4, 3, 0, 4, 3, 1, 1,
842 1, 1, 2, 3, 0, 0, 0, 0,
843 0, 0, 0, 0, 3, 2, 1, 1,
844 1, 1, 0, 0, 0, 0, 0, 0]
845 drawer1 = 12 + OffsetEBC[drawer]
852 def getDrawer(self, ros, drawer, pointInTime, printError=True, useDefault=True):
854 Returns a TileCalibDrawer object for the given ROS and drawer.
858 self.log().
debug(
"Validity key is %s", validityKey)
862 key = (ros,drawer,validityKey)
867 obj = self.
__folder.findObject(validityKey, chanNum, self.
__tag)
868 self.log().
debug(
"Fetching from DB: %s", obj)
869 blob = obj.payload()[0]
870 self.log().
debug(
"blob size: %d", blob.size())
872 if not useDefault
and blob.size()==0:
874 while blob.size()==0:
876 if ros==0
and drawer==0:
877 raise Exception(
'No default available')
881 obj = self.
__folder.findObject(validityKey, chanNum, self.
__tag)
882 blob = obj.payload()[0]
886 blob = obj.payload()[0]
887 self.log().
debug(
"blob size: %d", blob.size())
893 if typeName==
'TileCalibDrawerFlt':
895 self.log().
debug(
"typeName = Flt " )
896 elif typeName==
'TileCalibDrawerInt':
898 self.log().
debug(
"typeName = Int " )
899 elif typeName==
'TileCalibDrawerBch':
901 self.log().
debug(
"typeName = Bch " )
902 elif typeName==
'TileCalibDrawerOfc':
904 self.log().
debug(
"typeName = Ofc " )
906 raise Exception(
"Invalid blob type requested: %s" % typeName )
908 except Exception
as e:
910 self.log().
error(
"TileCalibTools.getDrawer(): Fetching of ros=%i, drawer=%i failed with exception %s", ros,drawer,e)
916 Returns a TileCalibDrawer object for the given ROS and drawer.
920 self.log().
debug(
"Validity key is %s", validityKey)
924 key = (ros,drawer,validityKey)
929 obj = self.
__folder.findObject(validityKey, chanNum, self.
__tag)
930 self.log().
debug(
"Fetching from DB: %s", obj)
931 blob = obj.payload()[0]
932 self.log().
debug(
"blob size: %d", blob.size())
934 while blob.size()==0:
936 if ros==0
and drawer==0:
937 raise Exception(
'No default available')
941 obj = self.
__folder.findObject(validityKey, chanNum, self.
__tag)
942 blob = obj.payload()[0]
946 blob = obj.payload()[0]
947 self.log().
debug(
"blob size: %d", blob.size())
953 if typeName==
'TileCalibDrawerFlt':
955 self.log().
debug(
"typeName = Flt " )
956 elif typeName==
'TileCalibDrawerInt':
958 self.log().
debug(
"typeName = Int " )
959 elif typeName==
'TileCalibDrawerBch':
961 self.log().
debug(
"typeName = Bch " )
962 elif typeName==
'TileCalibDrawerOfc':
964 self.log().
debug(
"typeName = Ofc " )
966 raise Exception(
"Invalid blob type requested: %s" % typeName )
968 except Exception
as e:
970 self.log().
error(
"TileCalibTools.getDefaultDrawer(): Fetching of ros=%i, drawer=%i failed with exception %s", ros,drawer,e)
974 def getDBobjsWithinRange(self, ros, drawer, point1inTime=(0,0), point2inTime=(2147483647,4294967295), printError=
True):
976 Returns all DB objects for the given ROS and drawer, within given validity range -- default: [0-Infty)
977 Check getBlobsWithinRange for an example on how to loop over objects and check validity ranges.
984 self.log().
debug(
"Validity key range is %s - %s", validityKey1,validityKey2)
989 dbChanSel = cool.ChannelSelection(dbChanNum)
991 objs = self.
__folder.browseObjects(validityKey1,validityKey2,dbChanSel,self.
__tag)
992 except Exception
as e:
994 self.log().
error(
"TileCalibTools.getDBobjsWithinRange(): Fetching of ros=%i, drawer=%i failed with exception %s", ros,drawer,e)
999 def getIOVsWithinRange(self, ros, drawer, point1inTime=(0,0), point2inTime=(2147483647,4294967295), printError=
True):
1001 Returns list of IOVS for the given ROS and drawer, within given validity range -- default: [0-Infty)
1005 if (dbobjs
is None):
1006 log.warning(
"Warning: can not read IOVs for ros %d drawer %d from input DB file", ros,drawer )
1008 while dbobjs.goToNext():
1009 obj = dbobjs.currentRef()
1010 objsince = obj.since()
1011 sinceRun = objsince >> 32
1012 sinceLum = objsince & 0xFFFFFFFF
1013 since = (sinceRun, sinceLum)
1020 Returns all blob objects for the given ROS and drawer, within given validity range -- default: [0-Infty)
1021 Note: the blobs don't contain validity range info. Check method getDBobjsWithinRange()
1027 print (
"Validity keys range is %s - %s" % (validityKey1, validityKey2))
1028 self.log().
debug(
"Validity key range is %s - %s", validityKey1,validityKey2)
1035 while objs.goToNext():
1036 obj=objs.currentRef()
1037 sinceCool=obj.since()
1038 if sinceCool < validityKey1:
1039 sinceCool = validityKey1
1040 untilCool=obj.until()
1041 blob = obj.payload()[0]
1042 print (
"[%d,%d)-[%d,%d) - %s" % ((sinceCool>>32),(sinceCool&0xFFFFFFFF),(untilCool>>32),(untilCool&0xFFFFFFFF),blob))
1043 self.log().
debug(
"blob size: %d", blob.size())
1046 while blob.size()==0:
1048 if ros==0
and drawer==0:
1049 raise Exception(
'No default available')
1053 obj = self.
__folder.findObject(sinceCool, chanNum, self.
__tag)
1054 blob = obj.payload()[0]
1055 self.log().
debug(
"blob size: 0 --> default: %d", blob.size())
1064 if typeName==
'TileCalibDrawerFlt':
1066 self.log().
debug(
"typeName = Flt " )
1067 elif typeName==
'TileCalibDrawerInt':
1069 self.log().
debug(
"typeName = Int " )
1070 elif typeName==
'TileCalibDrawerBch':
1072 self.log().
debug(
"typeName = Bch " )
1073 elif typeName==
'TileCalibDrawerOfc':
1075 self.log().
debug(
"typeName = Ofc " )
1077 raise Exception(
"Invalid blob type requested: %s" % typeName )
1079 blobs.append( calibDrawer )
1086 Returns true if MultiVersion folder is connected
1088 if self.
__folder.versioningMode()==cool.FolderVersioning.MULTI_VERSION:
1104 This is a class capable of parsing TileCal conditions data stored in
1105 ASCII files. Both the single and multi-line formats are supported.
1109 def __init__(self, fileName, calibId, isSingleLineFormat=True):
1112 - fileName : input file name
1113 - isSingleLineFormat: if False, multi line format is assumed
1116 TileCalibLogger.__init__(self,
"TileASCIIParser")
1119 lines =
open(fileName,
"r").readlines()
1120 except Exception
as e:
1121 self.log().
error(
"TileCalibASCIIParser::ERROR: Problem opening input file:" )
1122 self.log().
error( e )
1126 fields = line.strip().
split()
1128 if not len(fields) :
1130 if fields[0].startswith(
"#"):
1138 if not isSingleLineFormat:
1139 raise Exception(
"Multiline format not implemented yet")
1143 raise Exception(
"%s is not calibId=%s" % (type,calibId))
1146 if not (frag.startswith(
'0x')
or frag.startswith(
'-0x')
or frag.startswith(
'h_')):
1147 raise Exception(
"Misformated fragment %s" % frag)
1148 if frag.startswith(
'0x')
or frag.startswith(
'-0x'):
1156 elif frag.startswith(
'h_'):
1157 part_dict = {
'LBA':1,
'LBC':2,
'EBA':3,
'EBC':4}
1158 partname =
str(frag[2:5])
1159 ros=part_dict[partname]
1160 mod =
int(frag[5:])-1
1161 if (chan.startswith(
'ch')):
1168 dictKey = (ros,mod,chn)
1173 dictKey = (
int(ros),
int(drawer),
int(channel))
1184 "Reorder the PMTs (SV: how to get that from region.py???)"
1185 "This takes ros [1-4], drawer [0-63], pmt [1-48]"
1187 PMT2chan_Special={1:0,2:1,3:2,4:3,5:4,6:5,7:6,8:7,9:8,10:9,
1188 11:10,12:11,13:12,14:13,15:14,16:15,17:16,18:17, 19:18, 20:19,
1189 21:20,22:21,23:22,24:23,27:24,26:25,25:26,31:27,32:28,28:29,
1190 33:30,29:31,30:32,36:33,35:34,34:35,44:36,38:37,37:38,43:39,42:40,
1191 41:41,45:42,39:43,40:44,48:45,47:46,46:47}
1194 PMT2chan_LB={1:0,2:1,3:2,4:3,5:4,6:5,7:6,8:7,9:8,10:9,
1195 11:10,12:11,13:12,14:13,15:14,16:15,17:16,18:17,19:18,20:19,
1196 21:20,22:21,23:22,24:23,27:24,26:25,25:26,30:27,29:28,28:29,
1197 33:30,32:31,31:32,36:33,35:34,34:35,39:36,38:37,37:38,42:39,41:40,
1198 40:41,45:42,44:43,43:44,48:45,47:46,46:47}
1201 PMT2chan_EB={1:0,2:1,3:2,4:3,5:4,6:5,7:6,8:7,9:8,10:9,
1202 11:10,12:11,13:12,14:13,15:14,16:15,17:16,18:17,19:18,20:19,
1203 21:20,22:21,23:22,24:23,25:24,26:25,27:26,28:27,31:28,32:29,
1204 33:30,29:31,30:32,35:33,36:34,34:35,44:36,38:37,37:38,43:39,42:40,
1205 41:41,39:42,40:43,45:44,46:45,47:46,48:47}
1208 chan = PMT2chan_LB[pmt]
1209 elif (ros == 3
and drawer == 14)
or (ros == 4
and drawer == 17):
1210 chan = PMT2chan_Special[pmt]
1212 chan = PMT2chan_EB[pmt]
1226 This is a class capable of parsing TileCal conditions data stored in
1227 ASCII files. This version of parser can be used when mutiple IOVs are
1228 given in the file. First column is (run,lumi) pair in this case
1232 def __init__(self, fileName, calibId="", readGain=True):
1235 - fileName : input file name
1236 - calibId : like Ped, Las, ... or (r,l) or (run,lumi) but can be empty string as well
1237 - readGain : if False, no gain field in input file
1240 TileCalibLogger.__init__(self,
"TileASCIIParser2")
1248 lines =
open(fileName,
"r").readlines()
1249 except Exception
as e:
1250 self.log().
error(
"TileCalibASCIIParser2::ERROR: Problem opening input file:" )
1251 self.log().
error( e )
1254 self.log().
info(
"Parsing file %s",fileName)
1256 self.log().
info(
"Looking for prefix %s",calibId)
1259 fields = line.strip().
split()
1261 if not len(fields) :
1263 if fields[0].startswith(
"#"):
1271 if str(chan)[0:2].lower() ==
"pm":
1281 iov=tuple(
int(i)
for i
in pref[1:-1].
split(
","))
1282 if len(iov)!=2
or pref[0]!=
"(" or pref[-1]!=
")":
1283 raise Exception(
"%s is not %s IOV" % (pref,calibId))
1285 raise Exception(
"%s is not calibId=%s" % (pref,calibId))
1289 if str(chan)[0:2].lower() ==
"pm":
1298 if frag.startswith(
'0x')
or frag.startswith(
'-0x'):
1305 elif (frag.startswith(
"AUX")
or
1306 frag.startswith(
"LBA")
or
1307 frag.startswith(
"LBC")
or
1308 frag.startswith(
"EBA")
or
1309 frag.startswith(
"EBC")
or
1310 frag.startswith(
"ALL")
or
1311 frag.startswith(
"XXX") ):
1312 part_dict = {
'AUX':0,
'LBA':1,
'LBC':2,
'EBA':3,
'EBC':4,
'ALL':5,
'XXX':-1}
1313 partname =
str(frag[0:3])
1314 ros=part_dict[partname]
1315 mod =
int(frag[3:])-1
1317 raise Exception(
"Unknown fragment %s" % frag)
1333 if mod<0
or mod>=64:
1347 allchannels=(chn==-1)
1362 for ros
in range(rosmin,rosmax):
1363 for mod
in range(modmin,modmax):
1364 for chn
in range(chnmin,chnmax):
1365 if allchannels
or self.
channel2PMT(ros,mod,chn)>0:
1366 for adc
in range (adcmin,adcmax):
1367 dictKey = (ros,mod,chn,adc)
1377 def getData(self, ros, drawer, channel, adc, iov=(MAXRUN,MAXLBK)):
1378 dictKey = (
int(ros),
int(drawer),
int(channel),
int(adc))
1381 before= [i
for i
in sorted(data)
if i[0] <= iov ]
1383 data = before[-1][1]
1395 "Convert channel numbet to PMT number, negative for disconnected channels"
1396 "This takes ros [1-4], drawer [0-63], chan [0-47]"
1398 chan2PMT_LB=[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
1399 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1400 27, 26, 25, 30, 29, 28,-33,-32, 31, 36, 35, 34,
1401 39, 38, 37, 42, 41, 40, 45,-44, 43, 48, 47, 46 ]
1403 chan2PMT_EB=[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
1404 13, 14, 15, 16, 17, 18,-19,-20, 21, 22, 23, 24,
1405 -27,-26,-25,-31,-32,-28, 33, 29, 30,-36,-35, 34,
1406 44, 38, 37, 43, 42, 41,-45,-39,-40,-48,-47,-46 ]
1408 chan2PMT_Sp=[ -1, -2, -3, -4, 5, 6, 7, 8, 9, 10, 11, 12,
1409 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1410 -27,-26,-25,-31,-32,-28, 33, 29, 30,-36,-35, 34,
1411 44, 38, 37, 43, 42, 41,-45,-39,-40,-48,-47,-46 ]
1414 pmt = chan2PMT_LB[chan]
1415 elif (ros == 3
and drawer == 14)
or (ros == 4
and drawer == 17):
1416 pmt = chan2PMT_Sp[chan]
1418 pmt = chan2PMT_EB[chan]
1424 "Convert PMT number to channel numbet"
1425 "This takes partition (LBA,LBC,EBA,EBC) and pmt [1-48]"
1427 chan2PMT_LB=[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
1428 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1429 27, 26, 25, 30, 29, 28, 33, 32, 31, 36, 35, 34,
1430 39, 38, 37, 42, 41, 40, 45, 44, 43, 48, 47, 46 ]
1432 chan2PMT_EB=[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
1433 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1434 27, 26, 25, 31, 32, 28, 33, 29, 30, 36, 35, 34,
1435 44, 38, 37, 43, 42, 41, 45, 39, 40, 48, 47, 46 ]
1441 if str(partition)[0].
upper() ==
"E":
1442 chan = chan2PMT_EB.index(pm)
1444 chan = chan2PMT_LB.index(pm)
1457 This is a class capable of parsing TileCal conditions data stored in
1465 - fileName : input file name
1466 - calibId : like Trip, ...
1469 TileCalibLogger.__init__(self,
"TileASCIIParser3")
1472 lines =
open(fileName,
"r").readlines()
1473 except Exception
as e:
1474 self.log().
error(
"TileCalibASCIIParser3::ERROR: Problem opening input file:" )
1475 self.log().
error( e )
1479 fields = line.strip().
split()
1481 if not len(fields) :
1483 if fields[0].startswith(
"#"):
1493 raise Exception(
"%s is not calibId=%s" % (type, calibId))
1496 if not (frag.startswith(
'0x')
or frag.startswith(
'-0x')):
1497 raise Exception(
"Misformated fragment %s" % frag)
1507 dictKey = (ros, mod)
1512 dictKey = (
int(ros),
int(drawer))