ATLAS Offline Software
Loading...
Searching...
No Matches
CondDB.py
Go to the documentation of this file.
1# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2
3# CondDB.py
4# Configuration for Athena conditions DB access
5# usage:
6# from IOVDbSvc.CondDB import conddb
7# then add folders with
8# conddb.addFolder('INDET','/Indet/Align')
9# conddb.addFolder('INDET,'/Indet/Align <tag>my_explicit_tag</tag>') or
10# conddb.addFolderWithTag('INDET','/Indet/Align','my_explicit_tag')
11# conddb.addFolderSplitOnline('INDET','/Indet/OnlineF','/Indet/OfflineF')
12# conddb.addFolderSplitMC('INDET','/Indet/DataFolder','/Indet/MCFolder')
13# override a tag with
14# conddb.addOverride('/Indet/Align','override_tag_value')
15# block a folder from being added later
16# conddb.blockFolder('/Indet/Align')
17# add a folder even though blocked
18# conddb.addFolder('INDET','/Indet/Align',True)
19# conddb.addFolderWithTag('INDET','/Indet/Align','my_explicit_tag',True)
20# add markup (additional XML) to existing folder specifications
21# conddb.addMarkup('/Indet/Align','<channelSelection>1:3</channelSelection>')
22#
23# If the className argument is provided to addFolder, then also register
24# with CondInputLoader.
25
26import os
27
28from AthenaCommon.AppMgr import ServiceMgr as svcMgr
29from IOVSvc.IOVSvcConf import CondSvc
30from IOVSvc.IOVSvcConf import CondInputLoader
31from AthenaServices.AthenaServicesConf import Athena__ConditionsCleanerSvc
32from AthenaServices.AthenaServicesConf import Athena__DelayedConditionsCleanerSvc
33from AthenaCommon.AlgSequence import AthSequencer
34from AthenaCommon.ConcurrencyFlags import jobproperties as jp
35
36
37svcMgr += CondSvc()
38
39condSeq = AthSequencer("AthCondSeq")
40if not hasattr(condSeq, "CondInputLoader"):
41 condInputLoader = CondInputLoader( "CondInputLoader")
42 # We always want CondInputLoader to be first in the condSeq
43 # for serial running
44 condSeq.insert(0, condInputLoader)
45else:
46 condInputLoader = condSeq.CondInputLoader
47
48# Enable conditions garbage collection.
49nConcurrentEvents = max(1,jp.ConcurrencyFlags.NumConcurrentEvents())
50cleaner = Athena__DelayedConditionsCleanerSvc(RingSize = 2*nConcurrentEvents)
51svcMgr += cleaner
52svcMgr += Athena__ConditionsCleanerSvc (CleanerSvc = cleaner)
53
54class CondDB:
55 "Class to hold configuration information for Athena conditions DB access"
56 def __init__(self,doOldStyleConfig=False):
57 "Setup conditions DB - IOVDbSvc and connections according to GlobalFlags"
58 from AthenaCommon.AppMgr import ServiceMgr as svcMgr
59 from AthenaCommon.Logging import logging
60 self.msg = logging.getLogger( 'IOVDbSvc.CondDB' )
61 self.msg.debug("Loading basic services for CondDBSetup...")
62
63 # AthenaPool and IOVDbSvc configuration
64 from AthenaPoolCnvSvc import AthenaPool # noqa: F401
65 from IOVDbSvc import IOVDb # noqa: F401
66 # local access to IOVDbSvc parameters
67 self.iovdbsvc=svcMgr.IOVDbSvc
68
69 # initialise list of allowed DBs
70 self.dblist={}
71 # and list of blocked folders
72 self.blocklist=[]
73
74 # decide which instance to setup
75 # default database
76 self.dbname=''
77 # names for MC and data database in case forceMC/forceData are used
78 self.dbmc=''
79 self.dbdata=''
80 self.poolcats=[]
81 from AthenaCommon.GlobalFlags import globalflags
82 from AthenaCommon.AthenaCommonFlags import athenaCommonFlags
83 self.isOnline=athenaCommonFlags.isOnline()
84 self.isMC=not globalflags.DataSource()=='data'
85 if (globalflags.DetGeo() in ['atlas','commis']):
86 # ATLAS full or commissioning geometry
87 self.dbmc='OFLP200'
88 self.dbdata=globalflags.DatabaseInstance() #could be 'auto'
89 if self.isMC:
90 # Monte Carlo
91 self.dbname=self.dbmc
92 self.poolcats=['oflcond']
93 else:
94 # real data
95 if (self.dbdata=='auto'):
96 project_name = ''
97 if athenaCommonFlags.FilesInput():
98 from PyUtils.MetaReader import read_metadata
99 metadata = read_metadata(athenaCommonFlags.FilesInput())
100 project_name = metadata[athenaCommonFlags.FilesInput()[0]]['project_name']
101
102 self.dbdata=self._InstanceFromProjectName(project_name)
103 self.msg.info("Configuring database instance '%s' based on project tag '%s'", self.dbdata, project_name)
104 self.dbname=self.dbdata
105 self.poolcats=['comcond','oflcond']
106 elif (globalflags.DetGeo() in ['ctbh8','ctbh6']):
107 self.dbmc='TMCP200'
108 self.dbdata='TBDP200'
109 if self.isMC:
110 # 2004 combined testbeam, Monte Carlo
111 self.dbname=self.dbmc
112 self.poolcats=['tbcond','oflcond']
113 else:
114 # 2004 combined testbeam, real data
115 self.dbname=self.dbdata
116 self.poolcats=['tbcond','oflcond']
117 else:
118 raise RuntimeError("Unknown globalflags.DetGeo: %s" % globalflags.DetGeo())
119 if (self.dbname!=''):
120 self.msg.info('Setting up conditions DB access to instance %s', self.dbname)
121 # set up all access options - online schemas
122 self._SetAcc('INDET','COOLONL_INDET')
123 self._SetAcc('INDET_ONL','COOLONL_INDET')
124 self._SetAcc('PIXEL','COOLONL_PIXEL')
125 self._SetAcc('PIXEL_ONL','COOLONL_PIXEL')
126 self._SetAcc('SCT','COOLONL_SCT')
127 self._SetAcc('SCT_ONL','COOLONL_SCT')
128 self._SetAcc('TRT','COOLONL_TRT')
129 self._SetAcc('TRT_ONL','COOLONL_TRT')
130 self._SetAcc('LAR','COOLONL_LAR')
131 self._SetAcc('LAR_ONL','COOLONL_LAR')
132 self._SetAcc('TILE','COOLONL_TILE')
133 self._SetAcc('TILE_ONL','COOLONL_TILE')
134 self._SetAcc('MUON','COOLONL_MUON')
135 self._SetAcc('MUON_ONL','COOLONL_MUON')
136 self._SetAcc('MUONALIGN','COOLONL_MUONALIGN')
137 self._SetAcc('MUONALIGN_ONL','COOLONL_MUONALIGN')
138 self._SetAcc('MDT','COOLONL_MDT')
139 self._SetAcc('MDT_ONL','COOLONL_MDT')
140 self._SetAcc('RPC','COOLONL_RPC')
141 self._SetAcc('RPC_ONL','COOLONL_RPC')
142 self._SetAcc('TGC','COOLONL_TGC')
143 self._SetAcc('TGC_ONL','COOLONL_TGC')
144 self._SetAcc('CSC','COOLONL_CSC')
145 self._SetAcc('CSC_ONL','COOLONL_CSC')
146 self._SetAcc('TDAQ','COOLONL_TDAQ')
147 self._SetAcc('TDAQ_ONL','COOLONL_TDAQ')
148 self._SetAcc('GLOBAL','COOLONL_GLOBAL')
149 self._SetAcc('GLOBAL_ONL','COOLONL_GLOBAL')
150 self._SetAcc('TRIGGER','COOLONL_TRIGGER')
151 self._SetAcc('TRIGGER_ONL','COOLONL_TRIGGER')
152 self._SetAcc('CALO','COOLONL_CALO')
153 self._SetAcc('CALO_ONL','COOLONL_CALO')
154 self._SetAcc('FWD','COOLONL_FWD')
155 self._SetAcc('FWD_ONL','COOLONL_FWD')
156 # set up all access options - offline schemas
157 # only do this if isOnline flag is NOT set
158 # or MC flag is set, to allow HLT testing using MC database
159 if (self.isMC or not self.isOnline):
160 self._SetAcc('INDET_OFL','COOLOFL_INDET')
161 self._SetAcc('PIXEL_OFL','COOLOFL_PIXEL')
162 self._SetAcc('SCT_OFL','COOLOFL_SCT')
163 self._SetAcc('TRT_OFL','COOLOFL_TRT')
164 self._SetAcc('LAR_OFL','COOLOFL_LAR')
165 self._SetAcc('TILE_OFL','COOLOFL_TILE')
166 self._SetAcc('MUON_OFL','COOLOFL_MUON')
167 self._SetAcc('MUONALIGN_OFL','COOLOFL_MUONALIGN')
168 self._SetAcc('MDT_OFL','COOLOFL_MDT')
169 self._SetAcc('RPC_OFL','COOLOFL_RPC')
170 self._SetAcc('TGC_OFL','COOLOFL_TGC')
171 self._SetAcc('CSC_OFL','COOLOFL_CSC')
172 self._SetAcc('TDAQ_OFL','COOLOFL_TDAQ')
173 self._SetAcc('DCS_OFL','COOLOFL_DCS')
174 self._SetAcc('GLOBAL_OFL','COOLOFL_GLOBAL')
175 self._SetAcc('TRIGGER_OFL','COOLOFL_TRIGGER')
176 self._SetAcc('CALO_OFL','COOLOFL_CALO')
177 self._SetAcc('FWD_OFL','COOLOFL_FWD')
178 else:
179 self.msg.info('Running in online mode - no access to COOLOFL schemas')
180 self.iovdbsvc.OnlineMode=True
181
182 # setup default connection to localfile, and put in LOCAL symbol
183 localfile="sqlite://;schema=mycool.db;dbname="
184 self.dblist['LOCAL']=localfile
185 self.iovdbsvc.dbConnection=localfile+self.dbname
186
187 # setup knowledge of dbinstance in IOVDbSvc, for global tag x-check
188 self.iovdbsvc.DBInstance=self.dbname
189
190
191 # setup DBReplicaSvc to veto DBRelease SQLite files if real data
192 if not self.isMC:
193 from DBReplicaSvc.DBReplicaSvcConf import DBReplicaSvc
194 svcMgr+=DBReplicaSvc(COOLSQLiteVetoPattern="/DBRelease/")
195
196 # enable Frontier cache alignment if it looks like Frontier will
197 # be used (via FRONTIER_SERVER variable)
198 # but not for HLT (ATR-4646)
199 if 'FRONTIER_SERVER' in os.environ.keys() and os.environ['FRONTIER_SERVER']!="" and not self.isOnline:
200 self.iovdbsvc.CacheAlign=3
201
202 # setup PoolSvc catalogues
203 from PoolSvc.PoolSvcConf import PoolSvc
204 if not hasattr (svcMgr, 'PoolSvc'):
205 svcMgr+=PoolSvc()
206 # add the standard catalogues
207 # Set entries which will be resolved using ATLAS_POOLCOND_PATH
208 # (if set) - the actual resolution is done inside PoolSvc C++
209 for i in self.poolcats:
210 svcMgr.PoolSvc.ReadCatalog+=["apcfile:poolcond/PoolCat_%s.xml" % i]
211 svcMgr.PoolSvc.ReadCatalog+=["apcfile:poolcond/PoolFileCatalog.xml"]
212 else:
213 raise RuntimeError('Not enough configuration information to setup ConditionsDB access (are GlobalFlags being used?)')
214 self.msg.debug("Loading basic services for CondDBSetup... [DONE]")
215
216 def addFolder(self,ident,folder,force=False,forceMC=False,forceData=False,
217 className=None,extensible=False):
218 """Add access to the given folder, in the identified subdetector schema.
219If EXTENSIBLE is set, then if we access an open-ended IOV at the end of the list,
220the end time for this range will be set to just past the current event.
221Subsequent accesses will update this end time for subsequent events.
222This allows the possibility of later adding a new IOV using IOVSvc::setRange."""
223 # first check if access to this folder was blocked, unless forcing
224 for block in self.blocklist:
225 if (folder.find(block)>=0 and not force): return
226 folderadd=''
227 # now check if ident is defined, and add folder
228 if (ident in self.dblist.keys()):
229 folderadd="<db>%s%s</db> %s" % (self.dblist[ident],self._GetName(forceMC,forceData),folder)
230 elif (ident==''):
231 folderadd=folder
232 elif (ident.find('.')>0):
233 # interpret the identifier as a filename for SQLite file
234 folderadd='<db>sqlite://;schema=%s;dbname=%s</db> %s' % (ident,self._GetName(forceMC,forceData),folder)
235 else:
236 raise RuntimeError("Conditions database identifier %s is not defined" % ident)
237 if extensible:
238 folderadd = folderadd + '<extensible/>'
239
240 self.iovdbsvc.Folders+=[folderadd]
241
242 if className:
243 key = (className, self.extractFolder(folder))
244 if key not in condInputLoader.Load:
245 condInputLoader.Load.add(key)
246
247 def addFolderWithTag(self,ident,folder,tag,force=False,forceMC=False,forceData=False,className=None):
248 "Add access to the given folder/schema, using a specified tag"
249 self.addFolder(ident,folder+" <tag>%s</tag>" % tag,force,forceMC,forceData,className=className)
250
251 def addFolderSplitOnline(self,ident,folder1,folder2,force=False,forceMC=False,forceData=False,
252 className=None,extensible=False):
253 "Add access to given folder, using folder1 online, folder2 offline"
254 if self.isOnline and not self.isMC:
255 self.addFolder(ident,folder1,force=force,forceMC=forceMC,forceData=forceData,
256 className=className,extensible=extensible)
257 return folder1
258 else:
259 self.addFolder(ident+'_OFL',folder2,force=force,forceMC=forceMC,forceData=forceData,
260 className=className,extensible=extensible)
261 return folder2
262
263 def addFolderSplitMC(self,ident,folder1,folder2,force=False,forceMC=False,forceData=False,className=None):
264 "Add access to given folder, using folder1 (online) for real data, folde2 (offline) for MC"
265 if self.isMC:
266 self.addFolder(ident+'_OFL',folder2,force=force,forceMC=forceMC,forceData=forceData,className=className)
267 else:
268 self.addFolder(ident,folder1,force=force,forceMC=forceMC,forceData=forceData,className=className)
269
270 def addOverride(self,folder,tag):
271 "Add a tag override for the specified folder"
272 overrideDirective = '<prefix>%s</prefix> <tag>%s</tag>' % (folder,tag)
273 if overrideDirective not in self.iovdbsvc.overrideTags:
274 self.iovdbsvc.overrideTags+=[overrideDirective]
275
276 def blockFolder(self,folder):
277 "Block use of specified conditions DB folder so data can be read from elsewhere"
278 self.blocklist+=[folder]
279 # check existing list of folders and remove it if found
280 for i in range(0,len(self.iovdbsvc.Folders)):
281 if (self.iovdbsvc.Folders[i].find(folder)>=0):
282 del self.iovdbsvc.Folders[i]
283 break
284
285 folderName = self.extractFolder(folder)
286 for f in condInputLoader.Load:
287 if (f[-1] == folderName):
288 condInputLoader.Load.remove(f) # OK since we break after this
289 break
290
291 def folderRequested(self,folder):
292 "Return true if the given folder has already been requested"
293 for i in self.iovdbsvc.Folders:
294 if (i.find(folder)>=0): return True
295 return False
296
297 def addMarkup(self,folder,markup):
298 "Add given XML markup to folder string for given folder"
299 nmod=0
300 for i in range(0,len(self.iovdbsvc.Folders)):
301 if (self.iovdbsvc.Folders[i].find(folder)>=0):
302 self.iovdbsvc.Folders[i]+=markup
303 nmod+=1
304 if (nmod==0):
305 raise RuntimeError("conddb.addMarkup: Folder %s is not known to IOVDbSvc" % folder)
306
307
308 def setGlobalTag(self,tag):
309 "Set the GlobalTag value used as the key for hierarhical conditions"
310 self.iovdbsvc.GlobalTag=tag
311
312
313 def setRequireLock(self,lock=True):
314 "Set the flag indicating global tags will be required to be locked"
315 self.iovdbsvc.CheckLock=lock
316
317 def setWriteDataToFile(self, writeData=False):
318 "Set option to write data to file"
319 self.iovdbsvc.OutputToFile=writeData
320
321 def setCrestCoolToFile(self, crestCoolData=False):
322 "Set option to write CREST or COOL data in the same format"
323 self.iovdbsvc.CrestCoolToFile=crestCoolData
324
325 def extractFolder(self,folderstr):
326 "Extract the folder name (non-XML text) from a IOVDbSvc.Folders entry"
327 fname=""
328 xmltag=""
329 ix=0
330 while ix<len(folderstr):
331 if (folderstr[ix]=='<' and xmltag==""):
332 ix2=folderstr.find('>',ix)
333 if (ix2!=-1):
334 xmltag=(folderstr[ix+1:ix2]).strip()
335 ix=ix2+1
336 if xmltag[-1] == '/':
337 xmltag=""
338 ix=ix+1
339 elif (folderstr[ix:ix+2]=='</' and xmltag!=""):
340 ix2=folderstr.find('>',ix)
341 if (ix2!=-1):
342 xmltag=""
343 ix=ix2+1
344 else:
345 ix2=folderstr.find('<',ix)
346 if ix2==-1: ix2=len(folderstr)
347 if (xmltag==""): fname=fname+folderstr[ix:ix2]
348 ix=ix2
349 return fname.strip()
350
351
352 def dumpFolderTags(self,outfile,folderNames=False,folderOrigin=False):
353 "Write out folder-specific tag names to file, for use with AtlCoolCopy tools"
354 ofile=open(outfile,'w')
355 for folderstr in self.iovdbsvc.Folders:
356 # extract tag specifications and write in file
357 if (folderNames):
358 # also extract the name of the folder - all non-XML text
359 fname=self.extractFolder(folderstr)
360 if (fname!=""):
361 dbtype=""
362 # find the database schema and insert :ONL or :OFL
363 if (folderOrigin):
364 if '<db>' in folderstr:
365 idx1=folderstr.find('<db>')+4
366 idx2=folderstr.find('</db>')
367 if (idx2>0):
368 dbname=folderstr[idx1:idx2].strip()
369 if 'ONL' in dbname:
370 dbtype=':ONL'
371 elif 'OFL' in dbname:
372 dbtype=':OFL'
373 ofile.write('--folder %s%s\n' % (fname,dbtype))
374 if '<tag>' in folderstr:
375 idx1=folderstr.find('<tag>')+5
376 idx2=folderstr.find('</tag>')
377 if (idx2>0):
378 tag=folderstr[idx1:idx2].strip()
379 # do not write out TagInfo magic tags, except when giving
380 # folderOrigin
381 if ((tag.find('TagInfo')!=0 and tag!='HEAD') or folderOrigin):
382 ofile.write('--tag %s\n' % tag)
383 # also extract any special tag names from overrideTags list
384 for folderstr in self.iovdbsvc.overrideTags:
385 # extract tag specifications and write in file
386 if '<tag>' in folderstr:
387 idx1=folderstr.find('<tag>')+5
388 idx2=folderstr.find('</tag>')
389 if (idx2>0):
390 tag=folderstr[idx1:idx2].strip()
391 # do not write out TagInfo magic tags
392 if (tag.find('TagInfo')!=0 and tag!='HEAD'):
393 ofile.write('--tag %s\n' % tag)
394 ofile.close()
395
396 def dumpFolderReadReal(self,outfile):
397 "Dump configuration information for use in ReadReal in AthenaDBTestRec"
398 ofile=open(outfile,'w')
399 ofile.write('FolderList=%s\n' % self.iovdbsvc.Folders.__repr__())
400 ofile.close()
401
402 def GetInstance(self,forceMC=False,forceData=False):
403 "Get the name of the DB instance in use (e.g. OFLP200)"
404 return self._GetName(forceMC,forceData)
405
406
407 def _SetAcc(self,ident,schema):
408 "Internal helper function to setup database access string"
409 self.dblist[ident]="%s/" % schema
410
411 def _GetName(self,forceMC,forceData):
412 "Internal get db instance name, taking into account forceData/MC flags"
413 if forceMC:
414 return self.dbmc
415 elif forceData:
416 return self.dbdata
417 else:
418 return self.dbname
419
420 #decide database instance based on project tag dataXX_
421 def _InstanceFromProjectName(self,projectName):
422 try:
423 year=int(projectName[4:6])
424 except Exception:
425 self.msg.warning(f"Failed to extract year from project tag '{projectName}', using CONDBR2.")
426 return "CONDBR2"
427
428 if (year>13):
429 return "CONDBR2"
430 else:
431 return "COMP200"
432
433
434# make instance for use
435# false indicates no backward compatibility objects
436conddb=CondDB(False)
const bool debug
#define max(a, b)
Definition cfImp.cxx:41
ClassName: AthSequencer.
This class provides the interface to the LCG POOL persistency software.
Definition PoolSvc.h:36
GetInstance(self, forceMC=False, forceData=False)
Definition CondDB.py:402
dumpFolderTags(self, outfile, folderNames=False, folderOrigin=False)
Definition CondDB.py:352
setWriteDataToFile(self, writeData=False)
Definition CondDB.py:317
_GetName(self, forceMC, forceData)
Definition CondDB.py:411
addFolderSplitOnline(self, ident, folder1, folder2, force=False, forceMC=False, forceData=False, className=None, extensible=False)
Definition CondDB.py:252
folderRequested(self, folder)
Definition CondDB.py:291
__init__(self, doOldStyleConfig=False)
Definition CondDB.py:56
setCrestCoolToFile(self, crestCoolData=False)
Definition CondDB.py:321
addFolderWithTag(self, ident, folder, tag, force=False, forceMC=False, forceData=False, className=None)
Definition CondDB.py:247
setRequireLock(self, lock=True)
Definition CondDB.py:313
_SetAcc(self, ident, schema)
Definition CondDB.py:407
addMarkup(self, folder, markup)
Definition CondDB.py:297
blockFolder(self, folder)
Definition CondDB.py:276
addFolderSplitMC(self, ident, folder1, folder2, force=False, forceMC=False, forceData=False, className=None)
Definition CondDB.py:263
setGlobalTag(self, tag)
Definition CondDB.py:308
addOverride(self, folder, tag)
Definition CondDB.py:270
addFolder(self, ident, folder, force=False, forceMC=False, forceData=False, className=None, extensible=False)
Definition CondDB.py:217
dumpFolderReadReal(self, outfile)
Definition CondDB.py:396
_InstanceFromProjectName(self, projectName)
Definition CondDB.py:421
extractFolder(self, folderstr)
Definition CondDB.py:325
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:138