ATLAS Offline Software
Loading...
Searching...
No Matches
SimConfigFlags.py
Go to the documentation of this file.
1# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
2
3from AthenaConfiguration.AthConfigFlags import AthConfigFlags, isGaudiEnv
4from AthenaConfiguration.AutoConfigFlags import GetFileMD
5from AthenaConfiguration.Enums import BeamType, LHCPeriod
6from SimulationConfig.SimEnums import BeamPipeSimMode, CalibrationRun, CavernBackground, \
7 LArParameterization, InDetParameterization, SimulationFlavour, TruthStrategy, VertexSource
8from AthenaCommon.SystemOfUnits import m, ns
9
10#todo? add in the explanatory text from previous implementation
11
13 scf = AthConfigFlags()
14 scf.addFlag("Sim.ParticleID", False)
15
16 def _checkCalibrationRun(prevFlags):
17 if prevFlags.Sim.ISF.Simulator not in [SimulationFlavour.FullG4MT, SimulationFlavour.FullG4MT_QS, SimulationFlavour.PassBackG4MT, SimulationFlavour.AtlasG4, SimulationFlavour.AtlasG4_QS] \
18 or prevFlags.Sim.LArParameterization is not LArParameterization.NoFrozenShowers:
19 return CalibrationRun.Off
20 return CalibrationRun.DeadLAr
21
22 scf.addFlag("Sim.CalibrationRun", _checkCalibrationRun, type=CalibrationRun)
23
24 scf.addFlag("Sim.CavernBackground", CavernBackground.Off, type=CavernBackground)
25 scf.addFlag("Sim.ReadTR", False)
26 scf.addFlag("Sim.WorldRRange", False) # 12500. / int or float
27 scf.addFlag("Sim.WorldZRange", False) # 22031. / int or float
28
29 def _barcodeOffsetFromTruthStrategy(prevFlags):
30 if prevFlags.Sim.TruthStrategy in [TruthStrategy.MC15, TruthStrategy.MC18, TruthStrategy.MC18LLP]:
31 return 1000000 # 1M
32 return 200000 # 200k - This is the default value - in practice it has been the same for all campaigns
33
34 def _checkSimBarcodeOffsetConf(prevFlags):
35 simBarcodeOffset = 0
36 if prevFlags.Input.Files:
37 mdstring = GetFileMD(prevFlags.Input.Files).get("SimBarcodeOffset", "0")
38 simBarcodeOffset = eval(mdstring)
39 if not simBarcodeOffset:
40 simBarcodeOffset = _barcodeOffsetFromTruthStrategy(prevFlags)
41 return simBarcodeOffset
42
43 def _regenerationIncrementFromTruthStrategy(prevFlags):
44 if prevFlags.Sim.TruthStrategy in [TruthStrategy.MC15, TruthStrategy.MC18, TruthStrategy.MC18LLP]:
45 return 10000000 # 10M
46 return 1000000 # 1M - This is the default value - in practice it has been the same for all campaigns
47
48 def _checkRegenerationIncrementConf(prevFlags):
49 regenInc = 0
50 if prevFlags.Input.Files:
51 mdstring = GetFileMD(prevFlags.Input.Files).get("RegenerationIncrement", "0")
52 regenInc = eval(mdstring)
53 if not regenInc:
54 regenInc = _regenerationIncrementFromTruthStrategy(prevFlags)
55 return regenInc
56
57 # the G4 offset.
58 scf.addFlag("Sim.SimBarcodeOffset", _checkSimBarcodeOffsetConf)
59 # barcode offset when a particle survives an interaction during simulation
60 scf.addFlag("Sim.RegenerationIncrement", _checkRegenerationIncrementConf)
61
62 # Forward region
63 scf.addFlag("Sim.TwissFileBeam1", False)
64 scf.addFlag("Sim.TwissFileBeam2", False)
65 scf.addFlag("Sim.TwissEnergy", lambda prevFlags : float(prevFlags.Beam.Energy)) # energy of each beam
66 scf.addFlag("Sim.TwissFileBeta", 90.*m)
67 scf.addFlag("Sim.TwissFileNomReal", 'nominal') # "nominal", "real" / default to one of these?!
68 scf.addFlag("Sim.TwissFileVersion", "v02")
69
70 # G4AtlasAlg
71 scf.addFlag("Sim.ReleaseGeoModel", False)
72 scf.addFlag("Sim.SimplifiedGeoPath", "")
73 scf.addFlag("Sim.RecordFlux", False)
74 scf.addFlag("Sim.TruthStrategy", lambda prevFlags : TruthStrategy.Validation if prevFlags.Sim.ISF.ValidationMode else TruthStrategy.MC12,
75 type=TruthStrategy)
76 scf.addFlag("Sim.UseShadowEvent", lambda prevFlags : prevFlags.Sim.ISF.Simulator.isQuasiStable())
77 scf.addFlag("Sim.G4Commands", ["/run/verbose 2"])
78 scf.addFlag("Sim.FlagAbortedEvents", False)
79 scf.addFlag("Sim.KillAbortedEvents", True)
80 scf.addFlag("Sim.IncludeParentsInG4Event", False)
81 scf.addFlag("Sim.UseG4Workers", False) # Run Geant4 workers in separate thread pool managed by Geant4
82
83 # Do full simulation + digitisation + reconstruction chain
84 scf.addFlag("Sim.DoFullChain", False)
85
86 def _check_G4_version(prevFlags):
87 # Determine the Geant4 version which will be used by the
88 # configuration. In jobs where we are running simulation,
89 # then the G4Version should reflect the version in the
90 # release, so the version in environment should take
91 # precedence over any input file metadata. In jobs where
92 # simulation is not run, then the G4Version from the input
93 # file metadata should take precedence.
94 version = ""
95 from AthenaConfiguration.Enums import ProductionStep
96 if prevFlags.Common.ProductionStep not in [ProductionStep.Simulation, ProductionStep.FastChain]:
97 if prevFlags.Input.Files:
98 version = GetFileMD(prevFlags.Input.Files).get("G4Version", "")
99 if not version:
100 from os import environ
101 version = str(environ.get("G4VERS", ""))
102 if prevFlags.Input.isMC and isGaudiEnv() and not version:
103 raise ValueError("Unknown G4 version")
104 return version
105
106 scf.addFlag("Sim.G4Version", _check_G4_version)
107
108 def _checkPhysicsListConf(prevFlags):
109 physicsList = "FTFP_BERT_ATL"
110 if prevFlags.Input.Files:
111 physicsList = GetFileMD(prevFlags.Input.Files).get("PhysicsList", "")
112 if not physicsList:
113 # Currently physicsList is also part of /Digitization/Parameters metadata. TODO migrate away from this.
114 physicsList = GetFileMD(prevFlags.Input.Files).get("physicsList", "FTFP_BERT_ATL")
115 return physicsList
116
117 scf.addFlag("Sim.PhysicsList", _checkPhysicsListConf)
118 scf.addFlag("Sim.NeutronTimeCut", 150.) # Sets the value for the neutron out of time cut in G4
119 scf.addFlag("Sim.NeutronEnergyCut", -1.) # Sets the value for the neutron energy cut in G4
120 scf.addFlag("Sim.ApplyEMCuts", False) # Turns on the G4 option to apply cuts for EM physics
121 scf.addFlag("Sim.MuonFieldOnlyInCalo", False) # Only muons see the B-field in the calo
122
123 # G4AtlasToolsConfig
124 scf.addFlag("Sim.RecordStepInfo", False)
125 scf.addFlag("Sim.StoppedParticleFile", "")
126 scf.addFlag("Sim.BeamPipeSimMode", BeamPipeSimMode.Normal, type=BeamPipeSimMode)
127 scf.addFlag("Sim.LArParameterization", LArParameterization.NoFrozenShowers, type=LArParameterization)
128 scf.addFlag("Sim.InDetParameterization", InDetParameterization.NONE, type=InDetParameterization)
129 # TRT Range cut used in simulation in mm. Should be 0.05 or 30.
130 scf.addFlag("Sim.TRTRangeCut",
131 lambda prevFlags: float(GetFileMD(prevFlags.Input.Files).get('TRTRangeCut', 30.0)))
132
133 # BeameffectsAlg
134 scf.addFlag("Sim.VertexSource", VertexSource.CondDB, type=VertexSource)
135 scf.addFlag("Sim.VertexTimeSmearing", lambda prevFlags:
136 prevFlags.Beam.Type == BeamType.Collisions and prevFlags.GeoModel.Run >= LHCPeriod.Run4)
137
138 def _checkVertexTimeWidth(prevFlags):
139 default = 0.175*ns
140 vertexTimeWidth = default
141 if prevFlags.Input.Files:
142 vertexTimeWidth = GetFileMD(prevFlags.Input.Files).get("VertexTimeWidth", default)
143 return vertexTimeWidth
144
145 scf.addFlag("Sim.VertexTimeWidth", _checkVertexTimeWidth)
146
147 # G4UserActions
148 scf.addFlag("Sim.NRRThreshold", False)
149 scf.addFlag("Sim.NRRWeight", False)
150 scf.addFlag("Sim.PRRThreshold", False)
151 scf.addFlag("Sim.PRRWeight", False)
152 scf.addFlag("Sim.MultipleStepsInMSCTransport", False)
153 scf.addFlag("Sim.OptionalUserActionList", [])
154
155 # G4FieldConfig
156 scf.addFlag("Sim.G4Stepper", "AtlasRK4")
157 scf.addFlag("Sim.G4EquationOfMotion", "")
158 scf.addFlag("Sim.UsingGeant4", True)
159
160 # Cosmics
161 # volume(s) used to do cosmics filtering
162 # G4 volume names from {"Muon", "Calo", "InnerDetector", "TRT_Barrel", "TRT_EC", "SCT_Barrel", "Pixel"}
163 scf.addFlag("Sim.CosmicFilterVolumeNames", ["InnerDetector"])
164 scf.addFlag("Sim.CosmicFilterID", False) # PDG ID to be filtered ("13")
165 scf.addFlag("Sim.CosmicFilterPTmin", False) # min pT filtered in cosmics processing (MeV) ("5000")
166 scf.addFlag("Sim.CosmicFilterPTmax", False) # max pT filtered in cosmics processing (MeV) ("6000")
167 scf.addFlag("Sim.CosmicPtSlice", "Off") # 'slice1', 'slice2', 'slice3', 'slice4', 'NONE'
168
169 # ISF
170 scf.addFlag("Sim.ISFRun", False)
171
172 def _checkSimulationFlavour(prevFlags):
173 simulator = SimulationFlavour.Unknown
174 if prevFlags.Input.Files:
175 simFlavour = GetFileMD(prevFlags.Input.Files).get("Simulator", "")
176 if not simFlavour:
177 simFlavour = GetFileMD(prevFlags.Input.Files).get("SimulationFlavour", "")
178 try:
179 simulator = SimulationFlavour(simFlavour)
180 except ValueError:
181 # Deal with old non-thread-safe simulators
182 if simFlavour in ['default']: # This is the case when ISF was not configured in sim
183 simulator = SimulationFlavour.AtlasG4
184 elif simFlavour in ['MC12G4', 'FullG4']:
185 simulator = SimulationFlavour.FullG4MT
186 elif simFlavour in ['FullG4_QS', 'FullG4_LongLived']:
187 simulator = SimulationFlavour.FullG4MT_QS
188 elif simFlavour in ['PassBackG4']:
189 simulator = SimulationFlavour.PassBackG4MT
190 elif simFlavour in ['ATLFASTII']:
191 simulator = SimulationFlavour.ATLFASTIIMT
192 elif simFlavour in ['ATLFASTIIF']:
193 simulator = SimulationFlavour.ATLFASTIIFMT
194 elif simFlavour in ['ATLFAST3']:
195 simulator = SimulationFlavour.ATLFAST3MT
196 elif simFlavour in ['ATLFAST3_QS']:
197 simulator = SimulationFlavour.ATLFAST3MT_QS
198 else:
199 # Obscure old-style configuration used - do not try to interpret
200 simulator = SimulationFlavour.Unknown
201 return simulator
202
203 scf.addFlag("Sim.ISF.Simulator", _checkSimulationFlavour, type=SimulationFlavour)
204 scf.addFlag("Sim.ISF.DoTimeMonitoring", True) # bool: run time monitoring
205 scf.addFlag("Sim.ISF.DoMemoryMonitoring", True) # bool: run time monitoring
206 scf.addFlag("Sim.ISF.ValidationMode", False) # bool: run ISF internal validation checks
207 scf.addFlag("Sim.ISF.ReSimulation", False) # Using ReSimulation workflow
208 scf.addFlag("Sim.ISF.UseTrackingGeometryCond", False) # Using Condition for tracking Geometry
209
210 def _decideHITSMerging(prevFlags):
211 # Further specialization possible in future
212 if prevFlags.Sim.ISF.Simulator.isFullSim() and prevFlags.Sim.LArParameterization!=LArParameterization.FastCaloSim:
213 doID = False
214 doITk = False
215 doCALO = False
216 doMUON = False
217 elif prevFlags.Sim.ISF.Simulator.usesFatras() and prevFlags.Sim.ISF.Simulator.usesFastCaloSim():
218 doID = True
219 doITk = True
220 doCALO = True
221 doMUON = True
222 elif prevFlags.Sim.ISF.Simulator.usesFastCaloSim() or prevFlags.Sim.LArParameterization is LArParameterization.FastCaloSim:
223 doID = False
224 doITk = False
225 doCALO = True
226 doMUON = False
227 elif prevFlags.Sim.ISF.Simulator in [SimulationFlavour.Unknown]:
228 doID = True
229 doITk = True
230 doCALO = True
231 doMUON = True
232 else:
233 raise ValueError("Invalid simulator")
234 return {"ID": doID, "CALO": doCALO, "MUON": doMUON, "ITk": doITk}
235
236 scf.addFlag("Sim.ISF.HITSMergingRequired", _decideHITSMerging)
237
238 # FastCalo
239 scf.addFlag("Sim.FastCalo.ParamsInputFilename", "FastCaloSim/MC23/TFCSparam_AF3_MC23_Sep23.root") # filename of the input parametrizations file
240 scf.addFlag("Sim.FastCalo.RunOnGPU", False) # Determines if run the FastCaloSim on GPU or not
241 scf.addFlag("Sim.FastCalo.CaloCellsName", "AllCalo") # StoreGate collection name for FastCaloSim hits
242 scf.addFlag("Sim.FastCalo.doPunchThrough", lambda prevFlags:
243 prevFlags.Sim.LArParameterization is LArParameterization.FastCaloSim)
244
245 # FastChain
246 # Setting the BCID for Out-of-Time PU events, list of int
247 scf.addFlag("Sim.FastChain.BCID", [1])
248 # weights for Out-of-Time PU events
249 scf.addFlag("Sim.FastChain.PUWeights_lar_em", [1.0]) # LAr EM
250 scf.addFlag("Sim.FastChain.PUWeights_lar_hec", [1.0]) # LAr HEC
251 scf.addFlag("Sim.FastChain.PUWeights_lar_bapre", [1.0]) # LAr Barrel presampler
252 scf.addFlag("Sim.FastChain.PUWeights_tile", [1.0]) # Tile
253
254 # Fatras
255 scf.addFlag("Sim.Fatras.RandomStreamName", "FatrasRnd")
256 scf.addFlag("Sim.Fatras.G4RandomStreamName", "FatrasG4")
257 scf.addFlag("Sim.Fatras.TrkExRandomStreamName", "TrkExRnd")
258 # Fatras fine tuning
259 scf.addFlag("Sim.Fatras.MomCutOffSec", 50.) # common momentum cut-off for secondaries
260 scf.addFlag("Sim.Fatras.HadronIntProb", 1.) # hadronic interaction scale factor
261 scf.addFlag("Sim.Fatras.GaussianMixtureModel", True) # use Gaussian mixture model for Multiple Scattering
262 scf.addFlag("Sim.Fatras.BetheHeitlerScale", 1.) # scale to Bethe-Heitler contribution
263
264 scf.addFlag("Sim.BeamPipeCut", 100.0)
265 scf.addFlag("Sim.TightMuonStepping", False)
266
267 scf.addFlag('Sim.GenerationConfiguration', 'NONE') # TODO replace this property with something more central for all Generator configuration
268
269 return scf
270
271
272def simulationRunArgsToFlags(runArgs, flags):
273 """Fill simulation configuration flags from run arguments."""
274 if hasattr(runArgs, "DataRunNumber"):
275 flags.Input.RunNumbers = [runArgs.DataRunNumber]
276 flags.Input.OverrideRunNumber = True
277 flags.Input.LumiBlockNumbers = [1] # dummy value
278
279 if hasattr(runArgs, "jobNumber"):
280 flags.Input.JobNumber = runArgs.jobNumber
281
282 if hasattr(runArgs, "physicsList"):
283 flags.Sim.PhysicsList = runArgs.physicsList
284
285 if hasattr(runArgs, "truthStrategy"):
286 flags.Sim.TruthStrategy = TruthStrategy(runArgs.truthStrategy)
287
288 if hasattr(runArgs, "useG4Workers"):
289 flags.Sim.UseG4Workers = runArgs.useG4Workers
290
291 # Not used as deprecated
292 # '--enableLooperKiller'
293 # '--perfmon'
294 # '--randomSeed'
295 # '--useISF'
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition hcg.cxx:132
simulationRunArgsToFlags(runArgs, flags)