12Python helper module for managing COOL DB connections and TileCalibBlobs.
16from PyCool
import cool
17import datetime, time, re, os, json
18from urllib.request
import urlopen
21from TileCalibBlobObjs.Classes
import TileCalibUtils, TileCalibDrawerCmt, \
22 TileCalibDrawerInt, TileCalibDrawerOfc, TileCalibDrawerBch, \
23 TileCalibDrawerFlt, TileCalibType
26from TileCalibBlobPython.TileCalibLogger
import TileCalibLogger, getLogger
27log = getLogger(
"TileCalibTools")
42MAXLBK = cool.UInt32Max
44UNIXTMAX = cool.Int32Max
52 Return the run number of next run to be taken in the pit
53 Keep this function temporary for backward compatibility
61 Return the run number of next run to be taken in the pit
64 urls = [
"http://atlas-run-info-api.web.cern.ch/api/runs?sort=runnumber:DESC&size=1",
65 "http://pcata007.cern.ch/cgi-bin/getLastRunNumber.py",
66 "http://pcata007.cern.ch/latestRun"]
71 for line
in urlopen(url).readlines():
78 run=int(jdata[
'resources'][0][
'runnumber'])
85 return max(run+1,222222)
91 Return the minimal run number of runs in prompt calibration loop
97 fin = open(
"/afs/cern.ch/user/a/atlcond/scratch0/nemo/prod/web/calibruns.txt",
"r").
read().
split()
101 promptCalibRuns.append( int(line) )
107 if len(promptCalibRuns)==0:
109 urls = [
"http://pcata007.cern.ch/cgi-bin/getBulkRunNumber.py",
110 "http://pcata007.cern.ch/latestRun"]
115 for line
in urlopen(url).readlines():
121 promptCalibRuns=[run]
126 if len(promptCalibRuns) >= 1:
127 promptCalibRuns.sort()
128 return promptCalibRuns[0]
136 Return name of top-level tag for 'Current' or 'CurrentES' or 'Next' or 'NextES' aliases
139 aliasfolder =
'/afs/cern.ch/atlas/conditions/poolcond/buffer/BestKnowledge'
141 falias = open(
'%s/%s' % (aliasfolder, aliastype))
142 alias = falias.readline()
144 return alias.replace(
'\n',
'').
replace(
'*',
'')
147 aliasfolder = os.getcwd()+
'/BestKnowledge'
148 print(
"Looking for %s in %s" % (aliastype,aliasfolder))
150 falias = open(
'%s/%s' % (aliasfolder, aliastype))
151 alias = falias.readline()
153 return alias.replace(
'\n',
'').
replace(
'*',
'')
155 return aliastype.upper()
161 Returns the common Tile prefix used for all COOL folders.
162 ofl = False ... single version folders
163 ofl = True ... multiversion folders
164 splitOnlInOflSchema = False ... offline only folders or
165 splitOnline folders in Online schema
166 splitOnlInOflSchema = True ... splitOnlineFolders in
170 if splitOnlInOflSchema:
171 return "/TILE/OFL02/"
173 return "/TILE/OFL01/"
175 return "/TILE/ONL01/"
181 Returns a list of all TILE folder prefixes
183 return [
"/TILE/ONL01/",
"/TILE/OFL01/",
"/TILE/OFL02/"]
189 Returns the run-lumi type folder description needed to read back the folder content
190 as a CondAttrListCollection in Athena.
192 desc =
'<timeStamp>'+type+
'</timeStamp>'
193 desc+=
'<addrHeader><address_header service_type="71" clid="1238547719" /></addrHeader>'
194 desc+=
'<typeName>CondAttrListCollection</typeName>'
200 type = re.compile(
".*<timeStamp>(.*)</timeStamp>.*").
search(folderDescr)
202 raise Exception(
"No folder type info found in \'%s\'" % folderDescr)
203 return type.groups()[0]
207def openDb(db, instance, mode="READONLY", schema="COOLOFL_TILE", sqlfn="tileSqlite.db"):
209 Opens a COOL db connection.
210 - db: The DB type. The following names are recognized:
211 * SQLITE: Opens file mentioned in sqlfn parameter
212 * ORACLE or FRONTIER: Opens ORACLE DB, forces READONLY
213 - instance: One of valid instances - CONDBR2 OFLP200 COMP200 CMCP200
214 - mode: Can be READONLY (default), RECREATE or UPDATE
215 - schema: One of valid schemas - COOLONL_CALO COOLOFL_CALO COOLONL_LAR COOLOFL_LAR COOLONL_TILE COOLOFL_TILE
216 - sqlfn: Name of sqlite file if db is SQLITE
220 validDb = [
"SQLITE",
"ORACLE",
"FRONTIER"]
221 if db
not in validDb:
222 raise Exception(
"DB not valid: %s, valid DBs are: %s" % (db,validDb) )
223 elif db ==
"ORACLE" or db ==
"FRONTIER":
227 validInstance = [
"COMP200",
"CONDBR2",
"CMCP200",
"OFLP200"]
228 if instance
not in validInstance:
229 raise Exception(
"Instance not valid: %s, valid instance are: %s" % (instance,validInstance) )
232 validSchema = [
"COOLONL_TILE",
"COOLOFL_TILE"]
233 if schema
not in validSchema:
234 raise Exception(
"Schema not valid: %s, valid schemas are: %s" % (schema,validSchema) )
239 if mode==
"READONLY" and not os.path.exists(sqlfn):
240 raise Exception(
"Sqlite file %s does not exist" % (sqlfn) )
241 if (mode==
"RECREATE" or mode==
"UPDATE")
and not os.path.exists(os.path.dirname(sqlfn)):
242 dirn=os.path.dirname(sqlfn)
245 connStr=
"sqlite://X;schema=%s;dbname=%s" % (sqlfn,instance)
247 connStr=
'frontier://ATLF/()/;schema=ATLAS_%s;dbname=%s' % (schema,instance)
249 connStr=
'oracle://%s;schema=ATLAS_%s;dbname=%s' % (
'ATLAS_COOLPROD',schema,instance)
251 connStr=schema+
'/'+instance
259 Opens a COOL db connection.
260 - db: The DB type. The following names are recognized:
261 * ORACLE or FRONTIER: Opens ORACLE DB, forces READONLY
262 - schema: Full schema string for sqlite file, dbname will be extracted from this string
263 - folder: Fill folder path, schema string will be construced using folder name
267 if '/OFL' in folder.upper():
271 connStr += folder.strip(
'/').
split(
'/')[0].
upper()
272 dbn=schema.split(
'dbname=')
274 dbname=dbn[1].
split(
';')[0]
277 connStr +=
'/' + dbname
285 Opens a COOL db connection.
286 - connStr: The DB connection string
287 - mode: Can be READONLY (default), RECREATE or UPDATE
288 or ORACLE or FRONTIER if connStr is only short name of the database
292 splitname=connStr.split(
'/')
293 if (len(splitname)!=2):
297 instance=splitname[1]
299 connStr_new=
'oracle://%s;schema=ATLAS_%s;dbname=%s' % (
'ATLAS_COOLPROD',schema,instance)
301 connStr_new=
'frontier://ATLF/()/;schema=ATLAS_%s;dbname=%s' % (schema,instance)
304 dbSvc = cool.DatabaseSvcFactory.databaseService()
305 log.info(
"---------------------------------------------------------------------------------" )
306 log.info(
"-------------------------- TileCalibTools.openDbConn ----------------------------" )
307 log.info(
"- using COOL version %s", dbSvc.serviceVersion() )
308 log.info(
"- opening TileDb: %s",connStr_new )
309 log.info(
"- mode: %s", mode )
310 log.info(
"---------------------------------------------------------------------------------" )
313 if mode
in [
"READONLY",
"ORACLE",
"FRONTIER",
"",
None]:
316 db=dbSvc.openDatabase(connStr_new,
True)
317 except Exception
as e:
319 log.critical(
"Could not connect to %s" % connStr_new )
322 elif mode==
"RECREATE":
324 dbSvc.dropDatabase(connStr_new)
326 db = dbSvc.createDatabase(connStr_new)
327 except Exception
as e:
329 log.critical(
"Could not create database, giving up..." )
335 db=dbSvc.openDatabase(connStr_new,
False)
336 except Exception
as e:
338 log.warning(
"Could not connect to \'%s\', trying to create it....", connStr_new )
340 db=dbSvc.createDatabase(connStr_new)
341 except Exception
as e:
343 log.critical(
"Could not create database, giving up..." )
347 log.error(
"Mode \"%s\" not recognized", mode )
354 Returns COOL timeStamp build from run and lumi block numbers
356 return (int(runNum)<<32) + int(lbkNum)
362 Retruns UNIX time stamp given an input time string
364 return int(time.mktime(time.strptime(timeString,
"%Y-%m-%d %H:%M:%S")))
370 The interpretation of pointInTime depends on their type:
371 - tuple(int,int) : run and lbk number
372 - integer : Values are interpreted as unix time stamps
373 - string : time stamp of format 'yyyy-mm-dd hh:mm:ss'
379 if isinstance(pointInTime, str):
383 if isinstance(pointInTime, int):
385 validityKey = pointInTime * UNIX2COOL
388 validityKey = int(time.time()) * UNIX2COOL
390 validityKey = cool.ValidityKeyMax
392 elif isinstance(pointInTime, tuple):
396 raise Exception(
"Unrecognized pointInTime type=%s" %
type(pointInTime))
397 return cool.ValidityKey(validityKey)
405 gTAG = globalTag.upper()
406 findTAG = (gTAG ==
"ANY" or gTAG ==
"FIRST" or gTAG ==
"LAST")
407 if globalTag.startswith(
"/")
or globalTag.startswith(
"TileO")
or globalTag.upper().startswith(
"CALO"):
409 log.warning(
"Using tag as-is for folder %s", folderPath)
410 elif '/TILE/ONL01' in folderPath:
411 log.info(
"Using empty tag for single-version folder %s", folderPath)
412 elif globalTag.startswith(
" "):
413 log.warning(
"Using empty tag for folder %s", folderPath)
416 log.warning(
"Using tag with empty suffix for folder %s", folderPath)
418 if folderPath.startswith(
'/CALO'):
419 dbname =
'COOLOFL_CALO' if folderPath.startswith(
'/CALO/Ofl')
else 'COOLONL_CALO'
421 dbname =
'COOLOFL_TILE'
422 schema=dbname+
'/CONDBR2'
423 if isinstance(db, str):
424 if 'OFLP200' in db
or 'MC' in db:
425 schema=dbname+
'/OFLP200'
426 if not globalTag.startswith(
"OFLCOND"):
427 if globalTag.startswith(
"RUN"):
428 globalTag=
'OFLCOND-'+globalTag
429 log.info(
"Using Simulation global tag \'%s\'", globalTag)
430 elif 'COMP200' in db
or 'RUN1' in db:
431 schema=dbname+
'/COMP200'
432 if globalTag!=
'UPD1' and globalTag!=
'UPD4' and (
'UPD1' in globalTag
or 'UPD4' in globalTag
or 'COND' not in globalTag):
434 log.info(
"Using suffix \'%s\' as it is", globalTag)
437 globalTag=
'COMCOND-BLKPA-RUN1-06'
438 log.info(
"Using RUN1 global tag \'%s\'", globalTag)
439 if schema == dbname+
'/CONDBR2':
440 if globalTag==
'CURRENT' or globalTag==
'UPD4' or globalTag==
'':
442 log.info(
"Resolved CURRENT globalTag to \'%s\'", globalTag)
443 elif globalTag==
'CURRENTES' or globalTag==
'UPD1':
445 log.info(
"Resolved CURRENT ES globalTag to \'%s\'", globalTag)
446 elif globalTag==
'NEXT':
448 log.info(
"Resolved NEXT globalTag to \'%s\'", globalTag)
449 elif globalTag==
'NEXTES':
451 log.info(
"Resolved NEXT ES globalTag to \'%s\'", globalTag)
452 globalTag=globalTag.replace(
'*',
'')
453 if not findTAG
and (
'UPD1' in globalTag
or 'UPD4' in globalTag
or 'COND' not in globalTag):
455 if tag.startswith(
'Calo')
and 'NoiseCell' not in tag:
457 tag=tag.replace(
'Pileupnoiselumi',
'PileUpNoiseLumi')
458 log.info(
"Resolved localTag \'%s\' to folderTag \'%s\'", globalTag,tag)
460 if not isinstance(db, str):
462 folder = db.getFolder(folderPath)
466 tag = folder.resolveTag(globalTag)
467 log.info(
"Resolved globalTag \'%s\' to folderTag \'%s\'", globalTag,tag)
469 except Exception
as e:
471 log.warning(
"Using %s to resolve globalTag",schema)
474 folder = dbr.getFolder(folderPath)
478 tag = folder.resolveTag(globalTag)
480 log.info(
"Resolved globalTag \'%s\' to folderTag \'%s\'", globalTag,tag)
487 taglist=folder.listTags()
494 return 'tag-not-found'
499 return (int(iov >> 32), int(iov & 0xFFFFFFFF))
503def copyFolder(dbr, dbw, folder, tagr, tagw, chanNum, pointInTime1, pointInTime2):
505 log.info(
"Copy channel %i", chanNum)
507 folderR = dbr.getFolder(folder)
508 folderW = dbw.getFolder(folder)
510 chansel = cool.ChannelSelection(chanNum)
517 objs = folderR.browseObjects(iov1,iov2,chansel)
520 objs = folderR.browseObjects(iov1,iov2,chansel,tagr)
521 while objs.goToNext():
522 obj=objs.currentRef()
523 sinceCool=obj.since()
526 untilCool=obj.until()
530 log.debug(
"Copy entry: [%i,%i] - [%i,%i]: %s", sinceTup[0],sinceTup[1],untilTup[0],untilTup[1], data)
531 folderW.storeObject(sinceCool, untilCool, data, chanNum, tagw, multiVersion)
535def moduleListToString(modules, checkAUX=True, checkMOD=True, checkComment=True, shortLength=15, exceptLength=15):
537 fulllist =
"@".join(modules)
541 list1=re.findall(
"AUX..",fulllist)
543 mlist += [
"ALL 20 AUX modules"]
545 mlist += [
" ".join(list1)]
547 mlist += [
"NO AUX modules"]
550 list2=re.findall(
"[LE]B[AC]..",fulllist)
552 mlist += [
"ALL 256 modules"]
553 elif 256-len(list2)<=exceptLength:
555 for p
in [
"LBA",
"LBC",
"EBA",
"EBC"]:
556 for n
in range(1,65):
560 mlist += [
"%d modules: all except %s" % (len(list2),
" ".join(list3))]
562 if len(list2)<=shortLength:
563 mlist += [
" ".join(list2)]
565 for p
in [
"LBA",
"LBC",
"EBA",
"EBC"]:
566 list2=re.findall(p+
"..",fulllist)
568 mlist += [
"64 %s modules" % p]
569 elif 64-len(list2)<=exceptLength:
571 for n
in range(1,65):
575 mlist += [
"%d %s modules: all except %s" % (len(list2),p,
" ".join(list3))]
577 mlist += [
" ".join(list2)]
579 mlist += [
"NO %s modules" % p]
581 mlist += [
"NO modules"]
584 list4=re.findall(
"Comment[^@]*",fulllist)
586 mlist += [
" ".join(list4)]
588 mlist += [
"NO COMMENT"]
590 all =
", ".join(mlist)
605 TileCalibBlobWriterBase is a helper class, managing the details of
606 COOL interactions for the user of TileCalibBlobs.
610 def __init__(self, db, folderPath, calibDrawerType,
611 isMultiVersionFolder=True, isRunLumiTimeStamp=True):
614 - db : db should be an open database connection
615 - folderPath: full folder path to create or update
619 TileCalibLogger.__init__(self,
"TileBlobWriter")
625 folderMode = cool.FolderVersioning.MULTI_VERSION
626 if not isMultiVersionFolder:
627 folderMode = cool.FolderVersioning.SINGLE_VERSION
631 if not isRunLumiTimeStamp:
637 if self.
__db.existsFolder(folderPath):
640 modeInCool = self.
__folder.versioningMode()
641 if modeInCool!=folderMode:
642 str =
"Incompatible folder mode detected, COOL folder has type "
643 if modeInCool==cool.FolderVersioning.MULTI_VERSION:
650 payloadSpec = cool.RecordSpecification()
651 payloadSpec.extend(
'TileCalibBlob', cool.StorageType.Blob64k )
652 folderSpec = cool.FolderSpecification(folderMode, payloadSpec)
653 self.
__folder = db.createFolder(folderPath, folderSpec, folderDescr,
True)
654 except Exception
as e:
655 self.log().critical( e )
664 if calibDrawerType==
'Flt':
665 self.
__defVec = cppyy.gbl.std.vector(
'std::vector<float>')()
666 elif calibDrawerType==
'Bch' or calibDrawerType==
'Int':
667 self.
__defVec = cppyy.gbl.std.vector(
'std::vector<unsigned int>')()
669 raise Exception(
"Unknown calibDrawerType: %s" % calibDrawerType)
673 def register(self, since=(MINRUN,MINLBK), until=(MAXRUN,MAXLBK), tag=
"", option=0):
675 Registers the folder in the database.
676 - since: lower limit of IOV
677 - until: upper limit of IOV
678 - tag : The cool folder tag to write to
680 The interpretation of the 'since' and 'until' inputs depends on their type:
681 - tuple(int,int) : run and lbk number
682 - integer : Values are interpreted as unix time stamps
683 If since<0, current time is assumed
684 If until<0, infinity is assumed
685 - string : time stamp of format 'yyyy-mm-dd hh:mm:ss'
690 raise Exception(
"Inconsistent types: since=%s, until=%s" % (
type(since),
type(until)))
694 if self.
__folder.versioningMode()==cool.FolderVersioning.SINGLE_VERSION:
698 self.log().warning(
"Trying to store with tag \"%s\" to SINGLE_VERSION folder", tag )
699 self.log().warning(
"... resetting tag to \"\"!" )
705 if untilCool <= sinceCool:
706 raise Exception(
"Until(%i) <= Since(%i)" % (untilCool,sinceCool))
710 if isinstance(since, tuple):
711 iovString =
"[%i,%i] - [%i,%i]" % (since[0],since[1],until[0],until[1])
713 sinceInfo = time.localtime( sinceCool//UNIX2COOL )
714 untilInfo = time.localtime(
min(UNIXTMAX, (untilCool//UNIX2COOL)))
715 untilStr =
"<infinity>"
716 if untilCool<cool.ValidityKeyMax:
717 untilStr = time.asctime(untilInfo)
718 if (untilCool//UNIX2COOL)>UNIXTMAX:
719 untilStr =
" > "+untilStr
720 iovString =
"[%s] - [%s]" % (time.asctime(sinceInfo), untilStr)
727 onlyComment = (option<0)
728 noComment = (comment
is None)
or (comment ==
"None")
or (comment.startswith(
"None")
and comment.endswith(
"None"))
or (option>0)
729 self.log().info(
"Registering folder %s with tag \"%s\"", self.
__folder.fullPath(),folderTag)
730 self.log().info(
"... with IOV : %s" , iovString )
733 self.log().info(
"... WITHOUT comment field" )
735 self.log().info(
"... with comment field: \"%s\"", self.
getComment() )
743 for chanNum
in chanList:
744 if chanNum==1000
and noComment:
747 strout =
"cool channel=%4i" % chanNum
748 self.log().
debug(
"Registering %s %s", strout, data)
749 channelId = cool.ChannelId(chanNum)
750 self.
__folder.storeObject(sinceCool, untilCool, data, channelId, folderTag, userTagOnly)
753 self.log().info(
"... %d cool channels have been written in total", cnt )
755 self.log().info(
"... 1 cool channel with comment field has been written" )
757 self.log().info(
"... %d cool channels have been written in total (including comment field)", cnt )
762 Sets a general comment in the comment channel.
768 spec = self.
__folder.payloadSpecification()
769 data = cool.Record( spec )
771 blob = data[
'TileCalibBlob']
772 if isinstance(author,tuple)
and len(author)==3:
773 tm=time.mktime(datetime.datetime.strptime(author[2],
"%a %b %d %H:%M:%S %Y").timetuple())
777 except Exception
as e:
778 self.log().critical( e )
783 Returns the general comment (default if none is set)
789 return "<No general comment!>"
790 blob = data[
'TileCalibBlob']
793 return (cmt.getAuthor(),cmt.getComment(),cmt.getDate())
795 return cmt.getFullComment()
796 except Exception
as e:
797 self.log().critical( e )
800 def getDrawer(self, ros, drawer, calibDrawerTemplate=None):
802 Returns a TileCalibDrawer object of requested type
803 for the given ROS and drawer.
815 spec = self.
__folder.payloadSpecification()
816 data = cool.Record( spec )
818 blob = data[
'TileCalibBlob']
828 raise Exception(
"Invalid blob type requested: %s" % type )
831 if calibDrawerTemplate:
832 calibDrawer.clone(calibDrawerTemplate)
838 except Exception
as e:
839 self.log().critical( e )
845 Resets blob size to zero
851 spec = self.
__folder.payloadSpecification()
852 data = cool.Record( spec )
854 blob = data[
'TileCalibBlob']
856 except Exception
as e:
857 self.log().critical( e )
872 TileCalibBlobReader is a helper class, managing the details of COOL interactions for
873 the user of TileCalibBlobs.
880 - db : db should be an open database connection
881 - folder: full folder path
882 - tag : The folder tag, e.g. \"000-00\"
885 TileCalibLogger.__init__(self,
"TileBlobReader")
891 except Exception
as e:
892 self.log().critical( e )
896 validFolderTypes = (
"run-lumi",
"time")
900 raise Exception(
"Invalid folder type found: \'%s\'" % self.
__folderType)
912 Returns the general comment (default if none is set)
917 obj = self.
__folder.findObject(validityKey, chanNum, self.
__tag)
918 self.log().
debug(
"getComment:Fetching from DB: %s", obj)
919 blob = obj.payload()[0]
922 return (cmt.getAuthor(),cmt.getComment(),cmt.getDate())
924 return cmt.getFullComment()
926 return "<no comment found>"
931 Returns a default drawer number (among first 20 COOL channels) for any drawer in any partition
934 if drawer<=4
or drawer==12
or drawer>=20:
940 elif ros==1
or ros==2:
943 OffsetEBA = [ 0, 0, 0, 0, 0, 0, 3, 2,
944 0, 0, 0, 0, 7, 6, 5, 7,
945 7, 6, 6, 7, 0, 0, 0, 2,
946 3, 0, 0, 0, 0, 0, 0, 0,
947 0, 0, 0, 0, 0, 0, 1, 1,
948 1, 1, 2, 3, 0, 0, 0, 0,
949 0, 0, 0, 0, 3, 2, 1, 1,
950 1, 1, 0, 0, 0, 0, 0, 0]
951 drawer1 = 12 + OffsetEBA[drawer]
953 OffsetEBC = [ 0, 0, 0, 0, 0, 0, 3, 2,
954 0, 0, 0, 0, 7, 6, 6, 7,
955 7, 5, 6, 7, 0, 0, 0, 2,
956 3, 0, 0, 3, 4, 0, 3, 4,
957 0, 4, 3, 0, 4, 3, 1, 1,
958 1, 1, 2, 3, 0, 0, 0, 0,
959 0, 0, 0, 0, 3, 2, 1, 1,
960 1, 1, 0, 0, 0, 0, 0, 0]
961 drawer1 = 12 + OffsetEBC[drawer]
968 def getDrawer(self, ros, drawer, pointInTime, printError=True, useDefault=True):
970 Returns a TileCalibDrawer object for the given ROS and drawer.
974 self.log().
debug(
"Validity key is %s", validityKey)
978 key = (ros,drawer,validityKey)
983 obj = self.
__folder.findObject(validityKey, chanNum, self.
__tag)
984 self.log().
debug(
"Fetching from DB: %s", obj)
985 blob = obj.payload()[0]
986 self.log().
debug(
"blob size: %d", blob.size())
988 if not useDefault
and blob.size()==0:
990 while blob.size()==0:
992 if ros==0
and drawer==0:
993 raise Exception(
'No default available')
997 obj = self.
__folder.findObject(validityKey, chanNum, self.
__tag)
998 blob = obj.payload()[0]
1002 blob = obj.payload()[0]
1003 self.log().
debug(
"blob size: %d", blob.size())
1009 if typeName==
'TileCalibDrawerFlt':
1011 self.log().
debug(
"typeName = Flt " )
1012 elif typeName==
'TileCalibDrawerInt':
1014 self.log().
debug(
"typeName = Int " )
1015 elif typeName==
'TileCalibDrawerBch':
1017 self.log().
debug(
"typeName = Bch " )
1018 elif typeName==
'TileCalibDrawerOfc':
1020 self.log().
debug(
"typeName = Ofc " )
1022 raise Exception(
"Invalid blob type requested: %s" % typeName )
1024 except Exception
as e:
1026 self.log().
error(
"TileCalibTools.getDrawer(): Fetching of ros=%i, drawer=%i failed with exception %s", ros,drawer,e)
1032 Returns a TileCalibDrawer object for the given ROS and drawer.
1036 self.log().
debug(
"Validity key is %s", validityKey)
1040 key = (ros,drawer,validityKey)
1045 obj = self.
__folder.findObject(validityKey, chanNum, self.
__tag)
1046 self.log().
debug(
"Fetching from DB: %s", obj)
1047 blob = obj.payload()[0]
1048 self.log().
debug(
"blob size: %d", blob.size())
1050 while blob.size()==0:
1052 if ros==0
and drawer==0:
1053 raise Exception(
'No default available')
1057 obj = self.
__folder.findObject(validityKey, chanNum, self.
__tag)
1058 blob = obj.payload()[0]
1062 blob = obj.payload()[0]
1063 self.log().
debug(
"blob size: %d", blob.size())
1069 if typeName==
'TileCalibDrawerFlt':
1071 self.log().
debug(
"typeName = Flt " )
1072 elif typeName==
'TileCalibDrawerInt':
1074 self.log().
debug(
"typeName = Int " )
1075 elif typeName==
'TileCalibDrawerBch':
1077 self.log().
debug(
"typeName = Bch " )
1078 elif typeName==
'TileCalibDrawerOfc':
1080 self.log().
debug(
"typeName = Ofc " )
1082 raise Exception(
"Invalid blob type requested: %s" % typeName )
1084 except Exception
as e:
1086 self.log().
error(
"TileCalibTools.getDefaultDrawer(): Fetching of ros=%i, drawer=%i failed with exception %s", ros,drawer,e)
1090 def getDBobjsWithinRange(self, ros, drawer, point1inTime=(0,0), point2inTime=(2147483647,4294967295), printError=
True):
1092 Returns all DB objects for the given ROS and drawer, within given validity range -- default: [0-Infty)
1093 Check getBlobsWithinRange for an example on how to loop over objects and check validity ranges.
1100 self.log().
debug(
"Validity key range is %s - %s", validityKey1,validityKey2)
1105 dbChanSel = cool.ChannelSelection(dbChanNum)
1107 objs = self.
__folder.browseObjects(validityKey1,validityKey2,dbChanSel,self.
__tag)
1108 except Exception
as e:
1110 self.log().
error(
"TileCalibTools.getDBobjsWithinRange(): Fetching of ros=%i, drawer=%i failed with exception %s", ros,drawer,e)
1115 def getIOVsWithinRange(self, ros, drawer, point1inTime=(0,0), point2inTime=(2147483647,4294967295), printError=
True):
1117 Returns list of IOVS for the given ROS and drawer, within given validity range -- default: [0-Infty)
1121 if (dbobjs
is None):
1122 log.warning(
"Warning: can not read IOVs for ros %d drawer %d from input DB file", ros,drawer )
1124 while dbobjs.goToNext():
1125 obj = dbobjs.currentRef()
1126 objsince = obj.since()
1127 sinceRun = objsince >> 32
1128 sinceLum = objsince & 0xFFFFFFFF
1129 since = (sinceRun, sinceLum)
1136 Returns all blob objects for the given ROS and drawer, within given validity range -- default: [0-Infty)
1137 Note: the blobs don't contain validity range info. Check method getDBobjsWithinRange()
1143 print (
"Validity keys range is %s - %s" % (validityKey1, validityKey2))
1144 self.log().
debug(
"Validity key range is %s - %s", validityKey1,validityKey2)
1151 while objs.goToNext():
1152 obj=objs.currentRef()
1153 sinceCool=obj.since()
1154 if sinceCool < validityKey1:
1155 sinceCool = validityKey1
1156 untilCool=obj.until()
1157 blob = obj.payload()[0]
1158 print (
"[%d,%d)-[%d,%d) - %s" % ((sinceCool>>32),(sinceCool&0xFFFFFFFF),(untilCool>>32),(untilCool&0xFFFFFFFF),blob))
1159 self.log().
debug(
"blob size: %d", blob.size())
1162 while blob.size()==0:
1164 if ros==0
and drawer==0:
1165 raise Exception(
'No default available')
1169 obj = self.
__folder.findObject(sinceCool, chanNum, self.
__tag)
1170 blob = obj.payload()[0]
1171 self.log().
debug(
"blob size: 0 --> default: %d", blob.size())
1180 if typeName==
'TileCalibDrawerFlt':
1182 self.log().
debug(
"typeName = Flt " )
1183 elif typeName==
'TileCalibDrawerInt':
1185 self.log().
debug(
"typeName = Int " )
1186 elif typeName==
'TileCalibDrawerBch':
1188 self.log().
debug(
"typeName = Bch " )
1189 elif typeName==
'TileCalibDrawerOfc':
1191 self.log().
debug(
"typeName = Ofc " )
1193 raise Exception(
"Invalid blob type requested: %s" % typeName )
1195 blobs.append( calibDrawer )
1202 Returns true if MultiVersion folder is connected
1204 if self.
__folder.versioningMode()==cool.FolderVersioning.MULTI_VERSION:
1220 This is a class capable of parsing TileCal conditions data stored in
1221 ASCII files. Both the single and multi-line formats are supported.
1225 def __init__(self, fileName, calibId, isSingleLineFormat=True):
1228 - fileName : input file name
1229 - isSingleLineFormat: if False, multi line format is assumed
1232 TileCalibLogger.__init__(self,
"TileASCIIParser")
1235 lines = open(fileName,
"r").readlines()
1236 except Exception
as e:
1237 self.log().
error(
"TileCalibASCIIParser::ERROR: Problem opening input file:" )
1238 self.log().
error( e )
1242 fields = line.strip().
split()
1244 if not len(fields) :
1246 if fields[0].startswith(
"#"):
1254 if not isSingleLineFormat:
1255 raise Exception(
"Multiline format not implemented yet")
1259 raise Exception(
"%s is not calibId=%s" % (type,calibId))
1262 if not (frag.startswith(
'0x')
or frag.startswith(
'-0x')
or frag.startswith(
'h_')):
1263 raise Exception(
"Misformated fragment %s" % frag)
1264 if frag.startswith(
'0x')
or frag.startswith(
'-0x'):
1272 elif frag.startswith(
'h_'):
1273 part_dict = {
'LBA':1,
'LBC':2,
'EBA':3,
'EBC':4}
1274 partname = str(frag[2:5])
1275 ros=part_dict[partname]
1276 mod = int(frag[5:])-1
1277 if (chan.startswith(
'ch')):
1284 dictKey = (ros,mod,chn)
1289 dictKey = (int(ros), int(drawer), int(channel))
1300 "Reorder the PMTs (SV: how to get that from region.py???)"
1301 "This takes ros [1-4], drawer [0-63], pmt [1-48]"
1303 PMT2chan_Special={1:0,2:1,3:2,4:3,5:4,6:5,7:6,8:7,9:8,10:9,
1304 11:10,12:11,13:12,14:13,15:14,16:15,17:16,18:17, 19:18, 20:19,
1305 21:20,22:21,23:22,24:23,27:24,26:25,25:26,31:27,32:28,28:29,
1306 33:30,29:31,30:32,36:33,35:34,34:35,44:36,38:37,37:38,43:39,42:40,
1307 41:41,45:42,39:43,40:44,48:45,47:46,46:47}
1310 PMT2chan_LB={1:0,2:1,3:2,4:3,5:4,6:5,7:6,8:7,9:8,10:9,
1311 11:10,12:11,13:12,14:13,15:14,16:15,17:16,18:17,19:18,20:19,
1312 21:20,22:21,23:22,24:23,27:24,26:25,25:26,30:27,29:28,28:29,
1313 33:30,32:31,31:32,36:33,35:34,34:35,39:36,38:37,37:38,42:39,41:40,
1314 40:41,45:42,44:43,43:44,48:45,47:46,46:47}
1317 PMT2chan_EB={1:0,2:1,3:2,4:3,5:4,6:5,7:6,8:7,9:8,10:9,
1318 11:10,12:11,13:12,14:13,15:14,16:15,17:16,18:17,19:18,20:19,
1319 21:20,22:21,23:22,24:23,25:24,26:25,27:26,28:27,31:28,32:29,
1320 33:30,29:31,30:32,35:33,36:34,34:35,44:36,38:37,37:38,43:39,42:40,
1321 41:41,39:42,40:43,45:44,46:45,47:46,48:47}
1324 chan = PMT2chan_LB[pmt]
1325 elif (ros == 3
and drawer == 14)
or (ros == 4
and drawer == 17):
1326 chan = PMT2chan_Special[pmt]
1328 chan = PMT2chan_EB[pmt]
1342 This is a class capable of parsing TileCal conditions data stored in
1343 ASCII files. This version of parser can be used when mutiple IOVs are
1344 given in the file. First column is (run,lumi) pair in this case
1348 def __init__(self, fileName, calibId="", readGain=True):
1351 - fileName : input file name
1352 - calibId : like Ped, Las, ... or (r,l) or (run,lumi) but can be empty string as well
1353 - readGain : if False, no gain field in input file
1356 TileCalibLogger.__init__(self,
"TileASCIIParser2")
1364 lines = open(fileName,
"r").readlines()
1365 except Exception
as e:
1366 self.log().
error(
"TileCalibASCIIParser2::ERROR: Problem opening input file:" )
1367 self.log().
error( e )
1370 self.log().info(
"Parsing file %s",fileName)
1372 self.log().info(
"Looking for prefix %s",calibId)
1375 fields = line.strip().
split()
1377 if not len(fields) :
1379 if fields[0].startswith(
"#"):
1387 if str(chan)[0:2].lower() ==
"pm":
1397 iov=tuple(int(i)
for i
in pref[1:-1].
split(
","))
1398 if len(iov)!=2
or pref[0]!=
"(" or pref[-1]!=
")":
1399 raise Exception(
"%s is not %s IOV" % (pref,calibId))
1401 raise Exception(
"%s is not calibId=%s" % (pref,calibId))
1405 if str(chan)[0:2].lower() ==
"pm":
1414 if frag.startswith(
'0x')
or frag.startswith(
'-0x'):
1421 elif (frag.startswith(
"AUX")
or
1422 frag.startswith(
"LBA")
or
1423 frag.startswith(
"LBC")
or
1424 frag.startswith(
"EBA")
or
1425 frag.startswith(
"EBC")
or
1426 frag.startswith(
"ALL")
or
1427 frag.startswith(
"XXX") ):
1428 part_dict = {
'AUX':0,
'LBA':1,
'LBC':2,
'EBA':3,
'EBC':4,
'ALL':5,
'XXX':-1}
1429 partname = str(frag[0:3])
1430 ros=part_dict[partname]
1431 mod = int(frag[3:])-1
1433 raise Exception(
"Unknown fragment %s" % frag)
1449 if mod<0
or mod>=64:
1463 allchannels=(chn==-1)
1478 for ros
in range(rosmin,rosmax):
1479 for mod
in range(modmin,modmax):
1480 for chn
in range(chnmin,chnmax):
1481 if allchannels
or self.
channel2PMT(ros,mod,chn)>0:
1482 for adc
in range (adcmin,adcmax):
1483 dictKey = (ros,mod,chn,adc)
1493 def getData(self, ros, drawer, channel, adc, iov=(MAXRUN,MAXLBK)):
1494 dictKey = (int(ros), int(drawer), int(channel), int(adc))
1497 before= [i
for i
in sorted(data)
if i[0] <= iov ]
1499 data = before[-1][1]
1511 "Convert channel numbet to PMT number, negative for disconnected channels"
1512 "This takes ros [1-4], drawer [0-63], chan [0-47]"
1514 chan2PMT_LB=[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
1515 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1516 27, 26, 25, 30, 29, 28,-33,-32, 31, 36, 35, 34,
1517 39, 38, 37, 42, 41, 40, 45,-44, 43, 48, 47, 46 ]
1519 chan2PMT_EB=[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
1520 13, 14, 15, 16, 17, 18,-19,-20, 21, 22, 23, 24,
1521 -27,-26,-25,-31,-32,-28, 33, 29, 30,-36,-35, 34,
1522 44, 38, 37, 43, 42, 41,-45,-39,-40,-48,-47,-46 ]
1524 chan2PMT_Sp=[ -1, -2, -3, -4, 5, 6, 7, 8, 9, 10, 11, 12,
1525 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1526 -27,-26,-25,-31,-32,-28, 33, 29, 30,-36,-35, 34,
1527 44, 38, 37, 43, 42, 41,-45,-39,-40,-48,-47,-46 ]
1530 pmt = chan2PMT_LB[chan]
1531 elif (ros == 3
and drawer == 14)
or (ros == 4
and drawer == 17):
1532 pmt = chan2PMT_Sp[chan]
1534 pmt = chan2PMT_EB[chan]
1540 "Convert PMT number to channel numbet"
1541 "This takes partition (LBA,LBC,EBA,EBC) and pmt [1-48]"
1543 chan2PMT_LB=[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
1544 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1545 27, 26, 25, 30, 29, 28, 33, 32, 31, 36, 35, 34,
1546 39, 38, 37, 42, 41, 40, 45, 44, 43, 48, 47, 46 ]
1548 chan2PMT_EB=[ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
1549 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
1550 27, 26, 25, 31, 32, 28, 33, 29, 30, 36, 35, 34,
1551 44, 38, 37, 43, 42, 41, 45, 39, 40, 48, 47, 46 ]
1557 if str(partition)[0].
upper() ==
"E":
1558 chan = chan2PMT_EB.index(pm)
1560 chan = chan2PMT_LB.index(pm)
1573 This is a class capable of parsing TileCal conditions data stored in
1581 - fileName : input file name
1582 - calibId : like Trip, ...
1585 TileCalibLogger.__init__(self,
"TileASCIIParser3")
1588 lines = open(fileName,
"r").readlines()
1589 except Exception
as e:
1590 self.log().
error(
"TileCalibASCIIParser3::ERROR: Problem opening input file:" )
1591 self.log().
error( e )
1595 fields = line.strip().
split()
1597 if not len(fields) :
1599 if fields[0].startswith(
"#"):
1609 raise Exception(
"%s is not calibId=%s" % (type, calibId))
1612 if not (frag.startswith(
'0x')
or frag.startswith(
'-0x')):
1613 raise Exception(
"Misformated fragment %s" % frag)
1623 dictKey = (ros, mod)
1628 dictKey = (int(ros), int(drawer))
void print(char *figname, TCanvas *c1)
static const TileCalibDrawerBch * getInstance(const coral::Blob &blob)
Returns a pointer to a const TileCalibDrawerBch.
static const TileCalibDrawerCmt * getInstance(const coral::Blob &blob)
Returns a pointer to a const TileCalibDrawerCmt.
static const TileCalibDrawerFlt * getInstance(const coral::Blob &blob)
Returns a pointer to a const TileCalibDrawerFlt.
static const TileCalibDrawerInt * getInstance(const coral::Blob &blob)
Returns a pointer to a const TileCalibDrawerBch.
static TileCalibDrawerOfc * getInstance(coral::Blob &blob, uint16_t objVersion, uint32_t nSamples, int32_t nPhases, uint16_t nChans, uint16_t nGains, const std::string &author="", const std::string &comment="", uint64_t timeStamp=0)
Returns a pointer to a non-const TileCalibDrawerOfc.
static std::string getClassName(TileCalibType::TYPE type)
Returns the class name.
static unsigned int getDrawerIdx(unsigned int ros, unsigned int drawer)
Returns a drawer hash.
static std::string getFullTag(const std::string &folder, const std::string &tag)
Returns the full tag string, composed of camelized folder name and tag part.
static unsigned int getCommentChannel()
Returns the COOL channel number for the comment channel.
std::string description
glabal timer - how long have I taken so far?
std::string replace(std::string s, const std::string &s2, const std::string &s3)
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
void search(TDirectory *td, const std::string &s, std::string cwd, node *n)
recursive directory search for TH1 and TH2 and TProfiles
std::vector< std::string > split(const std::string &s, const std::string &t=":")
IovVectorMap_t read(const Folder &theFolder, const SelectionCriterion &choice, const unsigned int limit=10)