diff --git a/DDG4/python/DDSim/DD4hepSimulation.py b/DDG4/python/DDSim/DD4hepSimulation.py index f84f7b69c..b0af0d847 100644 --- a/DDG4/python/DDSim/DD4hepSimulation.py +++ b/DDG4/python/DDSim/DD4hepSimulation.py @@ -566,6 +566,7 @@ def __parseAllHelper(self, parsed): self._errorMessages.append("ERROR: %s " % e) if logger.level <= logging.DEBUG: self._errorMessages.append(traceback.format_exc()) + obj._checkProperties() def __checkOutputLevel(self, level): """return outputlevel as int so we don't have to import anything for faster startup""" diff --git a/DDG4/python/DDSim/Helper/Action.py b/DDG4/python/DDSim/Helper/Action.py index 6f9f0bf41..b84c3f70d 100644 --- a/DDG4/python/DDSim/Helper/Action.py +++ b/DDG4/python/DDSim/Helper/Action.py @@ -39,6 +39,7 @@ def __init__(self): self._mapActions = dict() self._trackerSDTypes = ['tracker'] self._calorimeterSDTypes = ['calorimeter'] + self._closeProperties() @property def tracker(self): diff --git a/DDG4/python/DDSim/Helper/ConfigHelper.py b/DDG4/python/DDSim/Helper/ConfigHelper.py index 9bcce56f7..8072ec7e9 100644 --- a/DDG4/python/DDSim/Helper/ConfigHelper.py +++ b/DDG4/python/DDSim/Helper/ConfigHelper.py @@ -16,9 +16,25 @@ class ConfigHelper(object): """Base class for configuration helper""" + # We need a static set of properties, because steeringFile parsing creates new Helper objects! + _setOfProperties = dict() + def __init__(self): pass + def _name(self): + return self.__class__.__name__ + + def _closeProperties(self): + """Store the list of properties.""" + self._setOfProperties[self._name()] = set(vars(self)) + + def _checkProperties(self): + newProps = set(vars(self)) + if existingProps := self._setOfProperties.get(self._name(), set()): + if newProps - existingProps: + raise RuntimeError(f"{self._name()} error: Trying to add unknown propert(y/ies): {newProps - existingProps}!") + def getOptions(self): finalVars = {} diff --git a/DDG4/python/DDSim/Helper/Filter.py b/DDG4/python/DDSim/Helper/Filter.py index 0b967904a..ce7c39317 100644 --- a/DDG4/python/DDSim/Helper/Filter.py +++ b/DDG4/python/DDSim/Helper/Filter.py @@ -40,6 +40,7 @@ def __init__(self): self._calo = "edep0" self._filters = {} self._createDefaultFilters() + self._closeProperties() @property def tracker(self): diff --git a/DDG4/python/DDSim/Helper/Geometry.py b/DDG4/python/DDSim/Helper/Geometry.py index 5718e4002..c7c7e85d2 100644 --- a/DDG4/python/DDSim/Helper/Geometry.py +++ b/DDG4/python/DDSim/Helper/Geometry.py @@ -35,6 +35,7 @@ def __init__(self): self._dumpDGDML_EXTRA = {"help": "If not empty, filename to dump the Geometry as GDML"} self.dumpGDML = "" + self._closeProperties() def constructGeometry(self, kernel, geant4, geoPrintLevel=2, numberOfThreads=1): """Construct Geant4 geometry.""" diff --git a/DDG4/python/DDSim/Helper/GuineaPig.py b/DDG4/python/DDSim/Helper/GuineaPig.py index 1e2d26976..e771c2970 100644 --- a/DDG4/python/DDSim/Helper/GuineaPig.py +++ b/DDG4/python/DDSim/Helper/GuineaPig.py @@ -9,6 +9,7 @@ class GuineaPig(Input): def __init__(self): super(GuineaPig, self).__init__() self._parameters["ParticlesPerEvent"] = -1 + self._closeProperties() @property def particlesPerEvent(self): diff --git a/DDG4/python/DDSim/Helper/Gun.py b/DDG4/python/DDSim/Helper/Gun.py index 8b21d52ea..608b41f7c 100644 --- a/DDG4/python/DDSim/Helper/Gun.py +++ b/DDG4/python/DDSim/Helper/Gun.py @@ -43,6 +43,7 @@ def __init__(self): 'eta', 'pseudorapidity', 'ffbar']} # (1+cos^2 theta) self._distribution = None + self._closeProperties() @property def distribution(self): diff --git a/DDG4/python/DDSim/Helper/HepMC3.py b/DDG4/python/DDSim/Helper/HepMC3.py index 95e360c74..078d36141 100644 --- a/DDG4/python/DDSim/Helper/HepMC3.py +++ b/DDG4/python/DDSim/Helper/HepMC3.py @@ -12,6 +12,7 @@ def __init__(self): self._parameters["Flow2"] = "flow2" # this option will evaluate to True if the HEPMC3 plugin was build self._useHepMC3 = ("@DD4HEP_USE_HEPMC3@" != "OFF") + self._closeProperties() @property def useHepMC3(self): diff --git a/DDG4/python/DDSim/Helper/Input.py b/DDG4/python/DDSim/Helper/Input.py index 8154930ad..82288a63e 100644 --- a/DDG4/python/DDSim/Helper/Input.py +++ b/DDG4/python/DDSim/Helper/Input.py @@ -8,8 +8,8 @@ class Input(ConfigHelper): def __init__(self): super(Input, self).__init__() - self.__parameters = {} + self._closeProperties() def getParameters(self): return self.__parameters diff --git a/DDG4/python/DDSim/Helper/InputConfig.py b/DDG4/python/DDSim/Helper/InputConfig.py index 3392f8c89..375cdc859 100644 --- a/DDG4/python/DDSim/Helper/InputConfig.py +++ b/DDG4/python/DDSim/Helper/InputConfig.py @@ -10,6 +10,7 @@ class InputConfig(ConfigHelper): def __init__(self): super(InputConfig, self).__init__() self._userPlugin = [] + self._closeProperties() @property def userInputPlugin(self): diff --git a/DDG4/python/DDSim/Helper/LCIO.py b/DDG4/python/DDSim/Helper/LCIO.py index 7c0d6e849..79f789153 100644 --- a/DDG4/python/DDSim/Helper/LCIO.py +++ b/DDG4/python/DDSim/Helper/LCIO.py @@ -9,6 +9,7 @@ class LCIO(Input): def __init__(self): super(LCIO, self).__init__() self._parameters["MCParticleCollectionName"] = "MCParticle" + self._closeProperties() @property def mcParticleCollectionName(self): diff --git a/DDG4/python/DDSim/Helper/MagneticField.py b/DDG4/python/DDSim/Helper/MagneticField.py index dff5d51c9..f61bd60c5 100644 --- a/DDG4/python/DDSim/Helper/MagneticField.py +++ b/DDG4/python/DDSim/Helper/MagneticField.py @@ -17,3 +17,4 @@ def __init__(self): self.delta_intersection = 0.001 * mm self.delta_one_step = 0.01 * mm self.largest_step = 10 * m + self._closeProperties() diff --git a/DDG4/python/DDSim/Helper/Meta.py b/DDG4/python/DDSim/Helper/Meta.py index d1a367738..7b1e2f2e9 100644 --- a/DDG4/python/DDSim/Helper/Meta.py +++ b/DDG4/python/DDSim/Helper/Meta.py @@ -27,6 +27,7 @@ def __init__(self): " E.g setting it to 42 will start counting events from 42 instead of 0", 'type': int} self.eventNumberOffset = 0 + # no closeProperties, allow adding arbitrary information to runHeader def parseEventParameters(self): """ diff --git a/DDG4/python/DDSim/Helper/Output.py b/DDG4/python/DDSim/Helper/Output.py index f0ffe32bf..035e353c9 100644 --- a/DDG4/python/DDSim/Helper/Output.py +++ b/DDG4/python/DDSim/Helper/Output.py @@ -52,6 +52,7 @@ def __init__(self): self._geometry_EXTRA = {'choices': OUTPUT_CHOICES, 'type': outputLevelType} self._geometry = outputLevel('DEBUG') + self._closeProperties() @property def inputStage(self): diff --git a/DDG4/python/DDSim/Helper/OutputConfig.py b/DDG4/python/DDSim/Helper/OutputConfig.py index c4d05ea83..f16c12f8b 100644 --- a/DDG4/python/DDSim/Helper/OutputConfig.py +++ b/DDG4/python/DDSim/Helper/OutputConfig.py @@ -26,6 +26,7 @@ def __init__(self): self._forceLCIO = False self._forceEDM4HEP = False self._forceDD4HEP = False + self._closeProperties() def _checkConsistency(self): """Raise error if more than one force flag is true.""" diff --git a/DDG4/python/DDSim/Helper/ParticleHandler.py b/DDG4/python/DDSim/Helper/ParticleHandler.py index fb75d450f..9b7aafe42 100644 --- a/DDG4/python/DDSim/Helper/ParticleHandler.py +++ b/DDG4/python/DDSim/Helper/ParticleHandler.py @@ -19,6 +19,7 @@ def __init__(self): self._minDistToParentVertex = 2.2e-14 * mm self._enableDetailedHitsAndParticleInfo = False self._userParticleHandler = "Geant4TCUserParticleHandler" + self._closeProperties() @property def enableDetailedHitsAndParticleInfo(self): diff --git a/DDG4/python/DDSim/Helper/Physics.py b/DDG4/python/DDSim/Helper/Physics.py index 18bbded1e..ac92bd52d 100644 --- a/DDG4/python/DDSim/Helper/Physics.py +++ b/DDG4/python/DDSim/Helper/Physics.py @@ -27,6 +27,7 @@ def __init__(self): 5101, 5103, 5201, 5203, 5301, 5303, 5401, 5403, 5503} # b? diquarks self._zeroTimePDGs = {11, 13, 15, 17} self._userFunctions = [] + self._closeProperties() @property def rejectPDGs(self): diff --git a/DDG4/python/DDSim/Helper/Random.py b/DDG4/python/DDSim/Helper/Random.py index 363388e6f..5486c0211 100644 --- a/DDG4/python/DDSim/Helper/Random.py +++ b/DDG4/python/DDSim/Helper/Random.py @@ -23,6 +23,7 @@ def __init__(self): "on eventID and runID\nAllows reproducibility even when" "SkippingEvents"} self.enableEventSeed = False + self._closeProperties() def initialize(self, DDG4, kernel, output): """ initialize the random generator diff --git a/DDG4/python/DDSim/Helper/UI.py b/DDG4/python/DDSim/Helper/UI.py index 053cb84f3..d405a444b 100644 --- a/DDG4/python/DDSim/Helper/UI.py +++ b/DDG4/python/DDSim/Helper/UI.py @@ -29,6 +29,7 @@ def __init__(self): self._commandsPostRun = [] self._commandsPreRun = [] self._commandsTerminate = [] + self._closeProperties() @property def commandsConfigure(self):