Source code for Gauss.Configuration

###############################################################################
# (c) Copyright 2000-2022 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 Configurable, log
from GaudiConf.SimConf import SimConf
from GaudiKernel import SystemOfUnits
from Gauss.Generation import GaussGeneration
from Gauss.Geometry import GaussGeometry
from Gauss.Simulation import GaussSimulation
from Gaussino.Configuration import Gaussino

# Configurables (do NOT use 'from Configurables' here)
from Gaussino.Utilities import GaussinoConfigurable
from LHCbAlgs.Configuration import LHCbApp


[docs]class Gauss(GaussinoConfigurable): __used_configurables__ = [ LHCbApp, SimConf, GaussGeneration, GaussSimulation, GaussGeometry, Gaussino, ] __slots__ = { "Histograms": "DEFAULT", "EvtMax": -1, "Phases": ["Generator", "Simulation"], "EnableHive": True, "ThreadPoolSize": 1, "EventSlots": 1, "FirstTimingEvent": 1, "DatasetName": "Gauss", "OutputType": "SIM", "ReDecay": False, "Debug": False, "SpilloverPaths": [], "EnablePack": True, "DataType": "", "WriteFSR": False, "MergeGenFSR": False, "FirstEventNumber": 1, "RunNumber": 1, } # options to be directly propagated to Gaussino GAUSSINO_OPTIONS = [ "Histograms", "EvtMax", "Phases", "EnableHive", "ThreadPoolSize", "EventSlots", "FirstTimingEvent", "DatasetName", "OutputType", "ReDecay", "Debug", "FirstEventNumber", "RunNumber", ] # options to be directly propagated to LHCbApp LHCBAPP_OPTIONS = [ # TODO: investigate this! # I think this should be passed only to Gaussino "EvtMax", "DataType", ] SIMCONF_OPTIONS = [ "SpilloverPaths", "EnablePack", "Phases", "DataType", ] Run1DataTypes = ["2009", "2010", "2011", "2012", "2013"] Run2DataTypes = ["2015", "2016", "2017", "2018"] Run3DataTypes = ["2022", "2023", "2024", "Run3"] Run4DataTypes = ["Run4"] Run5DataTypes = ["Run5"] DataTypes = [ *Run1DataTypes, *Run2DataTypes, *Run3DataTypes, *Run4DataTypes, *Run5DataTypes, ] KNOWN_OUTPUTS = ["NONE", "GEN", "XGEN", "RGEN", "SIM", "XSIM"] def __init__(self, name=Configurable.DefaultName, _enabled=True, **kwargs): # -> the following makes sure that one does not instantiate Gaussino before # Gauss, otherwise the later in the code fix will be ill-formed if "Gaussino" in Configurable.allConfigurables: msg = "Gauss configurable must be instantiated before Gaussino" log.error(msg) raise RuntimeError(msg) # -> this makes the Gaussino configurable LHCbApp-dependent # -> explanation: in some cases different configurables have to be instantiated # with the same name (e.g. HiveWhiteBoard and EventDataSvc); # -> this makes sure that IOHelper via LHCbApp will not set the defaults before # Gaussino.__apply_configuration__ takes place Gaussino.__used_configurables__.append(LHCbApp) # -> end of the fix super(Gauss, self).__init__(name=name, _enabled=_enabled, **kwargs) # Apply the configuration
[docs] def __apply_configuration__(self): self._check_options_compatibility() self._propagate_gaussino() self._propagate_lhcbapp() packing = self._set_packing() self._propagate_sim_conf(packing) self._propagate_simulation() self._set_evtgen() self._define_output(prerequisites=[packing]) for conf in self.__used_configurables__: conf()
[docs] def _check_options_compatibility(self): if not self.getProp("DataType"): msg = "Must have a DataType." log.error(msg) raise ValueError(msg) if self.getProp("DataType") not in self.DataTypes: msg = ( f"Unknown DataType '{self.getProp('DataType')}'. " f"Must be one of: '{self.DataTypes}'" ) log.error(msg) raise ValueError(msg) for conf, props in Configurable.allConfigurables.items(): if conf.startswith("Gaussino") and props._enabled: msg = ( "When using Gauss, you must set " "Gaussino's properties through " "the corresponding configurable " "in Gauss. Setting Gaussino's options " "directly has been disabled." ) log.error(msg) raise RuntimeError(msg)
[docs] def _propagate_gaussino(self): self.propagateProperties(self.GAUSSINO_OPTIONS, Gaussino()) Gaussino().ConvertEDM = True
# FIXME: temporary! we have to wait for an official way of getting ParticleTable.txt # in the meantime, we use the internal ParticleTable.txt in Gaussino # see: https://gitlab.cern.ch/lhcb/LHCb/-/merge_requests/3510#note_5530125 # # Gaussino().ParticleTable = 'git:///param/ParticleTable.txt'
[docs] def _propagate_lhcbapp(self): self.propagateProperties(self.LHCBAPP_OPTIONS, LHCbApp()) LHCbApp( Simulation=True, # do not turn hive mode with LHCbApp # this is now done in Gaussino() in _setup_hive() EnableHive=False, )
[docs] def _set_packing(self): from Configurables import GaudiSequencer return GaudiSequencer("PackingSeq", Sequential=True, IgnoreFilterPassed=True)
[docs] def _propagate_sim_conf(self, packing): # Propagate properties to SimConf SimConf().setProp("Writer", "GaussTape") self.propagateProperties(self.SIMCONF_OPTIONS, SimConf()) # Empty the list of detectors, it is later populated when configuring # the subdetectors SimConf().Detectors = [] # if we have post-sim filters, we only want to write if the filter is # passed # if self.getProp("PostSimFilters"): # OutputStream("GaussTape").RequireAlgs.append("PostSimFilterSeq") # Don't want SIM data unpacking enabled in DoD service SimConf().EnableUnpack = False SimConf().SaveHepMC = False phases = self.getProp("Phases") if "GenToMCTree" in phases or "Simulation" in phases: for so in self.defineCrossingList(): SimConf().PackingSequencers[so] = packing
[docs] def defineCrossingList(self): crossingList = [""] spillOverList = self.getProp("SpilloverPaths") while "" in spillOverList: spillOverList.remove("") crossingList += spillOverList return crossingList
[docs] def _define_output(self, prerequisites): """ Set up output stream according to phase processed, the spill-over slots and the type of output """ output = self.getProp("OutputType").upper() if output == "NONE": log.warning("No event data output produced") return simWriter = SimConf().writer() # define default file extensions depending on the phase that has been # run fileDefaultExtension = ".gen" fileAllowedExtension = [fileDefaultExtension] if "GenToMCTree" in self.getProp("Phases"): fileDefaultExtension = ".xgen" fileAllowedExtension = [fileDefaultExtension, ".rgen"] elif "Simulation" in self.getProp("Phases"): fileDefaultExtension = ".sim" fileAllowedExtension = [fileDefaultExtension, ".xsim"] # choose the file extension from the one selected compatibly with the # phase run if output not in self.KNOWN_OUTPUTS: log.warning( "OutputType not supported. " f"Use default for chosen phases: {fileDefaultExtension}" ) fileExtension = "." + output.lower() if fileExtension not in fileAllowedExtension: fileExtension = fileDefaultExtension log.warning( "OutputType not supported " f"for this phase. Use default: {fileExtension}" ) # set saving or not of HepMC depending on chosen file extension if SimConf().isPropertySet("SaveHepMC"): log.warning("SimConf().SaveHepMC will " "be ignored. Value set by Gauss()") saveHepMC = False if fileExtension in [".gen", ".xgen", ".xsim"]: saveHepMC = True SimConf().setProp("SaveHepMC", saveHepMC) outputFile = "" from GaudiConf import IOHelper if simWriter.isPropertySet("Output"): outputFile = IOHelper().undressFile(simWriter.getProp("Output")) else: outputFile = Gaussino()._get_output_name() + fileExtension # Merge genFSRs if self.getProp("WriteFSR"): seqGenFSR = GaudiSequencer("GenFSRSeq") ApplicationMgr().TopAlg += [seqGenFSR] if self.getProp("MergeGenFSR"): seqGenFSR.Members += ["GenFSRMerge"] IOHelper().outStream(outputFile, simWriter, self.getProp("WriteFSR")) from Configurables import FileCatalog if not FileCatalog().isPropertySet("Catalogs"): FileCatalog().Catalogs = ["xmlcatalog_file:NewCatalog.xml"] edm_algos = Gaussino.edm_algorithms(self.getProp("ReDecay")) members = edm_algos + prerequisites + [SimConf().writer()] from Configurables import GaudiSequencer output_seq = GaudiSequencer( "OutputSeq", Members=members, Sequential=True, ) from Configurables import ApplicationMgr ApplicationMgr().TopAlg.append(output_seq)
[docs] def _propagate_simulation(self): if "Simulation" not in self.getProp("Phases"): GaussSimulation.only_generation_phase = True GaussGeometry.only_generation_phase = True return run1or2 = self.getProp("DataType") in self.Run1DataTypes + self.Run2DataTypes GaussGeometry.run1or2 = run1or2 GaussGeometry.run4or5 = ( self.getProp("DataType") in self.Run4DataTypes + self.Run5DataTypes ) GaussGeometry.datatype = self.getProp("DataType") GaussSimulation.run1or2 = run1or2
[docs] def _set_evtgen(self): from Configurables import EvtGenDecay EvtGenDecay().DecayFile = "$DECFILESROOT/dkfiles/DECAY.DEC"