Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-12 09:35:25

0001 #!/usr/bin/env python
0002 """
0003 DD4hep simulation with some argument parsing
0004 Based on M. Frank and F. Gaede runSim.py
0005    @author  A.Sailer
0006    @version 0.1
0007 
0008 Modified with standard EIC EPIC requirements.
0009 """
0010 from __future__ import absolute_import, unicode_literals
0011 import logging
0012 import sys
0013 
0014 from DDSim.DD4hepSimulation import DD4hepSimulation
0015 
0016 
0017 if __name__ == "__main__":
0018   logging.basicConfig(format='%(name)-16s %(levelname)s %(message)s', level=logging.INFO, stream=sys.stdout)
0019   logger = logging.getLogger('DDSim')
0020 
0021   RUNNER = DD4hepSimulation()
0022 
0023   RUNNER.part.userParticleHandler = "Geant4TVEicParticleHandler"
0024 
0025   # Parse remaining options (command line and steering file override above)
0026   # This is done before updating the settings to workaround issue reported in
0027   # https://github.com/AIDASoft/DD4hep/pull/1376
0028   RUNNER.parseOptions()
0029 
0030   # Ensure that Cerenkov and optical physics are always loaded
0031   def setupCerenkov(kernel):
0032     from DDG4 import PhysicsList
0033     seq = kernel.physicsList()
0034     cerenkov = PhysicsList(kernel, 'Geant4CerenkovPhysics/CerenkovPhys')
0035     cerenkov.MaxNumPhotonsPerStep = 10
0036     cerenkov.MaxBetaChangePerStep = 10.0
0037     cerenkov.TrackSecondariesFirst = False
0038     cerenkov.VerboseLevel = 0
0039     cerenkov.enableUI()
0040     seq.adopt(cerenkov)
0041     ph = PhysicsList(kernel, 'Geant4OpticalPhotonPhysics/OpticalGammaPhys')
0042     ph.addParticleConstructor('G4OpticalPhoton')
0043     ph.VerboseLevel = 0
0044     ph.enableUI()
0045     seq.adopt(ph)
0046     return None
0047   RUNNER.physics.setupUserPhysics(setupCerenkov)
0048 
0049   # Use the EIC tracking-volume particle handler.
0050   from DDSim.Helper.ParticleHandler import ParticleHandler as _PH
0051 
0052   _orig_setupUserParticleHandler = _PH.setupUserParticleHandler
0053 
0054   def _setupUserParticleHandler(self, part, kernel, DDG4):
0055     if self.userParticleHandler == "Geant4TVEicParticleHandler":
0056 
0057       handler = DDG4.Action(kernel, "Geant4TVEicParticleHandler/UserParticleHandler")
0058 
0059       logger.info(" *** Geant4TVEicParticleHandler enabled ***")
0060       logger.info("    ForwardRegionZ        = %s", handler.ForwardRegionZ)
0061       logger.info("    BackwardRegionZ       = %s", handler.BackwardRegionZ)
0062       logger.info("    ForwardMomentumMin    = %s", handler.ForwardMomentumMin)
0063       logger.info("    BackwardMomentumMin   = %s", handler.BackwardMomentumMin)
0064       logger.info("    KeepCaloHitParticles  = %s", handler.KeepCaloHitParticles)
0065       logger.info(" ******************************************")
0066 
0067       part.adopt(handler)
0068       return
0069 
0070     # Anything else (including "" and the stock TC/TV names) falls
0071     # through to the original DDSim implementation.
0072     _orig_setupUserParticleHandler(self, part, kernel, DDG4)
0073 
0074   _PH.setupUserParticleHandler = _setupUserParticleHandler
0075 
0076   # Disable warnings for unstable resonances with off-shell mass
0077   if hasattr(RUNNER.physics, "ESeverity"):
0078     RUNNER.physics.ESeverity = "IgnoreTheIssue"
0079 
0080   # Allow energy depositions to 0 energy in trackers (which include optical detectors)
0081   RUNNER.filter.tracker = 'edep0'
0082 
0083   # Some detectors are only sensitive to optical photons
0084   RUNNER.filter.filters['opticalphotons'] = dict(
0085     name='ParticleSelectFilter/OpticalPhotonSelector',
0086     parameter={"particle": "opticalphoton"},
0087   )
0088   # This could probably be a substring
0089   RUNNER.filter.mapDetFilter['DRICH'] = 'opticalphotons'
0090   RUNNER.filter.mapDetFilter['PFRICH'] = 'opticalphotons'
0091   RUNNER.filter.mapDetFilter['DIRC'] = 'opticalphotons'
0092 
0093   # Use the optical tracker for the dRICH, pfRICH and hpDIRC
0094   RUNNER.action.mapActions['DRICH'] = 'Geant4OpticalTrackerAction'
0095   RUNNER.action.mapActions['PFRICH'] = 'Geant4OpticalTrackerAction'
0096   RUNNER.action.mapActions['DIRC'] = 'Geant4OpticalTrackerAction'
0097 
0098   # Use the optical photon efficiency stacking action for hpDIRC
0099   RUNNER.action.stack = [
0100     {
0101       "name": "OpticalPhotonEfficiencyStackingAction",
0102       "parameter": {
0103         "LambdaMin": "180*nm",
0104         "LambdaMax": "678*nm",
0105         "Region": "DIRCRegion",
0106         "LogicalVolume": r"(bar_vol|glue_vol|lens_layer\d_vol|prism_vol|mcp_vol|Envelope_box_vol|Envelope_trap_vol)",
0107         "Efficiency": [e/100. for e in [
0108           0,    0,    14.0, 14.8, 14.5, 14.9, 14.4, 14.2, 13.9, 14.6, 15.2, 15.7, 16.4, 16.9, 17.5,
0109           17.7, 18.1, 18.8, 19.3, 19.8, 20.6, 21.4, 22.4, 23.1, 23.6, 24.1, 24.2, 24.6, 24.8, 25.2,
0110           25.7, 26.5, 27.1, 28.2, 29.0, 29.9, 30.8, 31.1, 31.7, 31.8, 31.6, 31.5, 31.5, 31.3, 31.0,
0111           30.8, 30.8, 30.4, 30.2, 30.3, 30.2, 30.1, 30.1, 30.1, 29.8, 29.9, 29.8, 29.7, 29.7, 29.7,
0112           29.8, 29.8, 29.9, 29.9, 29.8, 29.9, 29.8, 29.9, 29.8, 29.7, 29.8, 29.7, 29.8, 29.6, 29.5,
0113           29.7, 29.7, 29.8, 30.1, 30.4, 31.0, 31.3, 31.5, 31.8, 31.8, 31.9, 32.0, 32.0, 32.0, 32.0,
0114           32.2, 32.2, 32.1, 31.8, 31.8, 31.8, 31.7, 31.6, 31.6, 31.7, 31.5, 31.5, 31.4, 31.3, 31.3,
0115           31.2, 30.8, 30.7, 30.5, 30.3, 29.9, 29.5, 29.3, 29.2, 28.6, 28.2, 27.9, 27.8, 27.3, 27.0,
0116           26.6, 26.1, 25.9, 25.5, 25.0, 24.6, 24.2, 23.8, 23.4, 23.0, 22.7, 22.4, 21.9, 21.4, 21.2,
0117           20.7, 20.3, 19.8, 19.6, 19.3, 18.9, 18.7, 18.3, 17.9, 17.8, 17.8, 16.7, 16.5, 16.4, 16.0,
0118           15.6, 15.6, 15.2, 14.9, 14.6, 14.4, 14.1, 13.8, 13.6, 13.3, 13.0, 12.8, 12.6, 12.3, 12.0,
0119           11.9, 11.7, 11.5, 11.2, 11.1, 10.9, 10.7, 10.4, 10.3, 9.9,  9.8,  9.6,  9.3,  9.1,  9.0,
0120           8.8,  8.5,  8.3,  8.3,  8.2,  7.9,  7.8,  7.7,  7.5,  7.3,  7.1,  6.9,  6.7,  6.6,  6.3,
0121           6.2,  6.0,  5.8,  5.7,  5.6,  5.4,  5.2,  5.1,  4.9,  4.8,  4.6,  4.5,  4.4,  4.2,  4.1,
0122           4.0,  3.8,  3.7,  3.5,  3.3,  3.2,  3.1,  3.0,  2.9,  2.5,  2.4,  2.4,  2.3,  2.3,  2.1,
0123           1.8,  1.6,  1.5,  1.5,  1.6,  1.8,  1.9,  1.4,  0.8,  0.9,  0.8,  0.7,  0.6,  0.3,  0.3,
0124           0.5,  0.3,  0.4,  0.3,  0.1,  0.2,  0.1,  0.2,  0.3,  0.0
0125         ]]
0126       }
0127     }
0128   ]
0129 
0130   try:
0131     sys.exit(RUNNER.run())
0132   except NameError as e:
0133     if "global name" in str(e):
0134       globalToSet = str(e).split("'")[1]
0135       logger.fatal("Unknown global variable, please add\nglobal %s\nto your steeringFile" % globalToSet)