Loading [MathJax]/extensions/tex2jax.js
ATLAS Offline Software
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
DumpGeoConfig.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
2 
3 #----------------------------------------------------------------
4 # Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch>
5 # Initial version: Feb 2024
6 #
7 # Main updates:
8 # - 2025, Feb -- Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch>
9 # Added dedicated DumpGeo flags as GeoModel.DumpGeo;
10 # also, support the use of DumpGeo transforms and other
11 # Athena jobs -- that is, not standalone. This is useful
12 # when we want to dump the geometry that comes out as the
13 # output of an Athena job.
14 #----------------------------------------------------------------
15 import os, sys
16 
17 # Set the CA environment
18 from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator
19 from AthenaConfiguration.ComponentFactory import CompFactory
20 
21 # Set the Athena Logger
22 from AthenaCommon.Logging import logging
23 _logger = logging.getLogger('DumpGeo')
24 
25 def configureGeometry(flags, cfg):
26 
27  # Beam pipe
28  if flags.Detector.GeometryBpipe:
29  from BeamPipeGeoModel.BeamPipeGMConfig import BeamPipeGeometryCfg
30  cfg.merge(BeamPipeGeometryCfg(flags))
31 
32  # Inner Detectors
33  if flags.Detector.GeometryPixel:
34  from PixelGeoModel.PixelGeoModelConfig import PixelReadoutGeometryCfg
35  cfg.merge(PixelReadoutGeometryCfg(flags))
36  # TODO: do we need to set this separately?
37  # if flags.Detector.GeometryBCM:
38 
39  if flags.Detector.GeometrySCT:
40  from SCT_GeoModel.SCT_GeoModelConfig import SCT_ReadoutGeometryCfg
41  cfg.merge(SCT_ReadoutGeometryCfg(flags))
42 
43  if flags.Detector.GeometryTRT:
44  from TRT_GeoModel.TRT_GeoModelConfig import TRT_ReadoutGeometryCfg
45  cfg.merge(TRT_ReadoutGeometryCfg(flags))
46 
47  # InDetServMat
48  # Trigger the build of the InDetServMat geometry
49  # if any ID subsystems have been enabled
50  if flags.Detector.GeometryID:
51  from InDetServMatGeoModel.InDetServMatGeoModelConfig import (
52  InDetServiceMaterialCfg)
53  cfg.merge(InDetServiceMaterialCfg(flags))
54 
55  # Calorimeters
56  if flags.Detector.GeometryLAr:
57  from LArGeoAlgsNV.LArGMConfig import LArGMCfg
58  cfg.merge(LArGMCfg(flags))
59 
60  if flags.Detector.GeometryTile:
61  from TileGeoModel.TileGMConfig import TileGMCfg
62  #flags.Tile.forceFullGeometry = True
63  cfg.merge(TileGMCfg(flags))
64  # We must set the "FULL" geometry explicitely, otherwise the "RECO" version will be used by default,
65  # which is almost 'empty' (just the first level of child volumes is created for the "RECO" geo).
66  cfg.getService("GeoModelSvc").DetectorTools["TileDetectorTool"].GeometryConfig="FULL"
67  # TODO: do we need to set this separately?
68  # if flags.Detector.GeometryMBTS:
69 
70  # Muon spectrometer
71  if flags.Detector.GeometryMuon:
72  from MuonConfig.MuonGeometryConfig import MuonGeoModelCfg
73  cfg.merge(MuonGeoModelCfg(flags))
74 
75  # HGTD (defined only for Run4 geometry tags)
76  if flags.Detector.GeometryHGTD:
77  #set up geometry
78  if flags.HGTD.Geometry.useGeoModelXml:
79  from HGTD_GeoModelXml.HGTD_GeoModelConfig import HGTD_SimulationGeometryCfg
80  else:
81  from HGTD_GeoModel.HGTD_GeoModelConfig import HGTD_SimulationGeometryCfg
82  cfg.merge(HGTD_SimulationGeometryCfg(flags))
83 
84  # ITk (defined only for Run4 geometry tags)
85  if flags.Detector.GeometryITkPixel:
86  from PixelGeoModelXml.ITkPixelGeoModelConfig import ITkPixelReadoutGeometryCfg
87  cfg.merge(ITkPixelReadoutGeometryCfg(flags))
88  if flags.Detector.GeometryITkStrip:
89  from StripGeoModelXml.ITkStripGeoModelConfig import ITkStripReadoutGeometryCfg
90  cfg.merge(ITkStripReadoutGeometryCfg(flags))
91  # TODO: do we need to set those separately?
92  # if flags.Detector.GeometryBCMPrime:
93  # if flags.Detector.GeometryPLR:
94 
95  # Cavern (disabled by default)
96  if flags.Detector.GeometryCavern:
97  from AtlasGeoModel.CavernGMConfig import CavernGeometryCfg
98  cfg.merge(CavernGeometryCfg(flags))
99 
100  # Forward detectors (disabled by default)
101  if flags.Detector.GeometryLucid or flags.Detector.GeometryALFA or flags.Detector.GeometryAFP or flags.Detector.GeometryFwdRegion :
102  from AtlasGeoModel.ForDetGeoModelConfig import ForDetGeometryCfg
103  cfg.merge(ForDetGeometryCfg(flags))
104  if flags.Detector.GeometryZDC:
105  from ZDC_GeoM.ZdcGeoModelConfig import ZDC_DetToolCfg
106  cfg.merge(ZDC_DetToolCfg(flags))
107 
108  # Temporary 'hack':
109  # Replace EllipticTube with Box,
110  # to bypass a crash due to lack of support
111  # for EllipticTube in GeoModelIO
112  # See: https://its.cern.ch/jira/browse/ATLASSIM-7263
113  if "ForwardRegionGeoModelTool" in cfg.getService("GeoModelSvc").DetectorTools:
114  cfg.getService("GeoModelSvc").DetectorTools["ForwardRegionGeoModelTool"].vp1Compatibility=True
115 
116 
118  if "AtlasVersion" in os.environ:
119  return os.environ["AtlasVersion"]
120  if "AtlasBaseVersion" in os.environ:
121  return os.environ["AtlasBaseVersion"]
122  return "Unknown"
123 
124 def DumpGeoCfg(flags, name="DumpGeoCA", **kwargs):
125  result = ComponentAccumulator()
126 
127  _logger.info("We're using these 'GeoModel.DumpGeo' configuration flags:")
128  flags.dump("GeoModel.DumpGeo")
129 
130  # Debug messages
131  _logger.debug("kwargs: %s", kwargs)
132 
133  # set additional DumpGeo Alg's properties
134  _logger.verbose("Using ATLAS/Athena version: %s", getATLASVersion())
135  _logger.verbose("Using GeoModel ATLAS version: %s", flags.GeoModel.AtlasVersion)
136  kwargs.setdefault("AtlasRelease", getATLASVersion())
137  kwargs.setdefault("AtlasVersion", flags.GeoModel.AtlasVersion)
138 
139  # Set the user's choice to see the content of the Treetops
140  if flags.GeoModel.DumpGeo.ShowTreetopContent:
141  kwargs.setdefault("ShowTreetopContent", True)
142 
143  # Set the name of the output '.db' file.
144  # Pick the custom name if the user set it;
145  # otherwise, build it from the geometry tag
146  # and the filtered Detector Managers (if any).
147  outFileName = ""
148  if flags.GeoModel.DumpGeo.OutputFileName:
149  outFileName = flags.GeoModel.DumpGeo.OutputFileName
150  else:
151  # Handle the user's inputs and create a file name
152  # for the output SQLite, accordingly
153  outFileName = "geometry"
154  filterDetManagers = []
155  # - Put Geometry TAG into the file name
156  # NOTE: at this point, the user-defined Geo TAG args.detDescr,
157  # if set, has already replaced the default TAG in 'flags';
158  # so, we can use the latter, directy.
159  geoTAG = flags.GeoModel.AtlasVersion
160  _logger.info("+++ Dumping this Detector Description geometry TAG: '%s'", geoTAG)
161  outFileName = outFileName + "-" + geoTAG
162 
163  if flags.GeoModel.DumpGeo.FilterDetManagers:
164 
165  _logger.info("+++ Filtering on these GeoModel 'Detector Managers': '%s'", flags.GeoModel.DumpGeo.FilterDetManagers)
166 
167  filterDetManagers = flags.GeoModel.DumpGeo.FilterDetManagers
168 
169  # Set the filter variable that is used in the C++ code
170  kwargs.setdefault("UserFilterDetManager", filterDetManagers)
171 
172  # - Put the filtered Detector Managers' names into the file name,
173  # if the user asked to filter on them
174  outFileName = outFileName + "-" + "-".join(filterDetManagers)
175 
176  # - Add the final extension to the name of the output SQLite file
177  outFileName = outFileName + ".db"
178 
179  # Set the output file name variable in the C++ code
180  kwargs.setdefault("OutSQLiteFileName", outFileName)
181 
182  # Check if the output SQLite file exists already,
183  # and overwrite it if the user asked to do so;
184  # otherwise, throw an error.
185  if os.path.exists(outFileName):
186  if flags.GeoModel.DumpGeo.ForceOverwrite:
187  print("+ DumpGeo -- NOTE -- You chose to overwrite an existing geometry dump file with the same name, if present.")
188  # os.environ["DUMPGEOFORCEOVERWRITE"] = "1" # save to an env var, for later use in GeoModelStandalone/GeoExporter
189  # Check if the file exists before attempting to delete it
190  if os.path.exists(outFileName):
191  os.remove(outFileName)
192  _logger.verbose(f"The file {outFileName} has been deleted.")
193  else:
194  _logger.verbose(f"The file {outFileName} does not exist. So, it was not needed to 'force-delete' it. Continuing...")
195  else:
196  _logger.error(f"+++ DumpGeo -- ERROR!! The ouput file '{outFileName}' exists already!\nPlease move or remove it, or use the 'force' option: '-f' or '--forceOverWrite'.\n\n")
197  sys.exit()
198 
199  # Schedule the DumpGeo Athena Algorithm
200  the_alg = CompFactory.DumpGeo(name="DumpGeoAlg", **kwargs)
201  result.addEventAlgo(the_alg, primary=True)
202  return result
203 
204 
205 if __name__=="__main__":
206  # Run with e.g. python -m DumpGeo.DumpGeoConfig --detDescr=<ATLAS-geometry-tag> --filterDetManagers=[<list of tree tops>]
207 
208  from AthenaConfiguration.TestDefaults import defaultGeometryTags
209 
210  # ++++ Firstly we setup flags ++++
211  # +++ Set the Athena Flags
212  from AthenaConfiguration.AllConfigFlags import initConfigFlags
213  flags = initConfigFlags()
214 
215  flags.Exec.MaxEvents = 0
216  # ^ We do not need any events to get the GeoModel tree from the GeoModelSvc.
217  # So, we don't need to run on any events,
218  # and we don't need to trigger any execute() Athena methods either.
219  # So, we set 'EvtMax' to 0 and Athena will skip the 'execute' phase;
220  # only the 'finalize' step will be run after the 'init'.
221  # -- Note:
222  # Also, if we run on events (even on 1 event) and we dump the Pixel
223  # as part of the DetectorManager filter, then we get a crash because
224  # the PixelDetectorManager complains during the 'execute' phase,
225  # because we 'stole' a handle on its TreeTop,
226  # which contains a FullPhysVol and cannot be shared.
227 
228  flags.Concurrency.NumThreads = 0
229  # ^ DumpGeo will not work with the scheduler, since its condition/data dependencies are not known in advance
230  # More in details: the scheduler needs to know BEFORE the event, what the dependencies of each Alg are.
231  # So for DumpGeo, no dependencies are declared, which means the conditions data is not there.
232  # So when I load tracks, the geometry is missing and it crashes.
233  # Turning off the scheduler (with NumThreads=0) fixes this.
234 
235  # +++ Set custom CLI parameters for DumpGeo when ran as a standalone program
236  # (that is, from the command line,
237  # and not as part of an Athena Transform or job)
238  parser = flags.getArgumentParser(description="Dump the detector geometry to a GeoModel-based SQLite '.db' file.")
239  parser.prog = 'dump-geo'
240  # here we extend the parser with CLI options specific to DumpGeo
241  parser.add_argument("--detDescr", default=defaultGeometryTags.RUN3,
242  help="The ATLAS geometry tag you want to dump (a convenience alias for the Athena flag 'GeoModel.AtlasVersion=TAG')", metavar="TAG")
243  parser.add_argument("--outFilename", default="",
244  help="Here you can set a custom name for the output '.db' file. It will replace the name that is built with the geometry tag and the list of fileterd Detector Managers, if any.", metavar="FILENAME")
245  # parser.add_argument("--filterTreeTops", help="Only output the GeoModel Tree Tops specified in the FILTER list; input is a comma-separated list")
246  parser.add_argument("--filterDetManagers", help="Only output the GeoModel Detector Managers specified in the FILTER list; input is a comma-separated list")
247  parser.add_argument("-f", "--forceOverwrite",
248  help="Force to overwrite an existing SQLite output file with the same name, if any", action = 'store_true')
249  parser.add_argument("--showTreetopContent",
250  help="Show the content of the Treetops --- (by default, only the list of Treetops is shown)", action = 'store_true')
251  parser.add_argument("--debugCA", help="Debug the CA configuration: print flags, tools, ... --- mainly, for DumpGeo developers. '1' prints a subset of the CA flags, '2' prints all of them.")
252 
253  args = flags.fillFromArgs(parser=parser)
254 
255  if args.help:
256  # No point doing more here, since we just want to print the help.
257  sys.exit()
258 
259  # +++ Get CLI parameters and set the corresponding configuration flags
260  # Get the user's custom file name, if set;
261  # this will replace the filename computed
262  # from the geometry tag and the filtered volumes
263  if args.outFilename:
264  flags.GeoModel.DumpGeo.OutputFileName = args.outFilename
265  if args.showTreetopContent:
266  flags.GeoModel.DumpGeo.ShowTreetopContent = True
267  if args.forceOverwrite:
268  flags.GeoModel.DumpGeo.ForceOverwrite = True
269 
270 
271  # +++ Set the empty input
272  _logger.verbose("+ About to set flags related to the input")
273  # Empty input is not normal for Athena, so we will need to check
274  # this repeatedly below (the same as with VP1)
275  dumpgeo_empty_input = False
276  # This covers the use case where we launch DumpGeo
277  # without input files; e.g., to check the detector description
278  if (flags.Input.Files == [] or
279  flags.Input.Files == ['_ATHENA_GENERIC_INPUTFILE_NAME_']):
280  from Campaigns.Utils import Campaign
281  from AthenaConfiguration.TestDefaults import defaultConditionsTags, defaultGeometryTags
282 
283  dumpgeo_empty_input = True
284  # NB Must set e.g. ConfigFlags.Input.Runparse_args() Number and
285  # ConfigFlags.Input.TimeStamp before calling the
286  # MainServicesCfg to avoid it attempting auto-configuration
287  # from an input file, which is empty in this use case.
288  # If you don't have it, it (and/or other Cfg routines) complains and crashes.
289  # See also:
290  # https://acode-browser1.usatlas.bnl.gov/lxr/source/athena/InnerDetector/InDetConditions/SCT_ConditionsAlgorithms/python/SCT_DCSConditionsTestAlgConfig.py#0023
291  flags.Input.ProjectName = "mc23_13p6TeV"
292  flags.Input.RunNumbers = [330000]
293  flags.Input.TimeStamps = [1]
294  flags.Input.TypedCollections = []
295 
296  # set default CondDB and Geometry version
297  flags.IOVDb.GlobalTag = defaultConditionsTags.RUN3_MC
298  flags.Input.isMC = True
299  flags.Input.MCCampaign = Campaign.Unknown
300  flags.GeoModel.AtlasVersion = defaultGeometryTags.RUN3
301  _logger.verbose("+ ... Done")
302  _logger.verbose("+ empty input: '%s'" % dumpgeo_empty_input)
303 
304  _logger.verbose("+ detDescr flag: '%s'" % args.detDescr)
305 
306 
307  # +++ Set the detector geometry
308  _logger.verbose("+ About to set the detector flags")
309  # So we can now set up the geometry flags from the input
310  from AthenaConfiguration.DetectorConfigFlags import setupDetectorFlags
311  setupDetectorFlags(flags, None, use_metadata=not dumpgeo_empty_input,
312  toggle_geometry=True, keep_beampipe=True)
313  _logger.verbose("+ ... Done")
314 
315  if args.detDescr:
316  _logger.verbose("+ About to set this detector description tag: '%s'" % args.detDescr)
317  flags.GeoModel.AtlasVersion = args.detDescr
318  _logger.verbose("+ ... Done")
319 
320  # finalize setting flags: lock them.
321  flags.lock()
322 
323  # ++++ Now we setup the actual configuration ++++
324  _logger.verbose("+ Setup main services")
325  from AthenaConfiguration.MainServicesConfig import MainServicesCfg
326  cfg = MainServicesCfg(flags)
327  _logger.verbose("+ ...Done")
328 
329  _logger.verbose("+ About to setup geometry")
330  configureGeometry(flags,cfg)
331  _logger.verbose("+ ...Done")
332 
333  # debug messages
334  if args.debugCA:
335  debugCAlevel = int(args.debugCA)
336  if debugCAlevel >= 1:
337  _logger.verbose("Debug --- printing flags...")
338  print("\nflags:", flags)
339  for fl in flags:
340  print("fl:", fl)
341  print("\nflags.Tile:", flags.Tile)
342  for fl in flags.Tile:
343  print("fl.Tile:", fl)
344  print(dir(cfg))
345  print("cfg._privateTools: ", cfg._privateTools)
346  print("cfg._publicTools: ", cfg._publicTools)
347  if debugCAlevel >= 2:
348  flags.dump()
349  flags._loadDynaFlags('GeoModel')
350  flags._loadDynaFlags('Detector')
351  flags.dump('Detector.(Geometry|Enable)', True)
352  if debugCAlevel >= 1:
353  _logger.verbose("We're in a debugCA session, flags have been printed out, now exiting...")
354  sys.exit()
355 
356  # +++ Configure DumpGeo and run
357  cfg.merge(DumpGeoCfg(flags))
358  cfg.run()
359 
python.JetAnalysisCommon.ComponentAccumulator
ComponentAccumulator
Definition: JetAnalysisCommon.py:302
BeamPipeGMConfig.BeamPipeGeometryCfg
def BeamPipeGeometryCfg(flags)
Definition: BeamPipeGMConfig.py:5
TRT_GeoModelConfig.TRT_ReadoutGeometryCfg
def TRT_ReadoutGeometryCfg(flags)
Definition: TRT_GeoModelConfig.py:59
python.InDetServMatGeoModelConfig.InDetServiceMaterialCfg
def InDetServiceMaterialCfg(flags)
Definition: InDetServMatGeoModelConfig.py:8
ITkStripGeoModelConfig.ITkStripReadoutGeometryCfg
def ITkStripReadoutGeometryCfg(flags)
Definition: ITkStripGeoModelConfig.py:43
python.ForDetGeoModelConfig.ForDetGeometryCfg
def ForDetGeometryCfg(flags)
Definition: ForDetGeoModelConfig.py:33
ITkPixelGeoModelConfig.ITkPixelReadoutGeometryCfg
def ITkPixelReadoutGeometryCfg(flags)
Definition: ITkPixelGeoModelConfig.py:39
DumpGeoConfig.configureGeometry
def configureGeometry(flags, cfg)
Definition: DumpGeoConfig.py:25
ZdcGeoModelConfig.ZDC_DetToolCfg
def ZDC_DetToolCfg(flags)
Definition: ZdcGeoModelConfig.py:4
SCT_GeoModelConfig.SCT_ReadoutGeometryCfg
def SCT_ReadoutGeometryCfg(flags)
Definition: SCT_GeoModelConfig.py:50
python.LArMinBiasAlgConfig.int
int
Definition: LArMinBiasAlgConfig.py:59
python.MainServicesConfig.MainServicesCfg
def MainServicesCfg(flags, LoopMgr='AthenaEventLoopMgr')
Definition: MainServicesConfig.py:260
LArGMConfig.LArGMCfg
def LArGMCfg(flags)
Definition: LArGMConfig.py:8
beamspotman.dir
string dir
Definition: beamspotman.py:623
print
void print(char *figname, TCanvas *c1)
Definition: TRTCalib_StrawStatusPlots.cxx:25
PixelGeoModelConfig.PixelReadoutGeometryCfg
def PixelReadoutGeometryCfg(flags)
Definition: PixelGeoModelConfig.py:52
TCS::join
std::string join(const std::vector< std::string > &v, const char c=',')
Definition: Trigger/TrigT1/L1Topo/L1TopoCommon/Root/StringUtils.cxx:10
python.DetectorConfigFlags.setupDetectorFlags
def setupDetectorFlags(flags, custom_list=None, use_metadata=False, toggle_geometry=False, validate_only=False, keep_beampipe=False)
Definition: DetectorConfigFlags.py:291
DumpGeoConfig.getATLASVersion
def getATLASVersion()
Definition: DumpGeoConfig.py:117
python.CavernGMConfig.CavernGeometryCfg
def CavernGeometryCfg(flags)
Definition: CavernGMConfig.py:6
python.MuonGeometryConfig.MuonGeoModelCfg
def MuonGeoModelCfg(flags)
Definition: MuonGeometryConfig.py:28
python.AllConfigFlags.initConfigFlags
def initConfigFlags()
Definition: AllConfigFlags.py:19
DumpGeoConfig.DumpGeoCfg
def DumpGeoCfg(flags, name="DumpGeoCA", **kwargs)
Definition: DumpGeoConfig.py:124
HGTD_GeoModelConfig.HGTD_SimulationGeometryCfg
def HGTD_SimulationGeometryCfg(flags)
Definition: python/HGTD_GeoModelConfig.py:17
TileGMConfig.TileGMCfg
def TileGMCfg(flags)
Definition: TileGMConfig.py:7