Source code for Gauss.Simulation

###############################################################################
# (c) Copyright 2000-2020 CERN for the benefit of the LHCb Collaboration      #
#                                                                             #
# This software is distributed under the terms of the GNU General Public      #
# Licence version 3 (GPL Version 3), copied verbatim in the file "COPYING".   #
#                                                                             #
# In applying this licence, CERN does not waive the privileges and immunities #
# granted to it by virtue of its status as an Intergovernmental Organization  #
# or submit itself to any jurisdiction.                                       #
###############################################################################
__author__ = "Gloria Corti, Dominik Muller, and Michal Mazurek"
__email__ = "lhcb-simulation@cern.ch"

from Gaudi.Configuration import log
from GaudiKernel import SystemOfUnits
from Gauss.Defaults import DEFAULT_DETECTORS
from Gaussino.Simulation import GaussinoSimulation

# Configurables
from Gaussino.Utilities import GaussinoConfigurable


[docs]class GaussSimulation(GaussinoConfigurable): __required_configurables__ = [ "Gauss", ] __slots__ = { "EM": "Opt2", "Hadron": "FTFP_BERT", "GeneralPhys": True, "LHCbPhys": False, # FIXME: not implemented yet "Other": "", "DeltaRays": True, "RichUpgradeConfig": False, # FIXME: not implemented yet "AddPhysConstr": [], "CustomSimulation": "", "G4BeginRunCommand": ["/tracking/verbose 0", "/process/eLoss/verbose 0"], "G4EndRunCommand": [], } GAUSSINO_SIMULATION_OPTIONS = [ "CustomSimulation", "G4BeginRunCommand", "G4EndRunCommand", ] _em_physics_options = { "Opt1": ("G4EmStandardPhysics_option1", "EmOpt1Physics"), "Opt2": ("G4EmStandardPhysics_option2", "EmOpt2Physics"), "Opt3": ("G4EmStandardPhysics_option3", "EmOpt3Physics"), "Std": ("G4EmStandardPhysics", "EmPhysics"), "NoCuts": ("G4EmStandardPhysics_option1NoApplyCuts", "EmOpt1NoCutsPhysics"), } _hadron_physics_options = { "QGSP_BERT": [ ("G4HadronElasticPhysics", "ElasticPhysics"), ("G4HadronPhysicsQGSP_BERT", "QGSP_BERTPhysics"), ("G4StoppingPhysics", "StoppingPhysics"), ("G4NeutronTrackingCut", "NeutronTrkCut"), ], "QGSP_BERT_HP": [ ("G4HadronElasticPhysicsHP", "ElasticPhysicsHP"), ("G4HadronPhysicsQGSP_BERT_HP", "QGSP_BERT_HPPhysics"), ("G4StoppingPhysics", "StoppingPhysics"), ], "QGSP_FTFP_BERT": [ ("G4HadronElasticPhysics", "ElasticPhysics"), ("G4HadronPhysicsQGSP_FTFP_BERT", "QGSP_FTFP_BERTPhysics"), ("G4StoppingPhysics", "StoppingPhysics"), ("G4NeutronTrackingCut", "NeutronTrkCut"), ], "FTFP_BERT": [ ("G4HadronElasticPhysics", "ElasticPhysics"), ("G4HadronPhysicsFTFP_BERT", "FTFP_BERTPhysics"), ("G4StoppingPhysics", "StoppingPhysics"), ("G4NeutronTrackingCut", "NeutronTrkCut"), ], "FTFP_BERT_HP": [ ("G4HadronElasticPhysicsHP", "ElasticPhysicsHP"), ("G4HadronPhysicsFTFP_BERT_HP", "FTFP_BERT_HPPhysics"), ("G4StoppingPhysics", "StoppingPhysics"), ], } # internal options to be set by Gauss run1or2 = False only_generation_phase = False
[docs] def _add_constructor(self, sim, template, name): sim.PhysicsConstructors.append("GiGaMT_{}/{}".format(template, name))
[docs] def __apply_configuration__(self): log.debug("Configuring GaussSimulation") if GaussSimulation.only_generation_phase: log.debug("-> Only the generation phase, skipping.") return sim = GaussinoSimulation() self.propagateProperties( self.GAUSSINO_SIMULATION_OPTIONS, sim, ) self._set_production_cuts(sim) self._update_truth_flagging() # set up the physics list sim.PhysicsConstructors += self.getProp("AddPhysConstr") self._add_em_physics(sim) self._add_gen_physics(sim) self._add_hadron_physics(sim) self._add_lhcb_physics(sim) self._add_other_physics(sim) self._add_tracking_cuts(sim)
[docs] def _set_production_cuts(self, sim): # FIXME: to be passed as dictionary # see: https://gitlab.cern.ch/Gaussino/Gaussino/-/issues/27 ecut = 5.0 * SystemOfUnits.mm if not self.getProp("DeltaRays"): ecut = 10000.0 * SystemOfUnits.m sim.CutForElectron = ecut sim.CutForPositron = 5.0 * SystemOfUnits.mm sim.CutForGamma = 5.0 * SystemOfUnits.mm
[docs] def _add_em_physics(self, sim): em = self.getProp("EM") if not em: log.warning("No EM physics defined!") if em not in self._em_physics_options: msg = f"Unknown EM physics '{em}'" log.error(msg) raise NotImplementedError(msg) self._add_constructor(sim, *self._em_physics_options[em])
# FIXME: Not implemented! # if 'LHCb' not in emPhys: # return False # if 'Test' in emPhys: # self._add_constructor(sim, "G4EmStandardPhysics_LHCbTest", # "EmOpt1LHCbPhysics") # else: # self._add_constructor(sim, "G4EmStandardPhysics_option1LHCb", # "EmOpt1LHCbPhysics") # overwrite cuts depending on choice of list # if em == "NoCuts": # sim.EmOpt1LHCbPhysics.ApplyCuts = False # if 'OldForE' in emPhys: # sim.EmOpt1LHCbPhysics.NewModelForE = False
[docs] def _add_gen_physics(self, sim): if not self.getProp("GeneralPhys"): log.warning("The general physics is disabled.") log.debug("Applying general physics") self._add_constructor(sim, "G4DecayPhysics", "DecayPhysics") self._add_constructor(sim, "G4EmExtraPhysics", "EmExtraPhysics") self._add_constructor(sim, "G4IonPhysics", "IonPhysics")
[docs] def _add_hadron_physics(self, sim): hadron_phys = self.getProp("Hadron") if not hadron_phys: log.warning("No hadron physics defined!") return if hadron_phys not in self._hadron_physics_options: msg = f"Unknown hadronic physics '{hadron_phys}'." log.error(msg) raise NotImplementedError(msg) log.debug(f"Applying hadronic physics '{hadron_phys}'.") for hp in self._hadron_physics_options[hadron_phys]: self._add_constructor(sim, *hp)
[docs] def _add_lhcb_physics(self, sim): # FIXME: this is not implmented yet lhcb_phys = self.getProp("LHCbPhys") rich = self.getProp("RichUpgradeConfig") if lhcb_phys or rich: msg = "LHCbPhysics not implemented yet" log.error(msg) raise NotImplementedError(msg) sim.PhysicsConstructors.append("GiGaPhysUnknownParticles")
# FIXME: this is not implmented yet # if lhcbPhys: # log.info("Applying LHCb specific physics.") # if richUpgradeConfig: # self.defineRichMaPmtPhys(sim) # else: # self.defineRichPhys(sim) # else: # log.warning("The lhcb-related physics (RICH processed)" # "is disabled")
[docs] def _add_other_physics(self, sim): other = self.getProp("Other") if not other: return if other == "Higgs": log.debug("Enabling physics processe for Higgs particles") sim.PhysicsConstructors.append("GiGaMTHiggsParticles") msg = "Unknown other physics '{other}'" log.error(msg) raise NotImplementedError(msg)
[docs] def _add_tracking_cuts(self, sim): log.debug("Adding tracking cuts.") from Configurables import TrCutsRunAction sim.addTool(TrCutsRunAction("TrCuts"), name="TrCuts") sim.PhysicsConstructors.append("TrCutsRunAction/TrCuts")
[docs] def _update_truth_flagging(self): from Configurables import TruthFlaggingTrackAction # FIXME: this is set by Gaussino, # it would be better to pass this option # to GaussinoSimulation as a key in dict # see: https://gitlab.cern.ch/Gaussino/Gaussino/-/issues/30 trth = TruthFlaggingTrackAction( "GiGaMT.GiGaActionInitializer.TruthFlaggingTrackAction" ) # new ZMaxPlane settings depend now on the geometry if self.run1or2: # Other -> M1 | ZMax | PRS/SPD | ECAL trth.ZmaxForStoring = 12280.0 * SystemOfUnits.mm else: # Upgrade -> ZMax | Neutron Shielding | ECAL trth.ZmaxForStoring = 11948.0 * SystemOfUnits.mm # tilt of the zMax plane should be the same trth.ZmaxForStoringTilt = 0.207 * SystemOfUnits.degree