Back to home page

EIC code displayed by LXR

 
 

    


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

0001 """Helper object for physicslist properties"""
0002 
0003 import os
0004 
0005 from DDSim.Helper.ConfigHelper import ConfigHelper
0006 from g4units import mm
0007 import logging
0008 
0009 logger = logging.getLogger(__name__)
0010 
0011 
0012 class Physics(ConfigHelper):
0013   """Configuration for the PhysicsList and Monte Carlo particle selection."""
0014 
0015   def __init__(self):
0016     super(Physics, self).__init__()
0017     self._rangecut = 0.7 * mm
0018     self._list = "FTFP_BERT"
0019     self._decays = False
0020     self._pdgfile = None
0021     self._rejectPDGs = {1, 2, 3, 4, 5, 6,  # quarks
0022                         21, 23, 24, 25,  # bosons
0023                         1103,  # d? diquarks
0024                         2101, 2103, 2203,  # u? diquarks
0025                         3101, 3103, 3201, 3203, 3303,  # s? diquarks
0026                         4101, 4103, 4201, 4203, 4301, 4303, 4403,  # c? diquarks
0027                         5101, 5103, 5201, 5203, 5301, 5303, 5401, 5403, 5503}  # b? diquarks
0028     self._zeroTimePDGs = {11, 13, 15, 17}
0029     self._alternativeDecayStatuses = set()
0030     self._userFunctions = []
0031     self._closeProperties()
0032     Physics.__doc__ += "\n\n" + self.setupUserPhysics.__doc__
0033 
0034   @property
0035   def rejectPDGs(self):
0036     """Set of PDG IDs that will not be passed from the input record to Geant4.
0037 
0038     Quarks, gluons and W's Z's etc should not be treated by Geant4
0039     """
0040     return self._rejectPDGs
0041 
0042   @rejectPDGs.setter
0043   def rejectPDGs(self, val):
0044     self._rejectPDGs = self.makeSet(val)
0045 
0046   @property
0047   def zeroTimePDGs(self):
0048     """Set of PDG IDs for particles that should not be passed to Geant4 if their properTime is 0.
0049 
0050     The properTime of 0 indicates a documentation to add FSR to a lepton for example.
0051     """
0052     return self._zeroTimePDGs
0053 
0054   @zeroTimePDGs.setter
0055   def zeroTimePDGs(self, val):
0056     self._zeroTimePDGs = self.makeSet(val)
0057 
0058   @property
0059   def alternativeDecayStatuses(self):
0060     """Set of Generator Statuses that are used to mark unstable particles that should decay inside of Geant4.
0061     """
0062     return self._alternativeDecayStatuses
0063 
0064   @alternativeDecayStatuses.setter
0065   def alternativeDecayStatuses(self, val):
0066     self._alternativeDecayStatuses = self.makeSet(val)
0067 
0068   @property
0069   def rangecut(self):
0070     """ The global geant4 rangecut for secondary production
0071 
0072     Default is 0.7 mm as is the case in geant4 10
0073 
0074     To disable this plugin and be absolutely sure to use the Geant4 default range cut use "None"
0075 
0076     Set printlevel to DEBUG to see a printout of all range cuts,
0077     but this only works if range cut is not "None"
0078     """
0079     return self._rangecut
0080 
0081   @rangecut.setter
0082   def rangecut(self, val):
0083     if val is None:
0084       self._rangecut = None
0085       return
0086     if isinstance(val, str):
0087       if val == "None":
0088         self._rangecut = None
0089         return
0090     self._rangecut = val
0091 
0092   @property
0093   def pdgfile(self):
0094     """ location of particle.tbl file containing extra particles and their lifetime information
0095 
0096     For example in $DD4HEP/examples/DDG4/examples/particle.tbl
0097     """
0098     return self._pdgfile
0099 
0100   @pdgfile.setter
0101   def pdgfile(self, val):
0102     if not val:
0103       self._pdgfile = None
0104       return
0105     if not os.path.exists(val):
0106       raise RuntimeError("PDGFile: %s not found" % os.path.abspath(val))
0107     self._pdgfile = os.path.abspath(val)
0108 
0109   @property
0110   def decays(self):
0111     """If true, add decay processes for all particles.
0112 
0113     Only enable when creating a physics list not based on an existing Geant4 list!
0114     """
0115     return self._decays
0116 
0117   @decays.setter
0118   def decays(self, val):
0119     self._decays = val
0120 
0121   @property
0122   def list(self):  # noqa: A003
0123     """The name of the Geant4 Physics list."""
0124     return self._list
0125 
0126   @list.setter
0127   def list(self, val):  # noqa: A003
0128     self._list = val
0129 
0130   def setupPhysics(self, kernel, name=None):
0131     seq = kernel.physicsList()
0132     seq.extends = name if name is not None else self.list
0133     seq.decays = self.decays
0134     seq.enableUI()
0135     seq.dump()
0136 
0137     from DDG4 import PhysicsList
0138 
0139     # Add special particle types from specialized physics constructor
0140     if self.pdgfile:
0141       seq = kernel.physicsList()
0142       part = PhysicsList(kernel, 'Geant4ExtraParticles/ExtraParticles')
0143       part.enableUI()
0144       seq.adopt(part)
0145       part.pdgfile = self.pdgfile
0146 
0147     # Add global range cut
0148     if self.rangecut is not None:
0149       seq = kernel.physicsList()
0150       rg = PhysicsList(kernel, 'Geant4DefaultRangeCut/GlobalRangeCut')
0151       rg.enableUI()
0152       seq.adopt(rg)
0153       rg.RangeCut = self.rangecut
0154 
0155     for func in self._userFunctions:
0156       try:
0157         func(kernel)
0158       except Exception as e:
0159         logger.error("Exception in UserFunction: %r", e)
0160         raise RuntimeError("Exception in UserFunction: %r" % e)
0161 
0162     return seq
0163 
0164   def setupUserPhysics(self, userFunction):
0165     """To load arbitrary plugins, add a function to be executed.
0166 
0167     The function must take the DDG4.Kernel() object as the only argument.
0168 
0169     For example, add a function definition and the call to a steering file::
0170 
0171       def setupCerenkov(kernel):
0172         from DDG4 import PhysicsList
0173         seq = kernel.physicsList()
0174         cerenkov = PhysicsList(kernel, 'Geant4CerenkovPhysics/CerenkovPhys')
0175         cerenkov.MaxNumPhotonsPerStep = 10
0176         cerenkov.MaxBetaChangePerStep = 10.0
0177         cerenkov.TrackSecondariesFirst = True
0178         cerenkov.VerboseLevel = 2
0179         cerenkov.enableUI()
0180         seq.adopt(cerenkov)
0181         ph = PhysicsList(kernel, 'Geant4OpticalPhotonPhysics/OpticalGammaPhys')
0182         ph.addParticleConstructor('G4OpticalPhoton')
0183         ph.VerboseLevel = 2
0184         ph.enableUI()
0185         seq.adopt(ph)
0186         return None
0187 
0188       SIM.physics.setupUserPhysics(setupCerenkov)
0189 
0190     # End of example
0191     """
0192     self._userFunctions.append(userFunction)