Back to home page

EIC code displayed by LXR

 
 

    


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

0001 """Helper object for Filters
0002 
0003 Later the parameter dictionary is used to instantiate the filter object
0004 The default filters are a GeantinoRejector and a 1keV minimum energy cut
0005 
0006 """
0007 from DDSim.Helper.ConfigHelper import ConfigHelper
0008 from g4units import keV
0009 import logging
0010 
0011 logger = logging.getLogger(__name__)
0012 
0013 
0014 class Filter(ConfigHelper):
0015   """Configuration for sensitive detector filters
0016 
0017   Set the default filter for 'tracker'
0018   >>> SIM.filter.tracker = "edep1kev"
0019   Use no filter for 'calorimeter' by default
0020   >>> SIM.filter.calo = ""
0021 
0022   Assign a filter to a sensitive detector via pattern matching
0023   >>> SIM.filter.mapDetFilter['FTD'] = "edep1kev"
0024 
0025   Or more than one filter:
0026   >>> SIM.filter.mapDetFilter['FTD'] = ["edep1kev", "geantino"]
0027 
0028   Don't use the default filter or anything else:
0029   >>> SIM.filter.mapDetFilter['TPC'] = None ## or "" or []
0030 
0031   Create a custom filter. The dictionary is used to instantiate the filter later on
0032   >>> SIM.filter.filters['edep3kev'] = dict(name="EnergyDepositMinimumCut/3keV", parameter={"Cut": 3.0*keV} )
0033 
0034   """
0035 
0036   def __init__(self):
0037     super(Filter, self).__init__()
0038     self._mapDetFilter = {}
0039     self._tracker = "edep1kev"
0040     self._calo = "edep0"
0041     self._filters = {}
0042     self._createDefaultFilters()
0043     self._closeProperties()
0044 
0045   @property
0046   def tracker(self):
0047     """ default filter for tracking sensitive detectors; this is applied if no other filter is used for a tracker"""
0048     return self._tracker
0049 
0050   @tracker.setter
0051   def tracker(self, val):
0052     self._tracker = val
0053 
0054   @property
0055   def calo(self):
0056     """
0057     default filter for calorimeter sensitive detectors;
0058     this is applied if no other filter is used for a calorimeter
0059     """
0060     return self._calo
0061 
0062   @calo.setter
0063   def calo(self, val):
0064     self._calo = val
0065 
0066   @property
0067   def filters(self):
0068     """ list of filter objects: map between name and parameter dictionary """
0069     return self._filters
0070 
0071   @filters.setter
0072   def filters(self, val):
0073     if isinstance(val, dict):
0074       self._filters.update(val)
0075       return
0076     ##
0077     raise RuntimeError("Commandline setting of filters is not supported, use a steeringFile: %s " % val)
0078 
0079   @property
0080   def mapDetFilter(self):
0081     """ a map between patterns and filter objects, using patterns to attach filters to sensitive detector """
0082     return self._mapDetFilter
0083 
0084   @mapDetFilter.setter
0085   def mapDetFilter(self, val):
0086     if isinstance(val, dict):
0087       self._mapDetFilter.update(val)
0088       return
0089 
0090     if isinstance(val, str):
0091       vals = val.split(" ")
0092     elif isinstance(val, list):
0093       vals = val
0094     if len(vals) % 2 != 0:
0095       raise RuntimeError("Not enough parameters for mapDetFilter")
0096     for index in range(0, len(vals), 2):
0097       self._mapDetFilter[vals[index]] = vals[index + 1]
0098 
0099   def resetFilter(self):
0100     """ remove all filters """
0101     self._filters = {}
0102 
0103   def _createDefaultFilters(self):
0104     """ create the map with the default filters """
0105     self.filters["geantino"] = dict(name="GeantinoRejectFilter/GeantinoRejector",
0106                                     parameter={})
0107 
0108     self.filters["edep1kev"] = dict(name="EnergyDepositMinimumCut",
0109                                     parameter={"Cut": 1.0 * keV})
0110 
0111     self.filters["edep0"] = dict(name="EnergyDepositMinimumCut/Cut0",
0112                                  parameter={"Cut": 0.0})
0113 
0114   def __makeMapDetList(self):
0115     """ create the values of the mapDetFilters a list of filters """
0116     for pattern, filters in self._mapDetFilter.items():
0117       self._mapDetFilter[pattern] = ConfigHelper.makeList(filters)
0118 
0119   def setupFilters(self, kernel):
0120     """ attach all filters to the kernel """
0121     import DDG4
0122     setOfFilters = set()
0123 
0124     for name, filt in self.filters.items():
0125       setOfFilters.add(name)
0126       ddFilt = DDG4.Filter(kernel, filt['name'])
0127       for para, value in filt['parameter'].items():
0128         setattr(ddFilt, para, value)
0129       kernel.registerGlobalFilter(ddFilt)
0130       filt['filter'] = ddFilt
0131 
0132     from itertools import chain
0133     listOfFilters = []
0134     for val in self.mapDetFilter.values():
0135       listOfFilters += ConfigHelper.makeList(val)
0136     requestedFilter = set(chain(ConfigHelper.makeList(self.tracker), ConfigHelper.makeList(self.calo), listOfFilters))
0137     logger.info("ReqFilt %s", requestedFilter)
0138     if requestedFilter - setOfFilters:
0139       raise RuntimeError(" Filter(s) '%s' are not registered!" % str(requestedFilter - setOfFilters))
0140 
0141   def applyFilters(self, seq, det, defaultFilter=None):
0142     """apply the filters to to the sensitive detector
0143 
0144     :param seq: sequence object returned when creating sensitive detector
0145     :param det: sensitive detector name
0146     :returns: None
0147     """
0148     self.__makeMapDetList()
0149     foundFilter = False
0150     for pattern, filts in self.mapDetFilter.items():
0151       if pattern.lower() in det.lower():
0152         foundFilter = True
0153         for filt in filts:
0154           logger.info("Adding filter '%s' matched with '%s' to sensitive detector for '%s' " % (filt, pattern, det))
0155           seq.add(self.filters[filt]['filter'])
0156 
0157     if foundFilter:
0158       return
0159     if defaultFilter:
0160       logger.info("Adding default filter '%s' to sensitive detector for '%s' " % (defaultFilter, det))
0161       seq.add(self.filters[defaultFilter]['filter'])
0162       return
0163     logger.info("Not adding any filter to sensitive detector for '%s' " % det)