File indexing completed on 2025-01-18 09:14:13
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 from __future__ import absolute_import, unicode_literals
0014 import os
0015 import time
0016 import logging
0017 import DDG4
0018 from DDG4 import OutputLevel as Output
0019 from g4units import keV, GeV, mm, ns, MeV
0020
0021 logging.basicConfig(format='%(levelname)s: %(message)s', level=logging.INFO)
0022 logger = logging.getLogger(__name__)
0023
0024 """
0025
0026 dd4hep simulation example setup DDG4
0027 in multi-threaded mode using the python configuration
0028
0029 @author M.Frank
0030 @version 1.0
0031
0032 """
0033
0034
0035 def setupWorker(geant4):
0036 kernel = geant4.kernel()
0037 logger.info('#PYTHON: +++ Creating Geant4 worker thread ....')
0038 logger.info("#PYTHON: Configure Run actions")
0039 run1 = DDG4.RunAction(kernel, 'Geant4TestRunAction/RunInit', shared=True)
0040 run1.Property_int = int(12345)
0041 run1.Property_double = -5e15 * keV
0042 run1.Property_string = 'Startrun: Hello_2'
0043 logger.info("%s %s %s", run1.Property_string, str(run1.Property_double), str(run1.Property_int))
0044 run1.enableUI()
0045 kernel.runAction().adopt(run1)
0046
0047 logger.info("#PYTHON: Configure Event actions")
0048 prt = DDG4.EventAction(kernel, 'Geant4ParticlePrint/ParticlePrint')
0049 prt.OutputLevel = Output.INFO
0050 prt.OutputType = 3
0051 kernel.eventAction().adopt(prt)
0052
0053 logger.info("\n#PYTHON: Configure I/O\n")
0054
0055
0056
0057 geant4.setupROOTOutput('RootOutput', 'CLICSiD_' + time.strftime('%Y-%m-%d_%H-%M'))
0058
0059 gen = DDG4.GeneratorAction(kernel, "Geant4GeneratorActionInit/GenerationInit")
0060 kernel.generatorAction().adopt(gen)
0061
0062 logger.info("#PYTHON:\n#PYTHON: Generation of isotrope tracks of a given multiplicity with overlay:\n#PYTHON:")
0063 logger.info("#PYTHON: First particle generator: pi+")
0064 gen = DDG4.GeneratorAction(kernel, "Geant4IsotropeGenerator/IsotropPi+")
0065 gen.Mask = 1
0066 gen.Particle = 'pi+'
0067 gen.Energy = 20 * GeV
0068 gen.Multiplicity = 2
0069 kernel.generatorAction().adopt(gen)
0070 logger.info("#PYTHON: Install vertex smearing for this interaction")
0071 gen = DDG4.GeneratorAction(kernel, "Geant4InteractionVertexSmear/SmearPi+")
0072 gen.Mask = 1
0073 gen.Offset = (20 * mm, 10 * mm, 10 * mm, 0 * ns)
0074 gen.Sigma = (4 * mm, 1 * mm, 1 * mm, 0 * ns)
0075 kernel.generatorAction().adopt(gen)
0076
0077 logger.info("#PYTHON: Second particle generator: e-")
0078 gen = DDG4.GeneratorAction(kernel, "Geant4IsotropeGenerator/IsotropE-")
0079 gen.Mask = 2
0080 gen.Particle = 'e-'
0081 gen.Energy = 15 * GeV
0082 gen.Multiplicity = 3
0083 kernel.generatorAction().adopt(gen)
0084 logger.info("#PYTHON: Install vertex smearing for this interaction")
0085 gen = DDG4.GeneratorAction(kernel, "Geant4InteractionVertexSmear/SmearE-")
0086 gen.Mask = 2
0087 gen.Offset = (-20 * mm, -10 * mm, -10 * mm, 0 * ns)
0088 gen.Sigma = (12 * mm, 8 * mm, 8 * mm, 0 * ns)
0089 kernel.generatorAction().adopt(gen)
0090
0091
0092 logger.info("#PYTHON: Merge all existing interaction records")
0093 gen = DDG4.GeneratorAction(kernel, "Geant4InteractionMerger/InteractionMerger")
0094 gen.OutputLevel = 4
0095 gen.enableUI()
0096 kernel.generatorAction().adopt(gen)
0097
0098 logger.info("#PYTHON: Finally generate Geant4 primaries")
0099 gen = DDG4.GeneratorAction(kernel, "Geant4PrimaryHandler/PrimaryHandler")
0100 gen.OutputLevel = 4
0101 gen.enableUI()
0102 kernel.generatorAction().adopt(gen)
0103
0104 logger.info("#PYTHON: ....and handle the simulation particles.")
0105 part = DDG4.GeneratorAction(kernel, "Geant4ParticleHandler/ParticleHandler")
0106 kernel.generatorAction().adopt(part)
0107
0108 part.SaveProcesses = ['Decay']
0109 part.MinimalKineticEnergy = 100 * MeV
0110 part.OutputLevel = 5
0111 part.enableUI()
0112 user = DDG4.Action(kernel, "Geant4TCUserParticleHandler/UserParticleHandler")
0113 user.TrackingVolume_Zmax = DDG4.EcalEndcap_zmin
0114 user.TrackingVolume_Rmax = DDG4.EcalBarrel_rmin
0115 user.enableUI()
0116 part.adopt(user)
0117 logger.info('#PYTHON: +++ Geant4 worker thread configured successfully....')
0118 return 1
0119
0120
0121 def setupMaster(geant4):
0122 kernel = geant4.master()
0123 logger.info('#PYTHON: +++ Setting up master thread for %d workers', int(kernel.NumberOfThreads))
0124 return 1
0125
0126
0127 def setupSensitives(geant4):
0128 logger.info("#PYTHON: Setting up all sensitive detectors")
0129 geant4.printDetectors()
0130 logger.info("#PYTHON: First the tracking detectors")
0131 seq, act = geant4.setupTracker('SiVertexBarrel')
0132 seq, act = geant4.setupTracker('SiVertexEndcap')
0133 seq, act = geant4.setupTracker('SiTrackerBarrel')
0134 seq, act = geant4.setupTracker('SiTrackerEndcap')
0135 seq, act = geant4.setupTracker('SiTrackerForward')
0136 logger.info("#PYTHON: Now setup the calorimeters")
0137 seq, act = geant4.setupCalorimeter('EcalBarrel')
0138 seq, act = geant4.setupCalorimeter('EcalEndcap')
0139 seq, act = geant4.setupCalorimeter('HcalBarrel')
0140 seq, act = geant4.setupCalorimeter('HcalEndcap')
0141 seq, act = geant4.setupCalorimeter('HcalPlug')
0142 seq, act = geant4.setupCalorimeter('MuonBarrel')
0143 seq, act = geant4.setupCalorimeter('MuonEndcap')
0144 seq, act = geant4.setupCalorimeter('LumiCal')
0145 seq, act = geant4.setupCalorimeter('BeamCal')
0146 return 1
0147
0148
0149 def run():
0150 kernel = DDG4.Kernel()
0151 description = kernel.detectorDescription()
0152 install_dir = os.environ['DD4hepINSTALL']
0153 DDG4.Core.setPrintFormat(str("%-32s %6s %s"))
0154 kernel.loadGeometry(str("file:" + install_dir + "/DDDetectors/compact/SiD.xml"))
0155 DDG4.importConstants(description)
0156
0157 kernel.NumberOfThreads = 3
0158 kernel.RunManagerType = 'G4MTRunManager'
0159 geant4 = DDG4.Geant4(kernel, tracker='Geant4TrackerCombineAction')
0160 logger.info("# Configure UI")
0161 geant4.setupCshUI()
0162
0163 logger.info("# Geant4 user initialization action")
0164 geant4.addUserInitialization(worker=setupWorker, worker_args=(geant4,),
0165 master=setupMaster, master_args=(geant4,))
0166
0167 logger.info("# Configure G4 geometry setup")
0168 seq, act = geant4.addDetectorConstruction("Geant4DetectorGeometryConstruction/ConstructGeo")
0169
0170 logger.info("# Configure G4 sensitive detectors: python setup callback")
0171 seq, act = geant4.addDetectorConstruction("Geant4PythonDetectorConstruction/SetupSD",
0172 sensitives=setupSensitives, sensitives_args=(geant4,))
0173 logger.info("# Configure G4 sensitive detectors: atach'em to the sensitive volumes")
0174 seq, act = geant4.addDetectorConstruction("Geant4DetectorSensitivesConstruction/ConstructSD")
0175
0176
0177 logger.info("# Configure G4 magnetic field tracking")
0178 geant4.setupTrackingFieldMT()
0179
0180 logger.info("# Setup random generator")
0181 rndm = DDG4.Action(kernel, 'Geant4Random/Random')
0182 rndm.Seed = 987654321
0183 rndm.initialize()
0184
0185
0186 logger.info("# Now build the physics list:")
0187 phys = geant4.setupPhysics('QGSP_BERT')
0188 phys.dump()
0189
0190 geant4.run()
0191
0192
0193 if __name__ == "__main__":
0194 run()