Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-03 07:49:51

0001 import acts
0002 import argparse
0003 from acts.examples.simulation import (
0004     addParticleGun,
0005     addGeant4,
0006     EtaConfig,
0007     PhiConfig,
0008     ParticleConfig,
0009     MomentumConfig,
0010 )
0011 
0012 from acts.examples.odd import getOpenDataDetector
0013 
0014 u = acts.UnitConstants
0015 
0016 
0017 def main():
0018 
0019     import acts
0020 
0021     global __geant4Handle
0022     global __pmr
0023 
0024     p = argparse.ArgumentParser()
0025 
0026     p.add_argument("-n", "--events", type=int, default=1000, help="Number of Events")
0027 
0028     p.add_argument(
0029         "-j",
0030         "--threads",
0031         type=int,
0032         default=1,
0033         help="Number of Threads for parallel execution",
0034     )
0035 
0036     p.add_argument("-i", "--input", type=str, default="", help="Input SQL file")
0037 
0038     p.add_argument("-o", "--output", type=str, default="", help="Output prefix")
0039 
0040     p.add_argument(
0041         "-m", "--map", type=str, default="", help="Input file for the material map"
0042     )
0043 
0044     p.add_argument("-s", "--seed", type=int, default=221177, help="Random number seed")
0045 
0046     # Add Particle generation related arguments
0047     p.add_argument(
0048         "--tracks", type=int, default=10, help="Number of tracks to generate per event"
0049     )
0050     p.add_argument(
0051         "--eta-range",
0052         type=float,
0053         nargs=2,
0054         default=[-2.5, 2.5],
0055         help="Pseudorapidity range for particle generation",
0056     )
0057     p.add_argument(
0058         "--phi-range",
0059         type=float,
0060         nargs=2,
0061         default=[0, 360],
0062         help="Azimuthal angle range (in degrees) for particle generation",
0063     )
0064     p.add_argument(
0065         "--pt-range",
0066         type=float,
0067         nargs=2,
0068         default=[0.5, 10],
0069         help="Transverse momentum range (in GeV) for particle generation",
0070     )
0071 
0072     # The geometry modes are
0073     # gen1: Gen1 detector with Gen1 navigator and propagator
0074     # gen3: Gen3 detector with Gen3 navigator and propagator
0075     # detray: Gen3->detray detector with detray navigator and propagator
0076     # geant4: Geant4 navigator and propagator with gen3 surface matching
0077     p.add_argument(
0078         "--geo-mode",
0079         type=str,
0080         default="gen3",
0081         choices=["gen1", "gen3", "detray", "geant4"],
0082         help="Convert to detray detector and run detray navigation and propagation",
0083     )
0084 
0085     p.add_argument(
0086         "--output-summary",
0087         action=argparse.BooleanOptionalAction,
0088         help="Write out the summary objects",
0089     )
0090 
0091     p.add_argument(
0092         "--output-steps",
0093         action=argparse.BooleanOptionalAction,
0094         help="Write out the step objects",
0095     )
0096 
0097     p.add_argument(
0098         "--output-material",
0099         action=argparse.BooleanOptionalAction,
0100         help="Write out the recorded",
0101     )
0102 
0103     p.add_argument(
0104         "--output-sim-hits",
0105         action=argparse.BooleanOptionalAction,
0106         help="Write out sim hits, only makes sense for Geant4",
0107     )
0108 
0109     args = p.parse_args()
0110 
0111     prfx = args.output + "_" if args.output != "" else ""
0112 
0113     gContext = acts.GeometryContext.dangerouslyDefaultConstruct()
0114     logLevel = acts.logging.INFO
0115 
0116     # Common (to all modes): Evoke the sequence
0117     rnd = acts.examples.RandomNumbers(seed=args.seed)
0118 
0119     # Common: Build the sequencer
0120     s = acts.examples.Sequencer(events=args.events, numThreads=args.threads)
0121 
0122     # Common: Add the particle gun from ACTS
0123     addParticleGun(
0124         s,
0125         ParticleConfig(
0126             num=args.tracks, pdg=acts.PdgParticle.eMuon, randomizeCharge=True
0127         ),
0128         EtaConfig(args.eta_range[0], args.eta_range[1]),
0129         PhiConfig(args.phi_range[0], args.phi_range[1]),
0130         MomentumConfig(
0131             args.pt_range[0] * u.GeV, args.pt_range[1] * u.GeV, transverse=True
0132         ),
0133         rnd=rnd,
0134     )
0135 
0136     # Timing measurement is run if neither output in on
0137     sterileRun = False
0138     if not args.output_summary and not args.output_steps and not args.output_material:
0139         print(">> Timing measurement is enabled, no output is written")
0140         sterileRun = True
0141 
0142     # Material decoration for reconstruction geometry
0143     materialDecorator = None
0144     if args.map != "":
0145         print(">>> Loading a material decorator from file:", args.map)
0146         materialDecorator = acts.IMaterialDecorator.fromFile(args.map)
0147 
0148     trackingGeometry = None
0149     detectorStore = {}
0150 
0151     buildGen3 = args.geo_mode == "gen3" or args.geo_mode == "detray"
0152 
0153     with getOpenDataDetector(gen3=buildGen3) as detector:
0154         trackingGeometry = detector.trackingGeometry()
0155         detectorStore["Detector"] = detector
0156         detectorStore["Volume"] = trackingGeometry.highestTrackingVolume
0157         detectorStore["SurfaceByIdentifier"] = trackingGeometry.geoIdSurfaceMap()
0158 
0159     print(">>> Test mode is :", args.geo_mode)
0160     # check if the mode does not contain geant4
0161     if args.geo_mode != "geant4":
0162         # The propagator
0163         propagatorImpl = None
0164         stepper = acts.StraightLineStepper()
0165 
0166         # Build the detector for Gen1/Gen3
0167         if args.geo_mode != "detray":
0168             # Set up the navigator - Gen1/Gen3
0169             navigator = acts.Navigator(trackingGeometry=trackingGeometry)
0170             propagator = acts.Propagator(stepper, navigator)
0171             propagatorImpl = acts.examples.ConcretePropagator(propagator)
0172         else:
0173             import acts.vecmem, acts.detray
0174             import acts.examples.detray
0175 
0176             __pmr = acts.vecmem.HostMemoryResource()
0177 
0178             detrayGeometry = acts.detray.convertODD(
0179                 __pmr,
0180                 gContext,
0181                 trackingGeometry,
0182                 beampipeVolumeName="BeamPipe",
0183                 logLevel=logLevel,
0184             )
0185             propagatorImpl = acts.examples.detray.StraightLinePropagatorODD(
0186                 detrayGeometry, __pmr, sterileRun, logLevel
0187             )
0188 
0189         # Run particle smearing
0190         trkParamExtractor = acts.examples.ParticleTrackParamExtractor(
0191             level=acts.logging.INFO,
0192             inputParticles="particles_generated",
0193             outputTrackParameters="start_parameters",
0194         )
0195         s.addAlgorithm(trkParamExtractor)
0196 
0197         propagationAlgorithm = acts.examples.PropagationAlgorithm(
0198             propagatorImpl=propagatorImpl,
0199             level=acts.logging.INFO,
0200             sterileLogger=sterileRun,
0201             inputTrackParameters="start_parameters",
0202             outputSummaryCollection="propagation_summary",
0203             outputMaterialCollection="material_tracks",
0204         )
0205         s.addAlgorithm(propagationAlgorithm)
0206     else:
0207         print(">>> Running Geant4 simulation, buckle up...")
0208         detector = detectorStore["Detector"]
0209 
0210         import acts.examples.geant4
0211 
0212         from acts.examples.geant4 import (
0213             Geant4Simulation,
0214             Geant4ConstructionOptions,
0215             SensitiveSurfaceMapper,
0216         )
0217 
0218         customLogLevel = acts.examples.defaultLogging(s, logLevel)
0219 
0220         smmConfig = SensitiveSurfaceMapper.Config()
0221         smmConfig.volumeMappings = []
0222         smmConfig.materialMappings = ["Silicon"]
0223         sensitiveMapper = SensitiveSurfaceMapper.create(
0224             smmConfig, customLogLevel(), trackingGeometry
0225         )
0226 
0227         detectorConstructionOptions = acts.examples.geant4.Geant4ConstructionOptions()
0228 
0229         # Specify the physics list, kill volume and other options for the Geant4 simulation
0230         physicsList = "FTFP_BERT"  # "MaterialPhysicsList"
0231         killVolume = detectorStore["Volume"]
0232         killAfterTime = float("inf")
0233         bfield = None
0234 
0235         inputParticles = "particles_generated"
0236         outputParticles = "particles_final"
0237 
0238         addGeant4(
0239             s,
0240             detector,
0241             trackingGeometry,
0242             None,
0243             outputDirRoot=None,
0244             outputDirCsv=None,
0245             outputDirObj=None,
0246             rnd=rnd,
0247             killVolume=trackingGeometry.highestTrackingVolume,
0248             killAfterTime=25 * u.ns,
0249             killSecondaries=True,
0250             recordHitsOfSecondaries=False,
0251             recordPropagationSummaries=True,
0252         )
0253 
0254         s.addWhiteboardAlias("propagation_summary", "propagation_summaries")
0255 
0256     # Common: Write the summary
0257     if args.output_summary:
0258         s.addWriter(
0259             acts.examples.root.RootPropagationSummaryWriter(
0260                 level=acts.logging.INFO,
0261                 inputSummaryCollection="propagation_summary",
0262                 filePath=prfx + args.geo_mode + "_propagation_summary.root",
0263             )
0264         )
0265 
0266     # Common: Write the steps
0267     if args.output_steps:
0268         s.addWriter(
0269             acts.examples.root.RootPropagationStepsWriter(
0270                 level=acts.logging.INFO,
0271                 collection="propagation_summary",
0272                 filePath=prfx + args.geo_mode + "_propagation_steps.root",
0273             )
0274         )
0275 
0276     # Common: Write the material
0277     if args.output_material:
0278         s.addWriter(
0279             acts.examples.root.RootMaterialTrackWriter(
0280                 level=acts.logging.INFO,
0281                 inputMaterialTracks="material_tracks",
0282                 filePath=args.geo_mode + "_material_tracks.root",
0283                 storeSurface=False,
0284                 storeVolume=False,
0285             )
0286         )
0287 
0288     # Run the sequence
0289     s.run()
0290 
0291 
0292 if "__main__" == __name__:
0293     main()