Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:14:22

0001 """Helper object for SD Actions
0002 """
0003 
0004 from DDSim.Helper.ConfigHelper import ConfigHelper
0005 
0006 
0007 class Action(ConfigHelper):
0008   """Helper holding sensitive detector and other actions.
0009 
0010   The default tracker and calorimeter sensitive actions can be set with
0011 
0012   >>> SIM = DD4hepSimulation()
0013   >>> SIM.action.tracker=('Geant4TrackerWeightedAction', {'HitPositionCombination': 2, 'CollectSingleDeposits': False})
0014   >>> SIM.action.calo = "Geant4CalorimeterAction"
0015 
0016   The default sensitive actions for calorimeters and trackers are applied based on the sensitive type.
0017   The list of sensitive types can be changed with
0018 
0019   >>> SIM = DD4hepSimulation()
0020   >>> SIM.action.trackerSDTypes = ['tracker', 'myTrackerSensType']
0021   >>> SIM.calor.calorimeterSDTypes = ['calorimeter', 'myCaloSensType']
0022 
0023   For specific subdetectors specific sensitive detectors can be set based on patterns in the name of the subdetector.
0024 
0025   >>> SIM = DD4hepSimulation()
0026   >>> SIM.action.mapActions['tpc'] = "TPCSDAction"
0027 
0028   and additional parameters for the sensitive detectors can be set when the map is given a tuple
0029 
0030   >>> SIM = DD4hepSimulation()
0031   >>> SIM.action.mapActions['ecal'] =( "CaloPreShowerSDAction", {"FirstLayerNumber": 1} )
0032 
0033   Additional actions can be set as well with the following syntax variations:
0034 
0035   >>> SIM = DD4hepSimulation()
0036   # single action by name only:
0037   >>> SIM.action.run = "Geant4TestRunAction"
0038   # multiple actions with comma-separated names:
0039   >>> SIM.action.event = "Geant4TestEventAction/Action0,Geant4TestEventAction/Action1"
0040   # single action by tuple of name and parameter dict:
0041   >>> SIM.action.track = ( "Geant4TestTrackAction", {"Property_int": 10} )
0042   # single action by dict of name and parameter dict:
0043   >>> SIM.action.step = { "name": "Geant4TestStepAction", "parameter": {"Property_int": 10} }
0044   # multiple actions by list of dict of name and parameter dict:
0045   >>> SIM.action.stack = [ { "name": "Geant4TestStackAction", "parameter": {"Property_int": 10} } ]
0046 
0047 On the command line or in python, these actions can be specified as JSON strings:
0048   $ ddsim --action.stack '{ "name": "Geant4TestStackAction", "parameter": { "Property_int": 10 } }'
0049 or
0050   >>> SIM.action.stack = '''
0051   {
0052     "name": "Geant4TestStackAction",
0053     "parameter": {
0054       "Property_int": 10,
0055       "Property_double": "1.0*mm"
0056     }
0057   }
0058   '''
0059 
0060   """
0061 
0062   def __init__(self):
0063     super(Action, self).__init__()
0064     self._tracker = ('Geant4TrackerWeightedAction', {'HitPositionCombination': 2, 'CollectSingleDeposits': False})
0065     self._calo = 'Geant4ScintillatorCalorimeterAction'
0066     self._mapActions = dict()
0067     self._trackerSDTypes = ['tracker']
0068     self._calorimeterSDTypes = ['calorimeter']
0069     self._run = []
0070     self._run_EXTRA = {"action": "append"}
0071     self._event = []
0072     self._event_EXTRA = {"action": "append"}
0073     self._track = []
0074     self._track_EXTRA = {"action": "append"}
0075     self._step = []
0076     self._step_EXTRA = {"action": "append"}
0077     self._stack = []
0078     self._stack_EXTRA = {"action": "append"}
0079     self._closeProperties()
0080 
0081   @property
0082   def tracker(self):
0083     """ set the default tracker action """
0084     return self._tracker
0085 
0086   @tracker.setter
0087   def tracker(self, val):
0088     self._tracker = val
0089 
0090   @property
0091   def calo(self):
0092     """ set the default calorimeter action """
0093     return self._calo
0094 
0095   @calo.setter
0096   def calo(self, val):
0097     self._calo = val
0098 
0099   @property
0100   def mapActions(self):
0101     """Create a map of patterns and actions to be applied to sensitive detectors.
0102 
0103     Example: if the name of the detector matches 'tpc' the TPCSDAction is used.
0104 
0105       SIM.action.mapActions['tpc'] = "TPCSDAction"
0106     """
0107     return self._mapActions
0108 
0109   @mapActions.setter
0110   def mapActions(self, val):
0111     """check if the argument is a dict, then we just update mapActions
0112     if it is a string or list, we use pairs as patterns --> Action
0113     """
0114     if isinstance(val, dict):
0115       self._mapActions.update(val)
0116       return
0117 
0118     if isinstance(val, str):
0119       vals = val.split(" ")
0120     elif isinstance(val, list):
0121       vals = val
0122     if len(vals) % 2 != 0:
0123       raise RuntimeError("Not enough parameters for mapActions")
0124     for index in range(0, len(vals), 2):
0125       self._mapActions[vals[index]] = vals[index + 1]
0126 
0127   def clearMapActions(self):
0128     """empty the mapActions dictionary"""
0129     self._mapActions = dict()
0130 
0131   @property
0132   def trackerSDTypes(self):
0133     """List of patterns matching sensitive detectors of type Tracker."""
0134     return self._trackerSDTypes
0135 
0136   @trackerSDTypes.setter
0137   def trackerSDTypes(self, val):
0138     self._trackerSDTypes = ConfigHelper.makeList(val)
0139 
0140   @property
0141   def calorimeterSDTypes(self):
0142     """List of patterns matching sensitive detectors of type Calorimeter."""
0143     return self._calorimeterSDTypes
0144 
0145   @calorimeterSDTypes.setter
0146   def calorimeterSDTypes(self, val):
0147     self._calorimeterSDTypes = ConfigHelper.makeList(val)
0148 
0149   @staticmethod
0150   def makeListOfDictFromJSON(val):
0151     if isinstance(val, str):
0152       # assumes: valid JSON string or comma-separated list of names
0153       import json
0154       try:
0155         val = json.loads(val)
0156         # interpret json structure
0157         return Action.makeListOfDictFromJSON(val)
0158       except ValueError:
0159         # returns: [ { "name": "Geant4TestEventAction" } ]
0160         return [dict(name=v) for v in val.split(",")]
0161     if isinstance(val, tuple):
0162       # assumes: ( "Geant4TestEventAction", {"Property_int": 10} )
0163       # returns: [ { "name": "Geant4TestEventAction", "parameter": {"Property_int": 10} } ]
0164       # note: not able to be specified as json which only allows a list
0165       return [dict(name=val[0], parameter=val[1])]
0166     if isinstance(val, dict):
0167       # assumes: { "name": "Geant4TestEventAction", "parameter": {"Property_int": 10} }
0168       # returns: [ { "name": "Geant4TestEventAction", "parameter": {"Property_int": 10} } ]
0169       return [val]
0170     if isinstance(val, list):
0171       # interpret each list entry into a list and concatenate
0172       return [i for v in val for i in Action.makeListOfDictFromJSON(v)]
0173     raise RuntimeError("Commandline setting of action is not successful for: %s " % val)
0174 
0175   @property
0176   def run(self):
0177     """ set the default run action """
0178     return self._run
0179 
0180   @run.setter
0181   def run(self, val):
0182     for action in Action.makeListOfDictFromJSON(val):
0183       if action not in self._run:
0184         self._run.append(action)
0185 
0186   @property
0187   def event(self):
0188     """ set the default event action """
0189     return self._event
0190 
0191   @event.setter
0192   def event(self, val):
0193     for action in Action.makeListOfDictFromJSON(val):
0194       if action not in self._event:
0195         self._event.append(action)
0196 
0197   @property
0198   def track(self):
0199     """ set the default track action """
0200     return self._track
0201 
0202   @track.setter
0203   def track(self, val):
0204     for action in Action.makeListOfDictFromJSON(val):
0205       if action not in self._track:
0206         self._track.append(action)
0207 
0208   @property
0209   def step(self):
0210     """ set the default step action """
0211     return self._step
0212 
0213   @step.setter
0214   def step(self, val):
0215     for action in Action.makeListOfDictFromJSON(val):
0216       if action not in self._step:
0217         self._step.append(action)
0218 
0219   @property
0220   def stack(self):
0221     """ set the default stack action """
0222     return self._stack
0223 
0224   @stack.setter
0225   def stack(self, val):
0226     for action in Action.makeListOfDictFromJSON(val):
0227       if action not in self._stack:
0228         self._stack.append(action)