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