ATLAS Offline Software
Loading...
Searching...
No Matches
IOVDbSvcConfig.py
Go to the documentation of this file.
1# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2
3from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator, ConfigurationError
4import os
5from AthenaConfiguration.ComponentFactory import CompFactory
6from AthenaConfiguration.AccumulatorCache import AccumulatorCache
7from AthenaCommon.Logging import logging
8from functools import cache
9
10msg = logging.getLogger('IOVDbSvcCfg')
11
12def CondInputLoaderCfg(flags, **kwargs):
13 result = ComponentAccumulator()
14 result.addCondAlgo(CompFactory.CondInputLoader(**kwargs))
15 return result
16
17
18def DBReplicaSvcCfg(flags, vetoDBRelease=False, **kwargs):
19 if vetoDBRelease:
20 kwargs.setdefault('COOLSQLiteVetoPattern', '/DBRelease/')
21
22 result = ComponentAccumulator()
23 result.addService(CompFactory.DBReplicaSvc(**kwargs))
24 return result
25
26
27@AccumulatorCache
28def IOVDbSvcCfg(flags, **kwargs):
29 # Add the conditions loader, must be the first in the sequence
30 result = CondInputLoaderCfg(flags)
31
32 kwargs.setdefault('OnlineMode', flags.Common.isOnline)
33 kwargs.setdefault('dbConnection', flags.IOVDb.DBConnection)
34 kwargs.setdefault('crestServer', flags.IOVDb.CrestServer)
35 # setup knowledge of dbinstance in IOVDbSvc, for global tag x-check
36 kwargs.setdefault('DBInstance', flags.IOVDb.DatabaseInstance)
37
38 if 'FRONTIER_SERVER' in os.environ.keys() and os.environ['FRONTIER_SERVER'] != '':
39 kwargs.setdefault('CacheAlign', 3)
40
41 # Very important cache settings for use of CoralProxy at P1 (ATR-4646)
42 if flags.Common.isOnline and flags.Trigger.Online.isPartition:
43 kwargs['CacheAlign'] = 0
44 kwargs['CacheRun'] = 0
45 kwargs['CacheTime'] = 0
46
47 kwargs.setdefault('GlobalTag', flags.IOVDb.GlobalTag)
48 if 'Folders' in kwargs:
49 kwargs['Folders'] = ['/TagInfo<metaOnly/>'] + kwargs['Folders']
50 else:
51 kwargs.setdefault('Folders', ['/TagInfo<metaOnly/>'])
52
53 # Select CREST backend if needed
54 if flags.IOVDb.UseCREST:
55 kwargs.setdefault('Source', 'CREST')
56
57 result.addService(CompFactory.IOVDbSvc(**kwargs), primary=True)
58
59 # Set up POOLSvc with appropriate catalogs
60 from AthenaPoolCnvSvc.PoolCommonConfig import PoolSvcCfg
61 result.merge(PoolSvcCfg(flags, withCatalogs=True))
62 if flags.MP.UseSharedReader or flags.MP.UseSharedWriter:
63 from AthenaPoolCnvSvc.PoolCommonConfig import AthenaPoolSharedIOCnvSvcCfg
64 result.merge(AthenaPoolSharedIOCnvSvcCfg(flags))
65 else:
66 from AthenaPoolCnvSvc.PoolCommonConfig import AthenaPoolCnvSvcCfg
67 result.merge(AthenaPoolCnvSvcCfg(flags))
68 result.addService(CompFactory.CondSvc())
69 result.addService(CompFactory.ProxyProviderSvc(ProviderNames=['IOVDbSvc']))
70
71 if not flags.Input.isMC:
72 result.merge(DBReplicaSvcCfg(flags, vetoDBRelease=True))
73
74 # Get TagInfoMgr
75 from EventInfoMgt.TagInfoMgrConfig import TagInfoMgrCfg
76 result.merge(TagInfoMgrCfg(flags))
77
78 # Set up MetaDataSvc
79 from AthenaServices.MetaDataSvcConfig import MetaDataSvcCfg
80 result.merge(MetaDataSvcCfg(flags, ['IOVDbMetaDataTool']))
81
82 return result
83
84
85# Convenience method to add folders:
86def addFolders(flags, folderStrings, detDb=None, className=None, extensible=False, tag=None, db=None, modifiers=''):
87 tagString = ''
88 if tag is not None:
89 if flags.IOVDb.UseCREST:
90 tagString = '<ctag>%s</ctag>' % tag
91 else: #COOL variant
92 tagString = '<tag>%s</tag>' % tag
93
94 # Convenience hack: Allow a single string as parameter:
95 if isinstance(folderStrings, str):
96 return addFolderList(flags, ((folderStrings + tagString, detDb, className),), extensible, db, modifiers)
97
98 else: # Got a list of folders
99 folderDefinitions = []
100
101 for folderString in folderStrings:
102 folderDefinitions.append((folderString + tagString, detDb, className))
103
104 return addFolderList(flags, folderDefinitions, extensible, db, modifiers)
105
106
107def addFolderList(flags, listOfFolderInfoTuple, extensible=False, db=None, modifiers=''):
108 """Add access to the given set of folders, in the identified subdetector schema.
109 FolerInfoTuple consists of (foldername,detDB,classname)
110
111 If EXTENSIBLE is set, then if we access an open-ended IOV at the end of the list,
112 the end time for this range will be set to just past the current event.
113 Subsequent accesses will update this end time for subsequent events.
114 This allows the possibility of later adding a new IOV using IOVSvc::setRange."""
115 loadFolders = set()
116 folders = []
117 sqliteFolders=getSqliteContent(flags.IOVDb.SqliteInput,
118 flags.IOVDb.SqliteFolders,
119 flags.IOVDb.DatabaseInstance)
120
121 for (fs, detDb, className) in listOfFolderInfoTuple:
122 fse= _extractFolder(fs)
123 # Add class-name to CondInputLoader (if reqired)
124 if className is not None:
125 loadFolders.add((className, fse))
126
127 if fse in sqliteFolders:
128 msg.warning(f'Reading folder {fs} from sqlite, bypassing production database')
129 fs+=sqliteFolders[fse]
130 elif detDb is not None and fs.find('<db>') == -1:
131
132 if db: # override database name if provided
133 dbName=db
134 else:
135 dbName = flags.IOVDb.DatabaseInstance
136 if detDb in _dblist.keys():
137 fs = f'<db>{_dblist[detDb]}/{dbName}</db> {fs}'
138 elif os.access(detDb, os.R_OK):
139 # Assume slqite file
140 fs = f'<db>sqlite://;schema={detDb};dbname={dbName}</db> {fs}'
141 elif detDb.startswith("crest_fs:"):
142 fs = f'<db>{detDb}</db> {fs}'
143 else:
144 raise ConfigurationError(f'Error, db shorthand {detDb} not known, nor found as sqlite file')
145 # Append database string to folder-name
146
147 if extensible:
148 fs = fs + '<extensible/>'
149
150 # Add explicitly given xml-modifiers (like channel-selection)
151 fs += modifiers
152
153 # Append (modified) folder-name string to IOVDbSvc Folders property
154 folders.append(fs)
155
156
157 result = IOVDbSvcCfg(flags)
158 result.getPrimary().Folders+=folders
159 if loadFolders:
160 result.getCondAlgo('CondInputLoader').Load |= loadFolders
161
162 if flags.IOVDb.CleanerRingSize > 0:
163 #HLT-jobs set IOVDb.CleanerRingSize to 0 to run without the cleaning-service,
164 cleanerSvc = CompFactory.Athena.DelayedConditionsCleanerSvc(RingSize=flags.IOVDb.CleanerRingSize)
165 result.addService(cleanerSvc)
166 result.addService(CompFactory.Athena.ConditionsCleanerSvc(CleanerSvc=cleanerSvc))
167
168
169 return result
170
171
172def addFoldersSplitOnline(flags, detDb, onlineFolders, offlineFolders, className=None, extensible=False, addMCString='_OFL', splitMC=False, tag=None, forceDb=None, modifiers=''):
173 """Add access to given folder, using either online_folder or offline_folder. For MC, add addMCString as a postfix (default is _OFL)"""
174
175 if flags.Common.isOnline and not flags.Input.isMC:
176 folders = onlineFolders
177 elif splitMC and not flags.Input.isMC:
178 folders = onlineFolders
179 else:
180 # MC, so add addMCString
181 detDb = detDb + addMCString
182 folders = offlineFolders
183
184 return addFolders(flags, folders, detDb, className, extensible, tag=tag, db=forceDb, modifiers=modifiers)
185
186
187_dblist = {
188 'INDET':'COOLONL_INDET',
189 'INDET_ONL':'COOLONL_INDET',
190 'PIXEL':'COOLONL_PIXEL',
191 'PIXEL_ONL':'COOLONL_PIXEL',
192 'SCT':'COOLONL_SCT',
193 'SCT_ONL':'COOLONL_SCT',
194 'TRT':'COOLONL_TRT',
195 'TRT_ONL':'COOLONL_TRT',
196 'LAR':'COOLONL_LAR',
197 'LAR_ONL':'COOLONL_LAR',
198 'TILE':'COOLONL_TILE',
199 'TILE_ONL':'COOLONL_TILE',
200 'MUON':'COOLONL_MUON',
201 'MUON_ONL':'COOLONL_MUON',
202 'MUONALIGN':'COOLONL_MUONALIGN',
203 'MUONALIGN_ONL':'COOLONL_MUONALIGN',
204 'MDT':'COOLONL_MDT',
205 'MDT_ONL':'COOLONL_MDT',
206 'RPC':'COOLONL_RPC',
207 'RPC_ONL':'COOLONL_RPC',
208 'TGC':'COOLONL_TGC',
209 'TGC_ONL':'COOLONL_TGC',
210 'CSC':'COOLONL_CSC',
211 'CSC_ONL':'COOLONL_CSC',
212 'TDAQ':'COOLONL_TDAQ',
213 'TDAQ_ONL':'COOLONL_TDAQ',
214 'GLOBAL':'COOLONL_GLOBAL',
215 'GLOBAL_ONL':'COOLONL_GLOBAL',
216 'TRIGGER':'COOLONL_TRIGGER',
217 'TRIGGER_ONL':'COOLONL_TRIGGER',
218 'CALO':'COOLONL_CALO',
219 'CALO_ONL':'COOLONL_CALO',
220 'FWD':'COOLONL_FWD',
221 'FWD_ONL':'COOLONL_FWD',
222 'INDET_OFL':'COOLOFL_INDET',
223 'PIXEL_OFL':'COOLOFL_PIXEL',
224 'SCT_OFL':'COOLOFL_SCT',
225 'TRT_OFL':'COOLOFL_TRT',
226 'LAR_OFL':'COOLOFL_LAR',
227 'TILE_OFL':'COOLOFL_TILE',
228 'MUON_OFL':'COOLOFL_MUON',
229 'MUONALIGN_OFL':'COOLOFL_MUONALIGN',
230 'MDT_OFL':'COOLOFL_MDT',
231 'RPC_OFL':'COOLOFL_RPC',
232 'TGC_OFL':'COOLOFL_TGC',
233 'CSC_OFL':'COOLOFL_CSC',
234 'TDAQ_OFL':'COOLOFL_TDAQ',
235 'DCS_OFL':'COOLOFL_DCS',
236 'GLOBAL_OFL':'COOLOFL_GLOBAL',
237 'TRIGGER_OFL':'COOLOFL_TRIGGER',
238 'CALO_OFL':'COOLOFL_CALO',
239 'FWD_OFL':'COOLOFL_FWD'
240}
241
242
243def addOverride(flags, folder, tag, tagType="tag", db=None):
244 """Add xml override for the specified folder (folder-level tag, forceRunNumber, ...)"""
245 suffix = ''
246 if db:
247 suffix = f' <db>{db}</db>'
248 return IOVDbSvcCfg(flags, overrideTags=(f'<prefix>{folder}</prefix> <{tagType}>{tag}</{tagType}>{suffix}',))
249
250
251def _extractFolder(folderString):
252 """Extract the folder name (non-XML text) from a IOVDbSvc.Folders entry"""
253 folderName = ''
254 xmlTag = ''
255 ix = 0
256 while ix < len(folderString):
257 if (folderString[ix] == '<' and xmlTag == ''):
258 ix2 = folderString.find('>', ix)
259 if ix2 != -1:
260 xmlTag = folderString[ix + 1 : ix2].strip()
261 ix = ix2 + 1
262 elif folderString[ix:ix+2] == '</' and xmlTag != '':
263 ix2 = folderString.find('>', ix)
264 if ix2 != -1:
265 xmlTag = ''
266 ix = ix2 + 1
267 else:
268 ix2 = folderString.find('<', ix)
269 if ix2 == -1:
270 ix2 = len(folderString)
271 if xmlTag == '':
272 folderName = folderName + folderString[ix : ix2]
273 ix = ix2
274 return folderName.strip()
275
276
277@cache #Fill only once
278def getSqliteContent(sqliteInput,takeFolders,databaseInstance):
279 if sqliteInput == "": return []
280 sqliteFolders=dict()
281 if isinstance(takeFolders, str):
282 takeFolders=[takeFolders,]
283 dbStr="sqlite://;schema="+ sqliteInput+";dbname="+databaseInstance
284 from PyCool import cool
285 dbSvc = cool.DatabaseSvcFactory.databaseService()
286 db = dbSvc.openDatabase(dbStr)
287 nodelist=db.listAllNodes()
288 for node in nodelist:
289 if db.existsFolder(node):
290 if (len(takeFolders)>0 and str(node) not in takeFolders): continue
291 connStr="<db>"+dbStr+"</db>"
292 f=db.getFolder(node)
293 if f.versioningMode is not cool.FolderVersioning.SINGLE_VERSION:
294 tags=f.listTags()
295 if len(tags)==1:
296 connStr+="<tag>"+tags[0]+"</tag>"
297 sqliteFolders[str(node)]=connStr
298 db.closeDatabase()
299
300 if len(takeFolders)>0:
301 missedFolders=set(takeFolders)-set(sqliteFolders.keys())
302 if len(missedFolders):
303 msg.error("The following folders were requested via the flag IOVSvc.sqliteFolder but not found in the sqlite file %s",(sqliteInput))
304 for f in missedFolders:
305 msg.error(f)
306
307 msg.info("The following folders/tags are read from sqlite:")
308 for v in sqliteFolders.items():
309 msg.info("\t"+str(v))
310 return sqliteFolders
311
312
313#post-exec-style helper method to remove a folder from IOVDbSvc.Folders and CondInputLoader.Load
314#To be used in calibration-processing jobs that read the condions from anohter source or produce it in the same job
315def blockFolder(ca,folder):
316 "Block use of specified conditions DB folder so data can be read from elsewhere"
317 msg.info("Trying to remove folder [%s] from IOVDbSvc.Folders",folder)
318 iovdbsvc=ca.getService("IOVDbSvc")
319 oldLen=len(iovdbsvc.Folders)
320 iovdbsvc.Folders=[x for x in iovdbsvc.Folders if x.find(folder)==-1]
321 newLen=len(iovdbsvc.Folders)
322 if (oldLen==newLen):
323 msg.warning("Folder [%s] not found in IOVDbSvc.Folder",folder)
324 return
325 elif (oldLen-newLen>1):
326 msg.warning("Folder string [%s] matched more than one folder, removed %i folders",folder,oldLen-newLen)
327
328
329 condInputLoader=ca.getCondAlgo("CondInputLoader")
330 condInputLoader.Load=set([x for x in condInputLoader.Load if x[1].find(folder)==-1])
331 return
332
333
334
335if __name__ == '__main__':
336 from AthenaConfiguration.AllConfigFlags import initConfigFlags
337 from AthenaConfiguration.TestDefaults import defaultTestFiles
338 flags = initConfigFlags()
339 flags.Input.Files = defaultTestFiles.RAW_RUN2
340 flags.lock()
341
342 acc = IOVDbSvcCfg(flags)
343
344 with open('test.pkl','wb') as f:
345 acc.store(f)
STL class.
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:140
addFoldersSplitOnline(flags, detDb, onlineFolders, offlineFolders, className=None, extensible=False, addMCString='_OFL', splitMC=False, tag=None, forceDb=None, modifiers='')
IOVDbSvcCfg(flags, **kwargs)
addFolderList(flags, listOfFolderInfoTuple, extensible=False, db=None, modifiers='')
CondInputLoaderCfg(flags, **kwargs)
DBReplicaSvcCfg(flags, vetoDBRelease=False, **kwargs)
getSqliteContent(sqliteInput, takeFolders, databaseInstance)
addFolders(flags, folderStrings, detDb=None, className=None, extensible=False, tag=None, db=None, modifiers='')
addOverride(flags, folder, tag, tagType="tag", db=None)
_extractFolder(folderString)