ATLAS Offline Software
SimConfigFlags.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.AthConfigFlags import AthConfigFlags, isGaudiEnv
4 from AthenaConfiguration.AutoConfigFlags import GetFileMD
5 from AthenaConfiguration.Enums import BeamType, LHCPeriod
6 from SimulationConfig.SimEnums import BeamPipeSimMode, CalibrationRun, CavernBackground, \
7  LArParameterization, SimulationFlavour, TruthStrategy, VertexSource
8 from 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 
82  # Do full simulation + digitisation + reconstruction chain
83  scf.addFlag("Sim.DoFullChain", False)
84 
85  def _check_G4_version(prevFlags):
86  # Determine the Geant4 version which will be used by the
87  # configuration. In jobs where we are running simulation,
88  # then the G4Version should reflect the version in the
89  # release, so the version in environment should take
90  # precedence over any input file metadata. In jobs where
91  # simulation is not run, then the G4Version from the input
92  # file metadata should take precedence.
93  version = ""
94  from AthenaConfiguration.Enums import ProductionStep
95  if prevFlags.Common.ProductionStep not in [ProductionStep.Simulation, ProductionStep.FastChain]:
96  if prevFlags.Input.Files:
97  version = GetFileMD(prevFlags.Input.Files).get("G4Version", "")
98  if not version:
99  from os import environ
100  version = str(environ.get("G4VERS", ""))
101  if prevFlags.Input.isMC and isGaudiEnv() and not version:
102  raise ValueError("Unknown G4 version")
103  return version
104 
105  scf.addFlag("Sim.G4Version", _check_G4_version)
106 
107  def _checkPhysicsListConf(prevFlags):
108  physicsList = "FTFP_BERT_ATL"
109  if prevFlags.Input.Files:
110  physicsList = GetFileMD(prevFlags.Input.Files).get("PhysicsList", "")
111  if not physicsList:
112  # Currently physicsList is also part of /Digitization/Parameters metadata. TODO migrate away from this.
113  physicsList = GetFileMD(prevFlags.Input.Files).get("physicsList", "FTFP_BERT_ATL")
114  return physicsList
115 
116  scf.addFlag("Sim.PhysicsList", _checkPhysicsListConf)
117  scf.addFlag("Sim.NeutronTimeCut", 150.) # Sets the value for the neutron out of time cut in G4
118  scf.addFlag("Sim.NeutronEnergyCut", -1.) # Sets the value for the neutron energy cut in G4
119  scf.addFlag("Sim.ApplyEMCuts", False) # Turns on the G4 option to apply cuts for EM physics
120  scf.addFlag("Sim.MuonFieldOnlyInCalo", False) # Only muons see the B-field in the calo
121 
122  # G4AtlasToolsConfig
123  scf.addFlag("Sim.RecordStepInfo", False)
124  scf.addFlag("Sim.StoppedParticleFile", "")
125  scf.addFlag("Sim.BeamPipeSimMode", BeamPipeSimMode.Normal, type=BeamPipeSimMode)
126  scf.addFlag("Sim.LArParameterization", LArParameterization.NoFrozenShowers, type=LArParameterization)
127  # TRT Range cut used in simulation in mm. Should be 0.05 or 30.
128  scf.addFlag("Sim.TRTRangeCut",
129  lambda prevFlags: float(GetFileMD(prevFlags.Input.Files).get('TRTRangeCut', 30.0)))
130 
131  # BeameffectsAlg
132  scf.addFlag("Sim.VertexSource", VertexSource.CondDB, type=VertexSource)
133  scf.addFlag("Sim.VertexTimeSmearing", lambda prevFlags:
134  prevFlags.Beam.Type == BeamType.Collisions and prevFlags.GeoModel.Run >= LHCPeriod.Run4)
135 
136  def _checkVertexTimeWidth(prevFlags):
137  default = 0.175*ns
138  vertexTimeWidth = default
139  if prevFlags.Input.Files:
140  vertexTimeWidth = GetFileMD(prevFlags.Input.Files).get("VertexTimeWidth", default)
141  return vertexTimeWidth
142 
143  scf.addFlag("Sim.VertexTimeWidth", _checkVertexTimeWidth)
144 
145  # G4UserActions
146  scf.addFlag("Sim.NRRThreshold", False)
147  scf.addFlag("Sim.NRRWeight", False)
148  scf.addFlag("Sim.PRRThreshold", False)
149  scf.addFlag("Sim.PRRWeight", False)
150  scf.addFlag("Sim.OptionalUserActionList", [])
151 
152  # G4FieldConfig
153  scf.addFlag("Sim.G4Stepper", "AtlasRK4")
154  scf.addFlag("Sim.G4EquationOfMotion", "")
155  scf.addFlag("Sim.UsingGeant4", True)
156 
157  # Cosmics
158  # volume(s) used to do cosmics filtering
159  # G4 volume names from {"Muon", "Calo", "InnerDetector", "TRT_Barrel", "TRT_EC", "SCT_Barrel", "Pixel"}
160  scf.addFlag("Sim.CosmicFilterVolumeNames", ["InnerDetector"])
161  scf.addFlag("Sim.CosmicFilterID", False) # PDG ID to be filtered ("13")
162  scf.addFlag("Sim.CosmicFilterPTmin", False) # min pT filtered in cosmics processing (MeV) ("5000")
163  scf.addFlag("Sim.CosmicFilterPTmax", False) # max pT filtered in cosmics processing (MeV) ("6000")
164  scf.addFlag("Sim.CosmicPtSlice", "Off") # 'slice1', 'slice2', 'slice3', 'slice4', 'NONE'
165 
166  # ISF
167  scf.addFlag("Sim.ISFRun", False)
168 
169  def _checkSimulationFlavour(prevFlags):
170  simulator = SimulationFlavour.Unknown
171  if prevFlags.Input.Files:
172  simFlavour = GetFileMD(prevFlags.Input.Files).get("Simulator", "")
173  if not simFlavour:
174  simFlavour = GetFileMD(prevFlags.Input.Files).get("SimulationFlavour", "")
175  try:
176  simulator = SimulationFlavour(simFlavour)
177  except ValueError:
178  # Deal with old non-thread-safe simulators
179  if simFlavour in ['default']: # This is the case when ISF was not configured in sim
180  simulator = SimulationFlavour.AtlasG4
181  elif simFlavour in ['MC12G4', 'FullG4']:
182  simulator = SimulationFlavour.FullG4MT
183  elif simFlavour in ['FullG4_QS', 'FullG4_LongLived']:
184  simulator = SimulationFlavour.FullG4MT_QS
185  elif simFlavour in ['PassBackG4']:
186  simulator = SimulationFlavour.PassBackG4MT
187  elif simFlavour in ['ATLFASTII']:
188  simulator = SimulationFlavour.ATLFASTIIMT
189  elif simFlavour in ['ATLFASTIIF']:
190  simulator = SimulationFlavour.ATLFASTIIFMT
191  elif simFlavour in ['ATLFAST3']:
192  simulator = SimulationFlavour.ATLFAST3MT
193  elif simFlavour in ['ATLFAST3_QS']:
194  simulator = SimulationFlavour.ATLFAST3MT_QS
195  else:
196  # Obscure old-style configuration used - do not try to interpret
197  simulator = SimulationFlavour.Unknown
198  return simulator
199 
200  scf.addFlag("Sim.ISF.Simulator", _checkSimulationFlavour, type=SimulationFlavour)
201  scf.addFlag("Sim.ISF.DoTimeMonitoring", True) # bool: run time monitoring
202  scf.addFlag("Sim.ISF.DoMemoryMonitoring", True) # bool: run time monitoring
203  scf.addFlag("Sim.ISF.ValidationMode", False) # bool: run ISF internal validation checks
204  scf.addFlag("Sim.ISF.ReSimulation", False) # Using ReSimulation workflow
205  scf.addFlag("Sim.ISF.UseTrackingGeometryCond", False) # Using Condition for tracking Geometry
206 
207  def _decideHITSMerging(prevFlags):
208  # Further specialization possible in future
209  if prevFlags.Sim.ISF.Simulator.isFullSim() and prevFlags.Sim.LArParameterization!=LArParameterization.FastCaloSim:
210  doID = False
211  doITk = False
212  doCALO = False
213  doMUON = False
214  elif prevFlags.Sim.ISF.Simulator.usesFatras() and prevFlags.Sim.ISF.Simulator.usesFastCaloSim():
215  doID = True
216  doITk = True
217  doCALO = True
218  doMUON = True
219  elif prevFlags.Sim.ISF.Simulator.usesFastCaloSim() or prevFlags.Sim.LArParameterization is LArParameterization.FastCaloSim:
220  doID = False
221  doITk = False
222  doCALO = True
223  doMUON = False
224  elif prevFlags.Sim.ISF.Simulator in [SimulationFlavour.Unknown]:
225  doID = True
226  doITk = True
227  doCALO = True
228  doMUON = True
229  else:
230  raise ValueError("Invalid simulator")
231  return {"ID": doID, "CALO": doCALO, "MUON": doMUON, "ITk": doITk}
232 
233  scf.addFlag("Sim.ISF.HITSMergingRequired", _decideHITSMerging)
234 
235  scf.addFlag("Sim.FastCalo.ParamsInputFilename", "FastCaloSim/MC23/TFCSparam_AF3_MC23_Sep23.root") # filename of the input parametrizations file
236  scf.addFlag("Sim.FastCalo.RunOnGPU", False) # Determines if run the FastCaloSim on GPU or not
237  scf.addFlag("Sim.FastCalo.CaloCellsName", "AllCalo") # StoreGate collection name for FastCaloSim hits
238  scf.addFlag("Sim.FastCalo.doEMECFCS", False) # Run FastCaloSim in the EMEC only during full sim jobs
239 
240  # FastChain
241  # Setting the BCID for Out-of-Time PU events, list of int
242  scf.addFlag("Sim.FastChain.BCID", [1])
243  # weights for Out-of-Time PU events
244  scf.addFlag("Sim.FastChain.PUWeights_lar_em", [1.0]) # LAr EM
245  scf.addFlag("Sim.FastChain.PUWeights_lar_hec", [1.0]) # LAr HEC
246  scf.addFlag("Sim.FastChain.PUWeights_lar_bapre", [1.0]) # LAr Barrel presampler
247  scf.addFlag("Sim.FastChain.PUWeights_tile", [1.0]) # Tile
248 
249  # Fatras
250  scf.addFlag("Sim.Fatras.RandomStreamName", "FatrasRnd")
251  scf.addFlag("Sim.Fatras.G4RandomStreamName", "FatrasG4")
252  scf.addFlag("Sim.Fatras.TrkExRandomStreamName", "TrkExRnd")
253  # Fatras fine tuning
254  scf.addFlag("Sim.Fatras.MomCutOffSec", 50.) # common momentum cut-off for secondaries
255  scf.addFlag("Sim.Fatras.HadronIntProb", 1.) # hadronic interaction scale factor
256  scf.addFlag("Sim.Fatras.GaussianMixtureModel", True) # use Gaussian mixture model for Multiple Scattering
257  scf.addFlag("Sim.Fatras.BetheHeitlerScale", 1.) # scale to Bethe-Heitler contribution
258 
259  scf.addFlag("Sim.BeamPipeCut", 100.0)
260  scf.addFlag("Sim.TightMuonStepping", False)
261 
262  scf.addFlag('Sim.GenerationConfiguration', 'NONE') # TODO replace this property with something more central for all Generator configuration
263 
264  return scf
265 
266 
267 def simulationRunArgsToFlags(runArgs, flags):
268  """Fill simulation configuration flags from run arguments."""
269  if hasattr(runArgs, "DataRunNumber"):
270  flags.Input.RunNumbers = [runArgs.DataRunNumber]
271  flags.Input.OverrideRunNumber = True
272  flags.Input.LumiBlockNumbers = [1] # dummy value
273 
274  if hasattr(runArgs, "jobNumber"):
275  flags.Input.JobNumber = runArgs.jobNumber
276 
277  if hasattr(runArgs, "physicsList"):
278  flags.Sim.PhysicsList = runArgs.physicsList
279 
280  if hasattr(runArgs, "truthStrategy"):
281  flags.Sim.TruthStrategy = TruthStrategy(runArgs.truthStrategy)
282 
283  # Not used as deprecated
284  # '--enableLooperKiller'
285  # '--perfmon'
286  # '--randomSeed'
287  # '--useISF'
python.AutoConfigFlags.GetFileMD
def GetFileMD(filenames, allowEmpty=True, maxLevel='peeker')
Definition: AutoConfigFlags.py:65
SystemOfUnits
python.SimConfigFlags.createSimConfigFlags
def createSimConfigFlags()
Definition: SimConfigFlags.py:12
python.AthConfigFlags.isGaudiEnv
def isGaudiEnv()
Definition: AthConfigFlags.py:14
python.SimConfigFlags.simulationRunArgsToFlags
def simulationRunArgsToFlags(runArgs, flags)
Definition: SimConfigFlags.py:267
get
T * get(TKey *tobj)
get a TObject* from a TKey* (why can't a TObject be a TKey?)
Definition: hcg.cxx:127
str
Definition: BTagTrackIpAccessor.cxx:11
readCCLHist.float
float
Definition: readCCLHist.py:83