ATLAS Offline Software
Loading...
Searching...
No Matches
COOLUtils.py
Go to the documentation of this file.
1# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
2
3"""
4Miscellaneous utilities related to COOL.
5"""
6__author__ = 'Juerg Beringer'
7__version__ = 'COOLUtils.py atlas/athena'
8
9import os, time,sys
10
11from PyCool import cool
12from CoolConvUtilities import AtlCoolLib
13
14# For resolving tags
15#sys.path.append('/afs/cern.ch/user/a/atlcond/utils22/CondUtilsLib/')
16sys.path.append('/afs/cern.ch/user/a/atlcond/utils22/')
17
18
19#
20# Utility function to open a COOL SQLite beam spot file.
21#
22def openBeamSpotDbFile(fileName, forceNew=False, folderName='/Indet/Beampos', dbName='BEAMSPOT'):
23 """Open a beam spot SQLite COOL file and get a `folderHandle` to the beam spot folder. If the folder
24 doesn't exist yet, it is created. If the SQLite file doesn't exist, it is created. If forceNew=True,
25 any previously existing output file with the specified name is overwritten."""
26 connString = 'sqlite://;schema=%s;dbname=%s' % (fileName,dbName)
27 dbSvc = cool.DatabaseSvcFactory.databaseService()
28 if forceNew and os.path.exists(fileName):
29 os.remove(fileName)
30 if os.path.exists(fileName):
31 db = dbSvc.openDatabase(connString,False)
32 else:
33 db = dbSvc.createDatabase(connString)
34
35 # Make sure we have /Indet/Beampos with the correct schema
36 spec=cool.RecordSpecification()
37 spec.extend("status",cool.StorageType.Int32)
38 spec.extend("posX",cool.StorageType.Float)
39 spec.extend("posY",cool.StorageType.Float)
40 spec.extend("posZ",cool.StorageType.Float)
41 spec.extend("sigmaX",cool.StorageType.Float)
42 spec.extend("sigmaY",cool.StorageType.Float)
43 spec.extend("sigmaZ",cool.StorageType.Float)
44 spec.extend("tiltX",cool.StorageType.Float)
45 spec.extend("tiltY",cool.StorageType.Float)
46 spec.extend("sigmaXY",cool.StorageType.Float)
47 spec.extend("posXErr",cool.StorageType.Float)
48 spec.extend("posYErr",cool.StorageType.Float)
49 spec.extend("posZErr",cool.StorageType.Float)
50 spec.extend("sigmaXErr",cool.StorageType.Float)
51 spec.extend("sigmaYErr",cool.StorageType.Float)
52 spec.extend("sigmaZErr",cool.StorageType.Float)
53 spec.extend("tiltXErr",cool.StorageType.Float)
54 spec.extend("tiltYErr",cool.StorageType.Float)
55 spec.extend("sigmaXYErr",cool.StorageType.Float)
56
57 folder = AtlCoolLib.ensureFolder(db,folderName,spec,AtlCoolLib.athenaDesc(True,'AthenaAttributeList'),cool.FolderVersioning.MULTI_VERSION)
58
59 folderHandle = (db,folder,spec)
60 return folderHandle
61
62
63def writeBeamSpotEntry(folderHandle, tag='nominal',
64 runMin=0, runMax=(1 << 31)-1, lbMin=0, lbMax=(1 << 32)-2,
65 status=0,
66 posX=0., posY=0., posZ=0.,
67 sigmaX=30., sigmaY=30., sigmaZ=500.,
68 tiltX=0., tiltY=0.,
69 sigmaXY=0.,
70 posXErr=0., posYErr=0., posZErr=0.,
71 sigmaXErr=0., sigmaYErr=0., sigmaZErr=0.,
72 tiltXErr=0., tiltYErr=0.,
73 sigmaXYErr=0.):
74 """Write a beam spot entry for a given IOV into a beam spot folder whose 'folderHandle' is passsed.
75 The IOV is specified in terms of run and LB range. Note that lbMax is inclusive.
76 The default parameters for the position and tilt are zero, the ones for the widths are large
77 non-constraining widths of 30mm (500mm) transverse (longitudinal)."""
78 since = (runMin << 32)+lbMin
79 until = (runMax << 32)+lbMax+1
80 payload=cool.Record(folderHandle[2])
81 payload['status'] = int(status)
82 payload['posX'] = float(posX)
83 payload['posY'] = float(posY)
84 payload['posZ'] = float(posZ)
85 payload['sigmaX'] = float(sigmaX)
86 payload['sigmaY'] = float(sigmaY)
87 payload['sigmaZ'] = float(sigmaZ)
88 payload['tiltX'] = float(tiltX)
89 payload['tiltY'] = float(tiltY)
90 payload['sigmaXY'] = float(sigmaXY)
91 payload['posXErr'] = float(posXErr)
92 payload['posYErr'] = float(posYErr)
93 payload['posZErr'] = float(posZErr)
94 payload['sigmaXErr'] = float(sigmaXErr)
95 payload['sigmaYErr'] = float(sigmaYErr)
96 payload['sigmaZErr'] = float(sigmaZErr)
97 payload['tiltXErr'] = float(tiltXErr)
98 payload['tiltYErr'] = float(tiltYErr)
99 payload['sigmaXYErr'] = float(sigmaXYErr)
100
101 if tag=='HEAD':
102 folderHandle[1].storeObject(since,until,payload,0)
103 else:
104 folderHandle[1].storeObject(since,until,payload,0,tag)
105
106
107
108#
109# Utility function to convert from COOL time to Unix time (seconds since epoch)
110#
111def COOLToUnixTime(coolTime):
112 if coolTime is not None:
113 return int(coolTime/1000000000)
114 else:
115 return
116
117
118#
119# Class to convert query COOL for various quantities related to runs,
120# such as start and end times of runs and LBs, LHC fill number, etc.
121#
123 """Utility to query COOL to retrieve start and end time of run and LBs."""
124 def __init__(self,useOracle=False,debug=True):
125
126 self.tdaqdbname='COOLONL_TDAQ/CONDBR2'
127 self.coolpath='/TDAQ/RunCtrl'
128 self.coolScanPath='/TDAQ/OLC/LHC/SCANDATA'
129
130 self.trigdbname='COOLONL_TRIGGER/CONDBR2'
131 self.coollbpath='/TRIGGER/LUMI/LBLB'
132
133 self.dcsdbname = 'COOLOFL_DCS/CONDBR2'
134 self.coollhcpath = '/LHC/DCS/FILLSTATE'
135
136 self.debug = debug
137
138 print ('open cool db' )
139 self.cooldb = AtlCoolLib.indirectOpen(self.tdaqdbname, True, self.debug)
140 print ('open cooltrig db')
141 self.cooltrigdb = AtlCoolLib.indirectOpen(self.trigdbname, True, self.debug)
142 print ('open cooldcs db')
143 self.cooldcsdb = AtlCoolLib.indirectOpen(self.dcsdbname, True, self.debug)
144
145 self.lbDictCache = {'runnr': None, 'lbDict': None}
146 self.scanDictCache = {'runnr': None, 'scanDict': None}
147
148 def __del__(self):
149 try:
150 self.cooldb.closeDatabase()
151 self.cooltrigdb.closeDatabase()
152 self.cooldcsdb.closeDatabase()
153 except Exception:
154 print ("DB time out -- ignore")
155
156 def getRunStartTime(self,runnr):
157 """Get start time of run in Unix time (seconds since epoch)."""
158 iov=runnr << 32
159 if (iov>cool.ValidityKeyMax): iov=cool.ValidityKeyMax
160 folderSOR_Params = self.cooldb.getFolder(self.coolpath+'/SOR')
161 itr = folderSOR_Params.browseObjects(iov, iov, cool.ChannelSelection.all())
162 try:
163 itr.goToNext()
164 obj = itr.currentRef()
165 sorTime = obj.payload()['SORTime']
166 return COOLToUnixTime(sorTime)
167 except Exception:
168 return
169
170
171 def getLHCInfo(self,timeSinceEpochInSec):
172 """Get LHC fill and other info from COOL. The relevant COOL folder,
173 /LHC/DCS/FILLSTATE is time-based, so the iov must be specified in
174 ns since the epoch, but the argument to getLHCInfo is s since the
175 epoch for convenience."""
176 t = timeSinceEpochInSec*1000000000
177 lhcfolder = self.cooldcsdb.getFolder(self.coollhcpath)
178 itr = lhcfolder.browseObjects(t,t,cool.ChannelSelection.all())
179 try:
180 info = { 'FillNumber': 0,
181 'StableBeams': False,
182 'BeamEnergyGeV': 0,
183 'NumBunchColl': 0 ,
184 'BetaStar': 0}
185 itr.goToNext()
186 obj = itr.currentRef()
187 for k in info.keys():
188 try:
189 info[k] = obj.payload()[k]
190 except Exception:
191 print ('WARNING: Cannot find value for',k)
192 return info
193 except Exception:
194 return None
195
196 def getRunEndTime(self,runnr):
197 """Get end time of run in Unix time (seconds since epoch)."""
198 iov=runnr << 32
199 if (iov>cool.ValidityKeyMax): iov=cool.ValidityKeyMax
200 folderEOR_Params = self.cooldb.getFolder(self.coolpath+'/EOR')
201 itr = folderEOR_Params.browseObjects(iov, iov, cool.ChannelSelection.all())
202 try:
203 itr.goToNext()
204 obj = itr.currentRef()
205 eorTime = obj.payload()['EORTime']
206 return COOLToUnixTime(eorTime)
207 except Exception:
208 return
209
210 def getLbTimes(self,runnr):
211 """Get dict of LB start and end times in Unix time (seconds since epoch)."""
212 iov1=runnr << 32
213 iov2=(runnr+1) << 32
214 if (iov2>cool.ValidityKeyMax): iov2=cool.ValidityKeyMax
215 folderLB_Params = self.cooltrigdb.getFolder(self.coollbpath)
216 itr = folderLB_Params.browseObjects(iov1, iov2, cool.ChannelSelection.all())
217 lbDict = { }
218 while itr.goToNext():
219 obj = itr.currentRef()
220 since = obj.since()
221 run = since >> 32
222 lb = since & 0xFFFFFFFF
223 if (run != runnr): continue
224
225 tlo = obj.payload()['StartTime']
226 thi = obj.payload()['EndTime']
227 lbDict[lb] = (COOLToUnixTime(tlo),COOLToUnixTime(thi))
228 return lbDict
229
230 def lbTime(self,runnr,lbnr):
231 """Get (startTime,endTime) for a given LB. The LB information is cached
232 for the last run, in order make this efficient for querying for the
233 times of individual LBs."""
234 runnr = int(runnr)
235 if self.lbDictCache['runnr']!=runnr:
236 # print ('Caching lbDict for run',runnr)
237 self.lbDictCache['lbDict'] = self.getLbTimes(runnr)
238 self.lbDictCache['runnr'] = runnr
239 return self.lbDictCache['lbDict'].get(lbnr,None)
240
241 def getScanInfo(self,runnr):
242 """Get dict of scan info"""
243 iov1 = self.getRunStartTime(runnr)*1000000000
244 iov2 = self.getRunEndTime(runnr)*1000000000
245 if (iov2>cool.ValidityKeyMax): iov2=cool.ValidityKeyMax
246 folderScan_Params = self.cooldb.getFolder(self.coolScanPath)
247 itr = folderScan_Params.browseObjects(iov1, iov2, cool.ChannelSelection.all())
248 scanDict = { }
249 while itr.goToNext():
250 obj = itr.currentRef()
251 runLB = obj.payload()['RunLB']
252 run = runLB >> 32
253 if (run != runnr): continue
254 lb = runLB & 0xFFFFFFFF
255 channelId = obj.channelId()
256 scanningIP = obj.payload()['ScanningIP']
257 # Select only the channel corresponding to IP
258 mask = 1 << channelId
259 if(scanningIP & mask == 0): continue
260 acquisitionFlag = obj.payload()['AcquisitionFlag']
261 nominalSeparation = obj.payload()['NominalSeparation']
262 nominalSeparationPlane = obj.payload()['NominalSeparationPlane']
263 B1DeltaXSet = obj.payload()['B1DeltaXSet']
264 B2DeltaXSet = obj.payload()['B2DeltaXSet']
265 B1DeltaYSet = obj.payload()['B1DeltaYSet']
266 B2DeltaYSet = obj.payload()['B2DeltaYSet']
267 scanDict[lb] = (scanningIP,acquisitionFlag,nominalSeparation,nominalSeparationPlane,B1DeltaXSet,B2DeltaXSet,B1DeltaYSet,B2DeltaYSet)
268 return scanDict
269
270 def scanInfo(self,runnr,lbnr):
271 """Get scan information for a given LB. The LB information is cached
272 for the last run, in order make this efficient for querying for the
273 times of individual LBs."""
274 runnr = int(runnr)
275 if self.scanDictCache['runnr']!=runnr:
276 self.scanDictCache['scanDict'] = self.getScanInfo(runnr)
277 self.scanDictCache['runnr'] = runnr
278 return self.scanDictCache['scanDict'].get(lbnr,None)
279
280def resolveCurrentAlias(tagtype='ST'):
281 "Resolve the current BLK tag alias"
282
283 from CondUtilsLib.AtlCoolBKLib import resolveAlias
284
285 # Will raise exception if alias not defined
286 alias = resolveAlias.getCurrent()
287 return alias.replace('*', tagtype)
288
289def resolveNextAlias(tagtype='ST'):
290 "Resolve the next BLK tag alias"
291
292 from CondUtilsLib.AtlCoolBKLib import resolveAlias
293
294 # Returns an empty string if Next not existing or exception thrown
295
296 alias = ''
297 try:
298 alias = resolveAlias.getNext()
299 except Exception:
300 alias = ''
301
302 return alias.replace('*', tagtype)
303
304
305def resolveCurrentBeamSpotFolder(db = 'COOLOFL_INDET/CONDBR2', folder = '/Indet/Beampos'):
306 """
307 Resolve the beamspot folder tag for the current BLK tag alisa
308 """
309 tag = resolveCurrentAlias()
310 return resolveBLKTag(tag)
311
312def resolveNextBeamSpotFolder(db = 'COOLOFL_INDET/CONDBR2', folder = '/Indet/Beampos'):
313 """
314 Resolve the beamspot folder tag for the next BLK tag alias
315 """
316
317 tag = resolveNextAlias()
318 if tag == '': return ''
319
320 return resolveBLKTag(tag)
321
322def resolveBLKTag(blktag, db = 'COOLOFL_INDET/CONDBR2', folder = '/Indet/Beampos'):
323 """
324 Resolve a global tag into the corresponding tag for given folder in the database specified
325 """
326
327 dbSvc = cool.DatabaseSvcFactory.databaseService()
328 dbconn = dbSvc.openDatabase(db)
329 folder = dbconn.getFolder(folder)
330 try:
331 tag = folder.resolveTag(blktag)
332 finally:
333 del dbconn
334
335 return tag
336
337# Test code for modules
338if __name__ == '__main__':
340 print (time.strftime('%c', time.gmtime(c.getRunStartTime(142191)))) # in UTC
341 print (time.strftime('%c', time.gmtime(c.getRunStartTime(142193)))) # in UTC
342 print (time.strftime('%c', time.gmtime(c.getRunEndTime(142193))))
343 lbDict = c.getLbTimes(142193)
344 for l in lbDict.keys():
345 print (l,time.ctime(lbDict[l][0]),'-',time.ctime(lbDict[l][1])) # in local time zone
346
if(febId1==febId2)
getRunStartTime(self, runnr)
Definition COOLUtils.py:156
lbTime(self, runnr, lbnr)
Definition COOLUtils.py:230
scanInfo(self, runnr, lbnr)
Definition COOLUtils.py:270
getLHCInfo(self, timeSinceEpochInSec)
Definition COOLUtils.py:171
__init__(self, useOracle=False, debug=True)
Definition COOLUtils.py:124
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:130
resolveBLKTag(blktag, db='COOLOFL_INDET/CONDBR2', folder='/Indet/Beampos')
Definition COOLUtils.py:322
openBeamSpotDbFile(fileName, forceNew=False, folderName='/Indet/Beampos', dbName='BEAMSPOT')
Definition COOLUtils.py:22
COOLToUnixTime(coolTime)
Definition COOLUtils.py:111
resolveCurrentAlias(tagtype='ST')
Definition COOLUtils.py:280
writeBeamSpotEntry(folderHandle, tag='nominal', runMin=0, runMax=(1<< 31) -1, lbMin=0, lbMax=(1<< 32) -2, status=0, posX=0., posY=0., posZ=0., sigmaX=30., sigmaY=30., sigmaZ=500., tiltX=0., tiltY=0., sigmaXY=0., posXErr=0., posYErr=0., posZErr=0., sigmaXErr=0., sigmaYErr=0., sigmaZErr=0., tiltXErr=0., tiltYErr=0., sigmaXYErr=0.)
Definition COOLUtils.py:73
resolveNextAlias(tagtype='ST')
Definition COOLUtils.py:289
resolveCurrentBeamSpotFolder(db='COOLOFL_INDET/CONDBR2', folder='/Indet/Beampos')
Definition COOLUtils.py:305
resolveNextBeamSpotFolder(db='COOLOFL_INDET/CONDBR2', folder='/Indet/Beampos')
Definition COOLUtils.py:312