ATLAS Offline Software
AutoConfigFlags.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2 
3 from PyUtils.MetaReader import read_metadata, lite_primary_keys_to_keep, lite_TagInfo_keys_to_keep
4 from AthenaCommon.Logging import logging
5 from functools import lru_cache
6 
7 msg = logging.getLogger('AutoConfigFlags')
8 
9 # Module level cache of file-metadata:
10 _fileMetaData = dict()
11 
13  def __init__(self, filename):
14  self.metadata = {}
15  self.filename = filename
16  self.metAccessLevel = 'lite'
17  thisFileMD = read_metadata(filename, None, 'lite')
18  self.metadata.update(thisFileMD[self.filename])
19  msg.debug("Loaded using 'lite' %s", str(self.metadata))
20 
21  def _loadMore(self):
22  thisFileMD = read_metadata(self.filename, None, 'peeker')
23  self.metadata.update(thisFileMD[self.filename])
24 
25  def get(self, key, default):
26  if key in self.metadata:
27  return self.metadata[key]
28  if self.metAccessLevel != 'peeker' \
29  and key not in lite_primary_keys_to_keep \
30  and key not in lite_TagInfo_keys_to_keep:
31  msg.info("Looking into the file in 'peeker' mode as the configuration requires more details: %s ", key)
32  self.metAccessLevel = 'peeker'
33  self._loadMore()
34  if key in self.metadata:
35  return self.metadata[key]
36  return default
37 
38  def __contains__(self, key):
39  self.get(key, None)
40  return key in self.metadata
41 
42  def __getitem__(self, key):
43  return self.get(key, None)
44 
45  def __repr__(self):
46  return repr(self.metadata)
47 
48  def keys(self):
49  return self.metadata.keys()
50 
51 def GetFileMD(filenames, allowEmpty=True):
52  if not filenames:
53  if allowEmpty:
54  msg.info("Running an input-less job. Will have empty metadata.")
55  return {}
56  raise RuntimeError("Metadata can not be read in an input-less job.")
57  if isinstance(filenames, str):
58  filenames = [filenames]
59  if '_ATHENA_GENERIC_INPUTFILE_NAME_' in filenames:
60  raise RuntimeError('Input file name not set, instead _ATHENA_GENERIC_INPUTFILE_NAME_ found. Cannot read metadata.')
61  for filename in filenames:
62  if filename not in _fileMetaData:
63  msg.info("Obtaining metadata of auto-configuration by peeking into '%s'", filename)
64  _fileMetaData[filename] = DynamicallyLoadMetadata(filename)
65  if _fileMetaData[filename]['nentries'] not in [None, 0]:
66  return _fileMetaData[filename]
67  else:
68  msg.info("The file: %s has no entries, going to the next one for harvesting the metadata", filename)
69  msg.info("No file with events found, returning anyways metadata associated to the first file %s", filenames[0])
70  return _fileMetaData[filenames[0]]
71 
72 def _initializeGeometryParameters(geoTag,sqliteDB,sqliteDBFullPath):
73  """Read geometry database for all detectors"""
74 
75  from AtlasGeoModel import CommonGeoDB
76  from PixelGeoModel import PixelGeoDB
77  from LArGeoAlgsNV import LArGeoDB
78  from MuonGeoModel import MuonGeoDB
79 
80  if not sqliteDB:
81  # Read parameters from Oracle/Frontier
82  from AtlasGeoModel.AtlasGeoDBInterface import AtlasGeoDBInterface
83  dbGeomCursor = AtlasGeoDBInterface(geoTag)
84  dbGeomCursor.ConnectAndBrowseGeoDB()
85 
86  params = { 'Common' : CommonGeoDB.InitializeGeometryParameters(dbGeomCursor),
87  'Pixel' : PixelGeoDB.InitializeGeometryParameters(dbGeomCursor),
88  'LAr' : LArGeoDB.InitializeGeometryParameters(dbGeomCursor),
89  'Muon' : MuonGeoDB.InitializeGeometryParameters(dbGeomCursor),
90  'Luminosity' : CommonGeoDB.InitializeLuminosityDetectorParameters(dbGeomCursor),
91  }
92 
93  msg.debug('Config parameters retrieved from Geometry DB (Frontier/Oracle):')
94  for key in params.keys():
95  msg.debug(f'{key} -> {params[key]}')
96  else:
97  # Read parameters from SQLite
98  from AtlasGeoModel.AtlasGeoDBInterface import AtlasGeoDBInterface_SQLite
99  sqliteReader = AtlasGeoDBInterface_SQLite(geoTag,sqliteDBFullPath)
100  sqliteReader.ConnectToDB()
101 
102  params = { 'Common' : CommonGeoDB.InitializeGeometryParameters_SQLite(sqliteReader),
103  'Pixel' : PixelGeoDB.InitializeGeometryParameters_SQLite(sqliteReader),
104  'LAr' : LArGeoDB.InitializeGeometryParameters_SQLite(sqliteReader),
105  'Muon' : MuonGeoDB.InitializeGeometryParameters_SQLite(sqliteReader),
106  'Luminosity' : CommonGeoDB.InitializeLuminosityDetectorParameters_SQLite(sqliteReader),
107  }
108 
109  msg.debug('Config parameters retrieved from Geometry DB (SQLite):')
110  for key in params.keys():
111  msg.debug(f'{key} -> {params[key]}')
112 
113  return params
114 
115 
116 @lru_cache(maxsize=4) # maxsize=1 should be enough for most jobs
117 def DetDescrInfo(geoTag, sqliteDB, sqliteDBFullPath):
118  """Query geometry DB for detector description. Returns dictionary with
119  detector description. Queries DB for each tag only once.
120 
121  geoTag: geometry tag (e.g. ATLAS-R2-2016-01-00-01)
122  """
123  if not geoTag:
124  raise ValueError("No geometry tag specified")
125 
126  detDescrInfo = _initializeGeometryParameters(geoTag,sqliteDB,sqliteDBFullPath)
127  detDescrInfo["geomTag"] = geoTag
128  return detDescrInfo
129 
130 
131 @lru_cache(maxsize=4) # maxsize=1 should be enough for most jobs
132 def getDefaultDetectors(geoTag, sqliteDB, sqliteDBFullPath, includeForward=False):
133  """Query geometry DB for detector description.
134  Returns a set of detectors used in a geometry tag.
135 
136  geoTag: geometry tag (e.g. ATLAS-R2-2016-01-00-01)
137  """
138  detectors = DetDescrInfo(geoTag,sqliteDB,sqliteDBFullPath)['Common']['Detectors']
139 
140  manualConfig = not DetDescrInfo(geoTag,sqliteDB,sqliteDBFullPath)['Common']["DetectorsConfigured"]
141 
142 
143  if manualConfig:
144  detectors.add('Bpipe')
145  if DetDescrInfo(geoTag,sqliteDB,sqliteDBFullPath)['Common']['Run'] not in ['RUN1', 'RUN2', 'RUN3']: # RUN4 and beyond
146  detectors.add('ITkPixel')
147  detectors.add('ITkStrip')
148  if DetDescrInfo(geoTag,sqliteDB,sqliteDBFullPath)['Luminosity']['BCMPrime']:
149  detectors.add('BCMPrime') # since https://gitlab.cern.ch/Atlas-Inner-Tracking/ITKLayouts/-/merge_requests/347 introduced BCMPrime geometry
150  if DetDescrInfo(geoTag,sqliteDB,sqliteDBFullPath)['Luminosity']['PLR']:
151  detectors.add('PLR')
152  else:
153  detectors.add('Pixel')
154  detectors.add('SCT')
155  detectors.add('TRT')
156  detectors.add('BCM')
157 
158  if DetDescrInfo(geoTag,sqliteDB,sqliteDBFullPath)['Common']['Run'] not in ['RUN1', 'RUN2', 'RUN3']: # RUN4 and beyond
159  detectors.add('HGTD')
160 
161  detectors.add('LAr')
162  detectors.add('Tile')
163 
164 
165  if DetDescrInfo(geoTag,sqliteDB,sqliteDBFullPath)['Common']['Run'] in ['RUN1', 'RUN2', 'RUN3']:
166  detectors.add('MBTS')
167 
168  if DetDescrInfo(geoTag,sqliteDB,sqliteDBFullPath)['Muon']['HasMDT']:
169  detectors.add('MDT')
170  if DetDescrInfo(geoTag,sqliteDB,sqliteDBFullPath)['Muon']['HasRPC']:
171  detectors.add('RPC')
172  if DetDescrInfo(geoTag,sqliteDB,sqliteDBFullPath)['Muon']['HasTGC']:
173  detectors.add('TGC')
174  if DetDescrInfo(geoTag,sqliteDB,sqliteDBFullPath)['Muon']['HasCSC']:
175  detectors.add('CSC')
176  if DetDescrInfo(geoTag,sqliteDB,sqliteDBFullPath)['Muon']['HasSTGC']:
177  detectors.add('sTGC')
178  if DetDescrInfo(geoTag,sqliteDB,sqliteDBFullPath)['Muon']['HasMM']:
179  detectors.add('MM')
180 
181  if includeForward:
182  detectors.add('Lucid')
183  if DetDescrInfo(geoTag,sqliteDB,sqliteDBFullPath)['Common']['Run'] not in ['RUN1']:
184  detectors.add('AFP')
185  detectors.add('ZDC')
186  detectors.add('ALFA')
187  detectors.add('FwdRegion')
188 
189  return detectors
190 
191 
192 # Based on RunDMCFlags.py
194  # this wrapper is intended to avoid an initial import
195  from .RunToTimestampData import RunToTimestampDict
196  return RunToTimestampDict
197 
198 
200  """This is used to hold a dictionary of the form
201  {152166:1269948352889940910, ...} to allow the
202  timestamp to be determined from the run.
203  """
204  run2timestampDict = getRunToTimestampDict()
205  timeStamps = [run2timestampDict.get(runNumber,1) for runNumber in runNumbers] # Add protection here?
206  return timeStamps
207 
208 
209 def getGeneratorsInfo(flags):
210  """Read in GeneratorsInfo from the input file
211  """
212  from AthenaConfiguration.Enums import ProductionStep
213  inputFiles = flags.Input.Files
214  if flags.Common.ProductionStep in [ProductionStep.Overlay, ProductionStep.FastChain] and not flags.Overlay.DataOverlay and flags.Input.SecondaryFiles:
215  # Do something special for MC Overlay
216  inputFiles = flags.Input.SecondaryFiles
217  generatorsString = ""
218  from AthenaConfiguration.AutoConfigFlags import GetFileMD
219  if inputFiles:
220  generatorsString = GetFileMD(inputFiles).get("generators", "")
221  from GeneratorConfig.Versioning import generatorsGetFromMetadata
222  return generatorsGetFromMetadata( generatorsString )
223 
224 
226  """Read in special simulation job option fragments based on metadata
227  passed by the evgen stage
228  """
229  specialConfigDict = dict()
230  legacyPreIncludeToCAPostInclude = { 'SimulationJobOptions/preInclude.AMSB.py' : 'Charginos.CharginosConfig.AMSB_Cfg',
231  'SimulationJobOptions/preInclude.Monopole.py' : 'Monopole.MonopoleConfig.MonopoleCfg',
232  'SimulationJobOptions/preInclude.Quirks.py' : 'Quirks.QuirksConfig.QuirksCfg',
233  'SimulationJobOptions/preInclude.SleptonsLLP.py' : 'Sleptons.SleptonsConfig.SleptonsLLPCfg',
234  'SimulationJobOptions/preInclude.GMSB.py' : 'Sleptons.SleptonsConfig.GMSB_Cfg',
235  'SimulationJobOptions/preInclude.Qball.py' : 'Monopole.MonopoleConfig.QballCfg',
236  'SimulationJobOptions/preInclude.RHadronsPythia8.py' : 'RHadrons.RHadronsConfig.RHadronsCfg',
237  'SimulationJobOptions/preInclude.fcp.py' : 'Monopole.MonopoleConfig.fcpCfg' }
238  legacyPreIncludeToCAPreInclude = { 'SimulationJobOptions/preInclude.AMSB.py' : None,
239  'SimulationJobOptions/preInclude.Monopole.py' : 'Monopole.MonopoleConfig.MonopolePreInclude',
240  'SimulationJobOptions/preInclude.Quirks.py' : None,
241  'SimulationJobOptions/preInclude.SleptonsLLP.py' : None,
242  'SimulationJobOptions/preInclude.GMSB.py' : None,
243  'SimulationJobOptions/preInclude.Qball.py' : 'Monopole.MonopoleConfig.QballPreInclude',
244  'SimulationJobOptions/preInclude.RHadronsPythia8.py' : 'RHadrons.RHadronsConfig.RHadronsPreInclude',
245  'SimulationJobOptions/preInclude.fcp.py' : 'Monopole.MonopoleConfig.fcpPreInclude' }
246  specialConfigString = ''
247  from AthenaConfiguration.Enums import ProductionStep
248  inputFiles = flags.Input.Files
249  secondaryInputFiles = flags.Input.SecondaryFiles
250  if flags.Common.ProductionStep in [ProductionStep.Overlay, ProductionStep.FastChain] and not flags.Overlay.DataOverlay and flags.Input.SecondaryFiles:
251  # Do something special for MC Overlay
252  inputFiles = flags.Input.SecondaryFiles
253  secondaryInputFiles = flags.Input.Files
254  from AthenaConfiguration.AutoConfigFlags import GetFileMD
255  if len(inputFiles)>0:
256  specialConfigString = GetFileMD(inputFiles).get('specialConfiguration', '')
257  if (not len(specialConfigString) or specialConfigString == 'NONE') and len(secondaryInputFiles)>0:
258  # If there is no specialConfiguration metadata in the primary
259  # input try the secondary inputs (MC Overlay case)
260  specialConfigString = GetFileMD(secondaryInputFiles).get('specialConfiguration', '')
261  if len(specialConfigString)>0:
262 
264  spcitems = specialConfigString.split(";")
265  for spcitem in spcitems:
266  #print spcitem
267 
268  if not spcitem or spcitem.upper() == "NONE":
269  continue
270 
271  if "=" not in spcitem:
272  spcitem = "preInclude=" + spcitem
273 
274  k, v = spcitem.split("=")
275  if k == "preInclude" and v.endswith('.py'): # Translate old preIncludes into CA-based versions.
276  if v == 'SimulationJobOptions/preInclude.RhadronsPythia8.py':
277  v = 'SimulationJobOptions/preInclude.RHadronsPythia8.py' # ATLASSIM-6687 Fixup for older EVNT files
278  v1 = legacyPreIncludeToCAPreInclude[v]
279  if v1 is not None:
280  specialConfigDict[k] = v1
281  v2 = legacyPreIncludeToCAPostInclude[v]
282  if v2 is not None:
283  specialConfigDict['postInclude'] = v2
284  else:
285  specialConfigDict[k] = v
286  return specialConfigDict
287 
python.AutoConfigFlags.getGeneratorsInfo
def getGeneratorsInfo(flags)
Definition: AutoConfigFlags.py:209
PixelGeoDB.InitializeGeometryParameters_SQLite
def InitializeGeometryParameters_SQLite(sqliteDbReader)
Definition: PixelGeoDB.py:54
python.AutoConfigFlags.getDefaultDetectors
def getDefaultDetectors(geoTag, sqliteDB, sqliteDBFullPath, includeForward=False)
Definition: AutoConfigFlags.py:132
python.MetaReader.read_metadata
def read_metadata(filenames, file_type=None, mode='lite', promote=None, meta_key_filter=None, unique_tag_info_values=True, ignoreNonExistingLocalFiles=False)
Definition: MetaReader.py:52
python.AutoConfigFlags._initializeGeometryParameters
def _initializeGeometryParameters(geoTag, sqliteDB, sqliteDBFullPath)
Definition: AutoConfigFlags.py:72
MuonGeoDB.InitializeGeometryParameters
def InitializeGeometryParameters(dbGeomCursor)
Definition: MuonGeoDB.py:3
python.AutoConfigFlags.GetFileMD
def GetFileMD(filenames, allowEmpty=True)
Definition: AutoConfigFlags.py:51
python.AutoConfigFlags.DynamicallyLoadMetadata.get
def get(self, key, default)
Definition: AutoConfigFlags.py:25
LArGeoDB.InitializeGeometryParameters
def InitializeGeometryParameters(dbGeomCursor)
Definition: LArGeoDB.py:3
python.AutoConfigFlags.DynamicallyLoadMetadata._loadMore
def _loadMore(self)
Definition: AutoConfigFlags.py:21
python.AutoConfigFlags.DynamicallyLoadMetadata.metAccessLevel
metAccessLevel
Definition: AutoConfigFlags.py:16
python.AutoConfigFlags.DynamicallyLoadMetadata.__getitem__
def __getitem__(self, key)
Definition: AutoConfigFlags.py:42
python.AutoConfigFlags.DynamicallyLoadMetadata
Definition: AutoConfigFlags.py:12
python.AutoConfigFlags.DynamicallyLoadMetadata.filename
filename
Definition: AutoConfigFlags.py:15
PyAthena::repr
std::string repr(PyObject *o)
returns the string representation of a python object equivalent of calling repr(o) in python
Definition: PyAthenaUtils.cxx:106
python.AutoConfigFlags.DynamicallyLoadMetadata.metadata
metadata
Definition: AutoConfigFlags.py:14
python.AutoConfigFlags.getRunToTimestampDict
def getRunToTimestampDict()
Definition: AutoConfigFlags.py:193
python.AutoConfigFlags.DynamicallyLoadMetadata.__repr__
def __repr__(self)
Definition: AutoConfigFlags.py:45
LArGeoDB.InitializeGeometryParameters_SQLite
def InitializeGeometryParameters_SQLite(sqliteDbReader)
Definition: LArGeoDB.py:34
python.AutoConfigFlags.getInitialTimeStampsFromRunNumbers
def getInitialTimeStampsFromRunNumbers(runNumbers)
Definition: AutoConfigFlags.py:199
python.AutoConfigFlags.DynamicallyLoadMetadata.__contains__
def __contains__(self, key)
Definition: AutoConfigFlags.py:38
get
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition: hcg.cxx:127
python.AutoConfigFlags.DynamicallyLoadMetadata.keys
def keys(self)
Definition: AutoConfigFlags.py:48
PixelGeoDB.InitializeGeometryParameters
def InitializeGeometryParameters(dbGeomCursor)
Definition: PixelGeoDB.py:3
python.Versioning.generatorsGetFromMetadata
def generatorsGetFromMetadata(metadataString)
Definition: Versioning.py:32
python.AutoConfigFlags.DetDescrInfo
def DetDescrInfo(geoTag, sqliteDB, sqliteDBFullPath)
Definition: AutoConfigFlags.py:117
str
Definition: BTagTrackIpAccessor.cxx:11
python.AutoConfigFlags.getSpecialConfigurationMetadata
def getSpecialConfigurationMetadata(flags)
Definition: AutoConfigFlags.py:225
python.AutoConfigFlags.DynamicallyLoadMetadata.__init__
def __init__(self, filename)
Definition: AutoConfigFlags.py:13
WriteBchToCool.update
update
Definition: WriteBchToCool.py:67
MuonGeoDB.InitializeGeometryParameters_SQLite
def InitializeGeometryParameters_SQLite(sqliteDbReader)
Definition: MuonGeoDB.py:31