def addPythia8( sequencer: acts.examples.Sequencer, rnd: acts.examples.RandomNumbers, nhard=1, npileup=200, beam0=acts.PdgParticle.eProton, beam1=acts.PdgParticle.eProton, cmsEnergy=14 * acts.UnitConstants.TeV, vertexStddev: acts.Vector4 = acts.Vector4(0, 0, 0, 0), vertexMean: acts.Vector4 = acts.Vector4(0, 0, 0, 0), ): """This function steers the particle generation using Pythia8 NB. this version is included here only for compatibility. Please use pythia8.addPythia8 instead. """ import pythia8 evGen = pythia8.addPythia8( sequencer, rnd=rnd, nhard=nhard, npileup=npileup, beam=(beam0, beam1), cmsEnergy=cmsEnergy, vtxGen=acts.examples.GaussianVertexGenerator(stddev=vertexStddev, mean=vertexMean), returnEvGen=True, ) return evGen
def _factory(s): evGen = acts.examples.EventGenerator( level=acts.logging.INFO, generators=[ acts.examples.EventGenerator.Generator( multiplicity=acts.examples.FixedMultiplicityGenerator(n=2), vertex=acts.examples.GaussianVertexGenerator( stddev=acts.Vector4(0, 0, 0, 0), mean=acts.Vector4(0, 0, 0, 0)), particles=acts.examples.ParametricParticleGenerator( p=(1 * u.GeV, 10 * u.GeV), eta=(-2, 2), phi=(0, 360 * u.degree), randomizeCharge=True, numParticles=2, ), ) ], outputParticles="particles_input", randomNumbers=rng, ) s.addReader(evGen) return evGen
def runMaterialRecording(g4geo, outputDir, tracksPerEvent=10000, s=None): global _material_recording_executed if _material_recording_executed: warnings.warn("Material recording already ran in this process. Expect crashes") _material_recording_executed = True rnd = RandomNumbers(seed=228) s = s or acts.examples.Sequencer(events=2, numThreads=1) evGen = EventGenerator( level=acts.logging.INFO, generators=[ EventGenerator.Generator( multiplicity=FixedMultiplicityGenerator(n=1), vertex=GaussianVertexGenerator( stddev=acts.Vector4(0, 0, 0, 0), mean=acts.Vector4(0, 0, 0, 0), ), particles=ParametricParticleGenerator( p=(1 * u.GeV, 10 * u.GeV), eta=(-4, 4), numParticles=tracksPerEvent ), ) ], outputParticles="particles_initial", randomNumbers=rnd, ) s.addReader(evGen) g4AlgCfg = acts.examples.geant4.materialRecordingConfig( level=acts.logging.INFO, detector=g4geo, inputParticles=evGen.config.outputParticles, outputMaterialTracks="material_tracks", ) g4AlgCfg.detectorConstruction = g4geo g4Alg = acts.examples.geant4.Geant4Simulation( level=acts.logging.INFO, config=g4AlgCfg ) s.addAlgorithm(g4Alg) s.addWriter( acts.examples.RootMaterialTrackWriter( prePostStep=True, recalculateTotals=True, collection="material_tracks", filePath=os.path.join(outputDir, "geant4_material_tracks.root"), level=acts.logging.INFO, ) ) return s
def addPythia8( sequencer: acts.examples.Sequencer, rnd: acts.examples.RandomNumbers, nhard=1, npileup=200, beam0=acts.PdgParticle.eProton, beam1=acts.PdgParticle.eProton, cmsEnergy=14 * acts.UnitConstants.TeV, vertexStddev: acts.Vector4 = acts.Vector4(0, 0, 0, 0), vertexMean: acts.Vector4 = acts.Vector4(0, 0, 0, 0), ): vertexGenerator = acts.examples.GaussianVertexGenerator( stddev=vertexStddev, mean=vertexMean ) generators = [] if nhard > 0: generators.append( acts.examples.EventGenerator.Generator( multiplicity=acts.examples.FixedMultiplicityGenerator(n=nhard), vertex=vertexGenerator, particles=acts.examples.pythia8.Pythia8Generator( level=acts.logging.INFO, pdgBeam0=beam0, pdgBeam1=beam1, cmsEnergy=cmsEnergy, settings=["HardQCD:all = on"], ), ) ) if npileup > 0: generators.append( acts.examples.EventGenerator.Generator( multiplicity=acts.examples.FixedMultiplicityGenerator(n=npileup), vertex=vertexGenerator, particles=acts.examples.pythia8.Pythia8Generator( level=acts.logging.INFO, pdgBeam0=beam0, pdgBeam1=beam1, cmsEnergy=cmsEnergy, settings=["SoftQCD:all = on"], ), ) ) # Input evGen = acts.examples.EventGenerator( level=acts.logging.INFO, generators=generators, outputParticles="particles_input", randomNumbers=rnd, ) sequencer.addReader(evGen) return evGen
def runEventRecording(g4geo, outputDir, s=None): hepmc_dir = os.path.join(outputDir, "hepmc3") if not os.path.exists(hepmc_dir): os.mkdir(hepmc_dir) s = s or acts.examples.Sequencer( events=int(os.environ.get("NEVENTS", 100)), numThreads=1) rnd = acts.examples.RandomNumbers(seed=42) evGen = acts.examples.EventGenerator( level=acts.logging.INFO, generators=[ acts.examples.EventGenerator.Generator( multiplicity=acts.examples.FixedMultiplicityGenerator(n=2), vertex=acts.examples.GaussianVertexGenerator( stddev=acts.Vector4(0, 0, 0, 0), mean=acts.Vector4(0, 0, 0, 0)), particles=acts.examples.ParametricParticleGenerator( p=(1 * u.GeV, 10 * u.GeV), eta=(-2, 2), phi=(0, 90 * u.degree), randomizeCharge=True, numParticles=4, ), ) ], outputParticles="particles_input", randomNumbers=rnd, ) s.addReader(evGen) erAlgCfg = acts.examples.geant4.hepmc3.EventRecording.Config( inputParticles=evGen.config.outputParticles, outputHepMcTracks="geant-event", seed1=43, seed2=44, detectorConstruction=g4geo, ) erAlg = acts.examples.geant4.hepmc3.EventRecording(config=erAlgCfg, level=acts.logging.INFO) s.addAlgorithm(erAlg) s.addWriter( acts.examples.hepmc3.HepMC3AsciiWriter( level=acts.logging.INFO, outputDir=hepmc_dir, outputStem="events", inputEvents=erAlg.config.outputHepMcTracks, )) return s
def test_algebra(): v3 = acts.Vector3(1, 2, 3) with pytest.raises(TypeError): acts.Vector3(1, 2, 3, 4) with pytest.raises(TypeError): acts.Vector3(1, 2) v3 = acts.Vector3([1, 2, 3]) with pytest.raises(TypeError): acts.Vector3([1, 2, 3, 4]) with pytest.raises(TypeError): acts.Vector3([1, 2]) with pytest.raises(TypeError): acts.Vector3() v4 = acts.Vector4(1, 2, 3, 4) with pytest.raises(TypeError): v4 = acts.Vector4(1, 2, 3) v4 = acts.Vector4([1, 2, 3, 4]) with pytest.raises(TypeError): acts.Vector4([1, 2, 3]) with pytest.raises(TypeError): acts.Vector4()
def runTruthTracking( trackingGeometry, field, outputDir: Path, digiConfigFile: Path, directNavigation=False, s: acts.examples.Sequencer = None, ): # Preliminaries rnd = acts.examples.RandomNumbers() # Sequencer s = s or acts.examples.Sequencer( events=10, numThreads=-1, logLevel=acts.logging.INFO) # Input vtxGen = acts.examples.GaussianVertexGenerator() vtxGen.stddev = acts.Vector4(0, 0, 0, 0) ptclGen = acts.examples.ParametricParticleGenerator(p=(1 * u.GeV, 10 * u.GeV), eta=(-2, 2), numParticles=2) g = acts.examples.EventGenerator.Generator() g.multiplicity = acts.examples.FixedMultiplicityGenerator() g.vertex = vtxGen g.particles = ptclGen evGen = acts.examples.EventGenerator( level=acts.logging.INFO, generators=[g], outputParticles="particles_input", randomNumbers=rnd, ) s.addReader(evGen) s.addWriter( acts.examples.RootParticleWriter( level=acts.logging.INFO, inputParticles=evGen.config.outputParticles, filePath=str(outputDir / "particles.root"), )) # Selector selector = acts.examples.ParticleSelector( level=acts.logging.INFO, inputParticles=evGen.config.outputParticles, outputParticles="particles_selected", ) s.addAlgorithm(selector) # Simulation simAlg = acts.examples.FatrasSimulation( level=acts.logging.INFO, inputParticles=selector.config.outputParticles, outputParticlesInitial="particles_initial", outputParticlesFinal="particles_final", outputSimHits="simhits", randomNumbers=rnd, trackingGeometry=trackingGeometry, magneticField=field, generateHitsOnSensitive=True, ) s.addAlgorithm(simAlg) # Digitization digiCfg = acts.examples.DigitizationConfig( acts.examples.readDigiConfigFromJson(str(digiConfigFile), ), trackingGeometry=trackingGeometry, randomNumbers=rnd, inputSimHits=simAlg.config.outputSimHits, ) digiAlg = acts.examples.DigitizationAlgorithm(digiCfg, acts.logging.INFO) s.addAlgorithm(digiAlg) selAlg = acts.examples.TruthSeedSelector( level=acts.logging.INFO, ptMin=500 * u.MeV, nHitsMin=9, inputParticles=simAlg.config.outputParticlesInitial, inputMeasurementParticlesMap=digiCfg.outputMeasurementParticlesMap, outputParticles="particles_seed_selected", ) s.addAlgorithm(selAlg) inputParticles = selAlg.config.outputParticles smearAlg = acts.examples.ParticleSmearing( level=acts.logging.INFO, inputParticles=inputParticles, outputTrackParameters="smearedparameters", randomNumbers=rnd, # Gaussian sigmas to smear particle parameters # sigmaD0=20 * u.um, # sigmaD0PtA=30 * u.um, # sigmaD0PtB=0.3 / u.GeV, # sigmaZ0=20 * u.um, # sigmaZ0PtA=30 * u.um, # sigmaZ0PtB=0.3 / u.GeV, # sigmaPhi=1 * u.degree, # sigmaTheta=1 * u.degree, # sigmaPRel=0.01, # sigmaT0=1 * u.ns, # initialVarInflation=[1, 1, 1, 1, 1, 1], ) s.addAlgorithm(smearAlg) truthTrkFndAlg = acts.examples.TruthTrackFinder( level=acts.logging.INFO, inputParticles=inputParticles, inputMeasurementParticlesMap=digiAlg.config. outputMeasurementParticlesMap, outputProtoTracks="prototracks", ) s.addAlgorithm(truthTrkFndAlg) if directNavigation: srfSortAlg = acts.examples.SurfaceSortingAlgorithm( level=acts.logging.INFO, inputProtoTracks=truthTrkFndAlg.config.outputProtoTracks, inputSimulatedHits=simAlg.config.outputSimHits, inputMeasurementSimHitsMap=digiAlg.config. outputMeasurementSimHitsMap, outputProtoTracks="sortedprototracks", ) s.addAlgorithm(srfSortAlg) inputProtoTracks = srfSortAlg.config.outputProtoTracks else: inputProtoTracks = truthTrkFndAlg.config.outputProtoTracks fitAlg = acts.examples.TrackFittingAlgorithm( level=acts.logging.INFO, inputMeasurements=digiAlg.config.outputMeasurements, inputSourceLinks=digiAlg.config.outputSourceLinks, inputProtoTracks=inputProtoTracks, inputInitialTrackParameters=smearAlg.config.outputTrackParameters, outputTrajectories="trajectories", directNavigation=directNavigation, multipleScattering=True, energyLoss=True, pickTrack=-1, trackingGeometry=trackingGeometry, dFit=acts.examples.TrackFittingAlgorithm.makeTrackFitterFunction( field), fit=acts.examples.TrackFittingAlgorithm.makeTrackFitterFunction( trackingGeometry, field), ) s.addAlgorithm(fitAlg) # Output s.addWriter( acts.examples.RootTrajectoryStatesWriter( level=acts.logging.INFO, inputTrajectories=fitAlg.config.outputTrajectories, inputParticles=inputParticles, inputSimHits=simAlg.config.outputSimHits, inputMeasurementParticlesMap=digiAlg.config. outputMeasurementParticlesMap, inputMeasurementSimHitsMap=digiAlg.config. outputMeasurementSimHitsMap, filePath=str(outputDir / "trackstates_fitter.root"), )) s.addWriter( acts.examples.RootTrajectorySummaryWriter( level=acts.logging.INFO, inputTrajectories=fitAlg.config.outputTrajectories, inputParticles=inputParticles, inputMeasurementParticlesMap=digiAlg.config. outputMeasurementParticlesMap, filePath=str(outputDir / "tracksummary_fitter.root"), )) s.addWriter( acts.examples.TrackFinderPerformanceWriter( level=acts.logging.INFO, inputProtoTracks=truthTrkFndAlg.config.outputProtoTracks, inputParticles=inputParticles, inputMeasurementParticlesMap=digiAlg.config. outputMeasurementParticlesMap, filePath=str(outputDir / "performance_track_finder.root"), )) s.addWriter( acts.examples.TrackFitterPerformanceWriter( level=acts.logging.INFO, inputTrajectories=fitAlg.config.outputTrajectories, inputParticles=inputParticles, inputMeasurementParticlesMap=digiAlg.config. outputMeasurementParticlesMap, filePath=str(outputDir / "performance_track_fitter.root"), )) return s
def runSeeding(trackingGeometry, field, outputDir, s=None): srcdir = Path(__file__).resolve().parent.parent.parent.parent csv_dir = os.path.join(outputDir, "csv") if not os.path.exists(csv_dir): os.mkdir(csv_dir) # Input rnd = acts.examples.RandomNumbers(seed=42) evGen = acts.examples.EventGenerator( level=acts.logging.INFO, generators=[ acts.examples.EventGenerator.Generator( multiplicity=acts.examples.FixedMultiplicityGenerator(n=2), vertex=acts.examples.GaussianVertexGenerator( stddev=acts.Vector4(0, 0, 0, 0), mean=acts.Vector4(0, 0, 0, 0)), particles=acts.examples.ParametricParticleGenerator( p=(1 * u.GeV, 10 * u.GeV), eta=(-2, 2), phi=(0, 360 * u.degree), randomizeCharge=True, numParticles=4, ), ) ], outputParticles="particles_input", randomNumbers=rnd, ) # Read input from input collection (e.g. Pythia8 output) # evGen = acts.examples.RootParticleReader( # level=acts.logging.INFO, # particleCollection="particles_input", # inputDir="output", # inputFile="pythia8_particles.root", # ) # Simulation simAlg = acts.examples.FatrasSimulation( level=acts.logging.INFO, inputParticles=evGen.config.outputParticles, # inputParticles=evGen.config.particleCollection, outputParticlesInitial="particles_initial", outputParticlesFinal="particles_final", outputSimHits="simhits", randomNumbers=rnd, trackingGeometry=trackingGeometry, magneticField=field, generateHitsOnSensitive=True, ) # Digitization digiCfg = acts.examples.DigitizationConfig( acts.examples.readDigiConfigFromJson( str(srcdir / "Examples/Algorithms/Digitization/share/default-smearing-config-generic.json" )), trackingGeometry=trackingGeometry, randomNumbers=rnd, inputSimHits=simAlg.config.outputSimHits, ) digiAlg = acts.examples.DigitizationAlgorithm(digiCfg, acts.logging.INFO) selAlg = acts.examples.TruthSeedSelector( level=acts.logging.INFO, ptMin=1 * u.GeV, eta=(-2.5, 2.5), nHitsMin=9, inputParticles=simAlg.config.outputParticlesFinal, inputMeasurementParticlesMap=digiCfg.outputMeasurementParticlesMap, outputParticles="particles_selected", ) inputParticles = selAlg.config.outputParticles spAlg = acts.examples.SpacePointMaker( level=acts.logging.INFO, inputSourceLinks=digiCfg.outputSourceLinks, inputMeasurements=digiCfg.outputMeasurements, outputSpacePoints="spacepoints", trackingGeometry=trackingGeometry, geometrySelection=acts.examples.readJsonGeometryList( str(srcdir / "Examples/Algorithms/TrackFinding/share/geoSelection-genericDetector.json" )), ) gridConfig = acts.SpacePointGridConfig( bFieldInZ=1.99724 * u.T, minPt=500 * u.MeV, rMax=200 * u.mm, zMax=2000 * u.mm, zMin=-2000 * u.mm, deltaRMax=60 * u.mm, cotThetaMax=7.40627, # 2.7 eta ) seedFilterConfig = acts.SeedFilterConfig(maxSeedsPerSpM=1, deltaRMin=1 * u.mm) seedFinderConfig = acts.SeedfinderConfig( rMax=gridConfig.rMax, deltaRMin=seedFilterConfig.deltaRMin, deltaRMax=gridConfig.deltaRMax, collisionRegionMin=-250 * u.mm, collisionRegionMax=250 * u.mm, zMin=gridConfig.zMin, zMax=gridConfig.zMax, maxSeedsPerSpM=seedFilterConfig.maxSeedsPerSpM, cotThetaMax=gridConfig.cotThetaMax, sigmaScattering=50, radLengthPerSeed=0.1, minPt=gridConfig.minPt, bFieldInZ=gridConfig.bFieldInZ, beamPos=acts.Vector2(0 * u.mm, 0 * u.mm), impactMax=3 * u.mm, ) seedingAlg = acts.examples.SeedingAlgorithm( level=acts.logging.VERBOSE, inputSpacePoints=[spAlg.config.outputSpacePoints], outputSeeds="seeds", outputProtoTracks="prototracks", gridConfig=gridConfig, seedFilterConfig=seedFilterConfig, seedFinderConfig=seedFinderConfig, ) parEstimateAlg = acts.examples.TrackParamsEstimationAlgorithm( level=acts.logging.VERBOSE, inputProtoTracks=seedingAlg.config.outputProtoTracks, inputSpacePoints=[spAlg.config.outputSpacePoints], inputSourceLinks=digiCfg.outputSourceLinks, outputTrackParameters="estimatedparameters", outputProtoTracks="prototracks_estimated", trackingGeometry=trackingGeometry, magneticField=field, ) s = s or acts.examples.Sequencer( events=100, numThreads=-1, logLevel=acts.logging.INFO) s.addReader(evGen) s.addAlgorithm(simAlg) s.addAlgorithm(digiAlg) s.addAlgorithm(selAlg) s.addAlgorithm(spAlg) s.addAlgorithm(seedingAlg) s.addAlgorithm(parEstimateAlg) s.addWriter( acts.examples.RootParticleWriter( level=acts.logging.INFO, inputParticles=evGen.config.outputParticles, filePath=outputDir + "/evgen_particles.root", )) s.addWriter( acts.examples.CsvParticleWriter( level=acts.logging.INFO, inputParticles=evGen.config.outputParticles, outputStem="evgen_particles", outputDir=outputDir + "/csv", )) s.addWriter( acts.examples.RootParticleWriter( level=acts.logging.INFO, inputParticles=simAlg.config.outputParticlesFinal, filePath=outputDir + "/fatras_particles_final.root", )) s.addWriter( acts.examples.CsvParticleWriter( level=acts.logging.INFO, inputParticles=simAlg.config.outputParticlesFinal, outputStem="fatras_particles_final", outputDir=outputDir + "/csv", )) s.addWriter( acts.examples.RootParticleWriter( level=acts.logging.INFO, inputParticles=simAlg.config.outputParticlesInitial, filePath=outputDir + "/fatras_particles_initial.root", )) s.addWriter( acts.examples.CsvParticleWriter( level=acts.logging.INFO, inputParticles=simAlg.config.outputParticlesInitial, outputStem="fatras_particles_initial", outputDir=outputDir + "/csv", )) s.addWriter( acts.examples.TrackFinderPerformanceWriter( level=acts.logging.INFO, inputProtoTracks=seedingAlg.config.outputProtoTracks, inputParticles=inputParticles, inputMeasurementParticlesMap=digiCfg.outputMeasurementParticlesMap, filePath=outputDir + "/performance_seeding_trees.root", )) s.addWriter( acts.examples.SeedingPerformanceWriter( level=acts.logging.DEBUG, inputProtoTracks=seedingAlg.config.outputProtoTracks, inputParticles=inputParticles, inputMeasurementParticlesMap=digiCfg.outputMeasurementParticlesMap, filePath=outputDir + "/performance_seeding_hists.root", )) s.addWriter( acts.examples.RootTrackParameterWriter( level=acts.logging.VERBOSE, inputTrackParameters=parEstimateAlg.config.outputTrackParameters, inputProtoTracks=parEstimateAlg.config.outputProtoTracks, inputParticles=simAlg.config.outputParticlesFinal, inputSimHits=simAlg.config.outputSimHits, inputMeasurementParticlesMap=digiCfg.outputMeasurementParticlesMap, inputMeasurementSimHitsMap=digiCfg.outputMeasurementSimHitsMap, filePath=outputDir + "/estimatedparams.root", treeName="estimatedparams", )) return s
def runCKFTracks( trackingGeometry, decorators, geometrySelection: Path, digiConfigFile: Path, field, outputDir: Path, truthSmearedSeeded=False, truthEstimatedSeeded=False, outputCsv=True, inputParticlePath: Optional[Path] = None, s=None, ): s = s or Sequencer(events=100, numThreads=-1) logger = acts.logging.getLogger("CKFExample") for d in decorators: s.addContextDecorator(d) rnd = acts.examples.RandomNumbers(seed=42) if inputParticlePath is None: logger.info("Generating particles using particle gun") evGen = acts.examples.EventGenerator( level=acts.logging.INFO, generators=[ acts.examples.EventGenerator.Generator( multiplicity=acts.examples.FixedMultiplicityGenerator(n=2), vertex=acts.examples.GaussianVertexGenerator( stddev=acts.Vector4(0, 0, 0, 0), mean=acts.Vector4(0, 0, 0, 0)), particles=acts.examples.ParametricParticleGenerator( p=(1 * u.GeV, 10 * u.GeV), eta=(-2, 2), phi=(0, 360 * u.degree), randomizeCharge=True, numParticles=4, ), ) ], outputParticles="particles_input", randomNumbers=rnd, ) s.addReader(evGen) inputParticles = evGen.config.outputParticles else: logger.info("Reading particles from %s", inputParticlePath.resolve()) assert inputParticlePath.exists() inputParticles = "particles_read" s.addReader( RootParticleReader( level=acts.logging.INFO, filePath=str(inputParticlePath.resolve()), particleCollection=inputParticles, orderedEvents=False, )) # Selector selector = acts.examples.ParticleSelector( level=acts.logging.INFO, inputParticles=inputParticles, outputParticles="particles_selected", ) s.addAlgorithm(selector) # Simulation simAlg = acts.examples.FatrasSimulation( level=acts.logging.INFO, inputParticles=selector.config.outputParticles, outputParticlesInitial="particles_initial", outputParticlesFinal="particles_final", outputSimHits="simhits", randomNumbers=rnd, trackingGeometry=trackingGeometry, magneticField=field, generateHitsOnSensitive=True, ) s.addAlgorithm(simAlg) # Run the sim hits smearing digiCfg = acts.examples.DigitizationConfig( acts.examples.readDigiConfigFromJson(str(digiConfigFile)), trackingGeometry=trackingGeometry, randomNumbers=rnd, inputSimHits=simAlg.config.outputSimHits, ) digiAlg = acts.examples.DigitizationAlgorithm(digiCfg, acts.logging.INFO) s.addAlgorithm(digiAlg) # Run the particle selection # The pre-selection will select truth particles satisfying provided criteria # from all particles read in by particle reader for further processing. It # has no impact on the truth hits themselves selAlg = acts.examples.TruthSeedSelector( level=acts.logging.INFO, ptMin=500 * u.MeV, nHitsMin=9, inputParticles=simAlg.config.outputParticlesInitial, inputMeasurementParticlesMap=digiCfg.outputMeasurementParticlesMap, outputParticles="particles_seed_selected", ) s.addAlgorithm(selAlg) inputParticles = selAlg.config.outputParticles # Create starting parameters from either particle smearing or combined seed # finding and track parameters estimation if truthSmearedSeeded: logger.info("Using smeared truth particles for seeding") # Run particle smearing ptclSmear = acts.examples.ParticleSmearing( level=acts.logging.INFO, inputParticles=inputParticles, outputTrackParameters="smearedparameters", randomNumbers=rnd, # gaussian sigmas to smear particle parameters sigmaD0=20 * u.um, sigmaD0PtA=30 * u.um, sigmaD0PtB=0.3 / 1 * u.GeV, sigmaZ0=20 * u.um, sigmaZ0PtA=30 * u.um, sigmaZ0PtB=0.3 / 1 * u.GeV, sigmaPhi=1 * u.degree, sigmaTheta=1 * u.degree, sigmaPRel=0.01, sigmaT0=1 * u.ns, initialVarInflation=[1, 1, 1, 1, 1, 1], ) outputTrackParameters = ptclSmear.config.outputTrackParameters s.addAlgorithm(ptclSmear) else: # Create space points spAlg = acts.examples.SpacePointMaker( level=acts.logging.INFO, inputSourceLinks=digiAlg.config.outputSourceLinks, inputMeasurements=digiAlg.config.outputMeasurements, outputSpacePoints="spacepoints", trackingGeometry=trackingGeometry, geometrySelection=acts.examples.readJsonGeometryList( str(geometrySelection)), ) s.addAlgorithm(spAlg) # Run either: truth track finding or seeding if truthEstimatedSeeded: logger.info( "Using truth track finding from space points for seeding") # Use truth tracking truthTrackFinder = acts.examples.TruthTrackFinder( level=acts.logging.INFO, inputParticles=inputParticles, inputMeasurementParticlesMap=digiAlg.config. outputMeasurementParticlesMap, outputProtoTracks="prototracks", ) s.addAlgorithm(truthTrackFinder) inputProtoTracks = truthTrackFinder.config.outputProtoTracks inputSeeds = "" else: logger.info("Using seeding") # Use seeding gridConfig = acts.SpacePointGridConfig( bFieldInZ=1.99724 * u.T, minPt=500 * u.MeV, rMax=200 * u.mm, zMax=2000 * u.mm, zMin=-2000 * u.mm, deltaRMax=60 * u.mm, cotThetaMax=7.40627, # 2.7 eta ) seedFilterConfig = acts.SeedFilterConfig(maxSeedsPerSpM=1, deltaRMin=1 * u.mm) seedFinderConfig = acts.SeedfinderConfig( rMax=gridConfig.rMax, deltaRMin=seedFilterConfig.deltaRMin, deltaRMax=gridConfig.deltaRMax, collisionRegionMin=-250 * u.mm, collisionRegionMax=250 * u.mm, zMin=gridConfig.zMin, zMax=gridConfig.zMax, maxSeedsPerSpM=seedFilterConfig.maxSeedsPerSpM, cotThetaMax=gridConfig.cotThetaMax, sigmaScattering=50, radLengthPerSeed=0.1, minPt=gridConfig.minPt, bFieldInZ=gridConfig.bFieldInZ, beamPos=acts.Vector2(0 * u.mm, 0 * u.mm), impactMax=3 * u.mm, ) seeding = acts.examples.SeedingAlgorithm( level=acts.logging.INFO, inputSpacePoints=[spAlg.config.outputSpacePoints], outputSeeds="seeds", outputProtoTracks="prototracks", gridConfig=gridConfig, seedFilterConfig=seedFilterConfig, seedFinderConfig=seedFinderConfig, ) s.addAlgorithm(seeding) inputProtoTracks = seeding.config.outputProtoTracks inputSeeds = seeding.config.outputSeeds # Write truth track finding / seeding performance trackFinderPerformanceWriter = acts.examples.TrackFinderPerformanceWriter( level=acts.logging.INFO, inputProtoTracks=inputProtoTracks, inputParticles= inputParticles, # the original selected particles after digitization inputMeasurementParticlesMap=digiAlg.config. outputMeasurementParticlesMap, filePath=str(outputDir / "performance_seeding_trees.root"), ) s.addWriter(trackFinderPerformanceWriter) # Estimate track parameters from seeds paramEstimation = acts.examples.TrackParamsEstimationAlgorithm( level=acts.logging.INFO, inputSeeds=inputSeeds, inputProtoTracks=inputProtoTracks, inputSpacePoints=[spAlg.config.outputSpacePoints], inputSourceLinks=digiCfg.outputSourceLinks, outputTrackParameters="estimatedparameters", outputProtoTracks="prototracks_estimated", trackingGeometry=trackingGeometry, magneticField=field, bFieldMin=0.1 * u.T, deltaRMax=100.0 * u.mm, deltaRMin=10.0 * u.mm, sigmaLoc0=25.0 * u.um, sigmaLoc1=100.0 * u.um, sigmaPhi=0.02 * u.degree, sigmaTheta=0.02 * u.degree, sigmaQOverP=0.1 / 1.0 * u.GeV, sigmaT0=1400.0 * u.s, initialVarInflation=[1, 1, 1, 1, 1, 1], ) s.addAlgorithm(paramEstimation) outputTrackParameters = paramEstimation.config.outputTrackParameters # Setup the track finding algorithm with CKF # It takes all the source links created from truth hit smearing, seeds from # truth particle smearing and source link selection config trackFinder = acts.examples.TrackFindingAlgorithm( level=acts.logging.INFO, measurementSelectorCfg=acts.MeasurementSelector.Config([ (acts.GeometryIdentifier(), ([], [15.0], [10])) ]), inputMeasurements=digiAlg.config.outputMeasurements, inputSourceLinks=digiAlg.config.outputSourceLinks, inputInitialTrackParameters=outputTrackParameters, outputTrajectories="trajectories", findTracks=acts.examples.TrackFindingAlgorithm.makeTrackFinderFunction( trackingGeometry, field), ) s.addAlgorithm(trackFinder) # write track states from CKF trackStatesWriter = acts.examples.RootTrajectoryStatesWriter( level=acts.logging.INFO, inputTrajectories=trackFinder.config.outputTrajectories, # @note The full particles collection is used here to avoid lots of warnings # since the unselected CKF track might have a majority particle not in the # filtered particle collection. This could be avoided when a seperate track # selection algorithm is used. inputParticles=selector.config.outputParticles, inputSimHits=simAlg.config.outputSimHits, inputMeasurementParticlesMap=digiAlg.config. outputMeasurementParticlesMap, inputMeasurementSimHitsMap=digiAlg.config.outputMeasurementSimHitsMap, filePath=str(outputDir / "trackstates_ckf.root"), treeName="trackstates", ) s.addWriter(trackStatesWriter) # write track summary from CKF trackSummaryWriter = acts.examples.RootTrajectorySummaryWriter( level=acts.logging.INFO, inputTrajectories=trackFinder.config.outputTrajectories, # @note The full particles collection is used here to avoid lots of warnings # since the unselected CKF track might have a majority particle not in the # filtered particle collection. This could be avoided when a seperate track # selection algorithm is used. inputParticles=selector.config.outputParticles, inputMeasurementParticlesMap=digiAlg.config. outputMeasurementParticlesMap, filePath=str(outputDir / "tracksummary_ckf.root"), treeName="tracksummary", ) s.addWriter(trackSummaryWriter) # Write CKF performance data ckfPerfWriter = acts.examples.CKFPerformanceWriter( level=acts.logging.INFO, inputParticles=inputParticles, inputTrajectories=trackFinder.config.outputTrajectories, inputMeasurementParticlesMap=digiAlg.config. outputMeasurementParticlesMap, # The bottom seed could be the first, second or third hits on the truth track nMeasurementsMin=selAlg.config.nHitsMin - 3, ptMin=0.4 * u.GeV, filePath=str(outputDir / "performance_ckf.root"), ) s.addWriter(ckfPerfWriter) if outputCsv: csv_dir = outputDir / "csv" csv_dir.mkdir(parents=True, exist_ok=True) logger.info("Writing CSV files") csvMTJWriter = acts.examples.CsvMultiTrajectoryWriter( level=acts.logging.INFO, inputTrajectories=trackFinder.config.outputTrajectories, inputMeasurementParticlesMap=digiAlg.config. outputMeasurementParticlesMap, outputDir=str(csv_dir), ) s.addWriter(csvMTJWriter) return s
def addPythia8( s: acts.examples.Sequencer, rnd: Optional[acts.examples.RandomNumbers] = None, nhard: int = 1, npileup: int = 200, beam: Optional[ Union[acts.PdgParticle, Iterable]] = None, # default: acts.PdgParticle.eProton cmsEnergy: Optional[float] = None, # default: 14 * acts.UnitConstants.TeV hardProcess: Optional[Iterable] = None, # default: ["HardQCD:all = on"] pileupProcess: Iterable = ["SoftQCD:all = on"], vtxGen: Optional[acts.examples.EventGenerator.VertexGenerator] = None, outputDirCsv: Optional[Union[Path, str]] = None, outputDirRoot: Optional[Union[Path, str]] = None, printParticles: bool = False, returnEvGen: bool = False, ) -> Union[acts.examples.Sequencer, acts.examples.EventGenerator]: """This function steers the particle generation using Pythia8 NB. this is a reimplementation of common.addPythia8, which is maintained for now for compatibility. Parameters ---------- s: Sequencer the sequencer module to which we add the particle gun steps (returned from addParticleGun) rnd : RandomNumbers, None random number generator nhard, npileup : int, 1, 200 Number of hard-scatter and pileup vertices beam : PdgParticle|[PdgParticle,PdgParticle], eProton beam particle(s) cmsEnergy : float, 14 TeV CMS energy hardProcess, pileupProcess : [str], ["HardQCD:all = on"], ["SoftQCD:all = on"] hard and pileup processes vtxGen : VertexGenerator, None vertex generator module outputDirCsv : Path|str, path, None the output folder for the Csv output, None triggers no output outputDirRoot : Path|str, path, None the output folder for the Root output, None triggers no output printParticles : bool, False print generated particles returnEvGen: bool, False returns EventGenerator instead of Sequencer. This option is included for compatibility and will be removed when common.addPythia8 is removed. """ if int(s.config.logLevel) <= int(acts.logging.DEBUG): acts.examples.dump_args_calls(locals()) # Preliminaries rnd = rnd or acts.examples.RandomNumbers() vtxGen = vtxGen or acts.examples.GaussianVertexGenerator( stddev=acts.Vector4(0, 0, 0, 0), mean=acts.Vector4(0, 0, 0, 0)) if not isinstance(beam, Iterable): beam = (beam, beam) generators = [] if nhard is not None and nhard > 0: generators.append( acts.examples.EventGenerator.Generator( multiplicity=acts.examples.FixedMultiplicityGenerator(n=nhard), vertex=vtxGen, particles=acts.examples.pythia8.Pythia8Generator( level=s.config.logLevel, **acts.examples.defaultKWArgs( pdgBeam0=beam[0], pdgBeam1=beam[1], cmsEnergy=cmsEnergy, settings=hardProcess, ), ), )) if npileup > 0: generators.append( acts.examples.EventGenerator.Generator( multiplicity=acts.examples.FixedMultiplicityGenerator( n=npileup), vertex=vtxGen, particles=acts.examples.pythia8.Pythia8Generator( level=s.config.logLevel, **acts.examples.defaultKWArgs( pdgBeam0=beam[0], pdgBeam1=beam[1], cmsEnergy=cmsEnergy, settings=pileupProcess, ), ), )) # Input evGen = acts.examples.EventGenerator( level=s.config.logLevel, generators=generators, outputParticles="particles_input", randomNumbers=rnd, ) s.addReader(evGen) if printParticles: s.addAlgorithm( acts.examples.ParticlesPrinter( level=s.config.logLevel, inputParticles=evGen.config.outputParticles)) if outputDirCsv is not None: outputDirCsv = Path(outputDirCsv) if not outputDirCsv.exists(): outputDirCsv.mkdir() s.addWriter( acts.examples.CsvParticleWriter( level=s.config.logLevel, inputParticles=evGen.config.outputParticles, outputDir=str(outputDirCsv), outputStem="particles", )) if outputDirRoot is not None: outputDirRoot = Path(outputDirRoot) if not outputDirRoot.exists(): outputDirRoot.mkdir() s.addWriter( acts.examples.RootParticleWriter( level=s.config.logLevel, inputParticles=evGen.config.outputParticles, filePath=str(outputDirRoot / "pythia8_particles.root"), )) return evGen if returnEvGen else s
def addParticleGun( s: Sequencer, outputDirCsv: Optional[Union[Path, str]] = None, outputDirRoot: Optional[Union[Path, str]] = None, momentumConfig: MomentumConfig = MomentumConfig(), etaConfig: EtaConfig = EtaConfig(), phiConfig: PhiConfig = PhiConfig(), particleConfig: ParticleConfig = ParticleConfig(), multiplicity: int = 1, vtxGen: Optional[EventGenerator.VertexGenerator] = None, printParticles: bool = False, rnd: Optional[RandomNumbers] = None, ) -> Sequencer: """This function steers the particle generation using the particle gun Parameters ---------- s: Sequencer the sequencer module to which we add the particle gun steps (returned from addParticleGun) outputDirCsv : Path|str, path, None the output folder for the Csv output, None triggers no output outputDirRoot : Path|str, path, None the output folder for the Root output, None triggers no output momentumConfig : MomentumConfig(min, max, transverse) momentum configuration: minimum momentum, maximum momentum, transverse etaConfig : EtaConfig(min, max, uniform) pseudorapidity configuration: eta min, eta max, uniform phiConfig : PhiConfig(min, max) azimuthal angle configuration: phi min, phi max particleConfig : ParticleConfig(num, pdg, randomizeCharge) partilce configuration: number of particles, particle type, charge flip multiplicity : int, 1 number of generated vertices vtxGen : VertexGenerator, None vertex generator module printParticles : bool, False print generated particles rnd : RandomNumbers, None random number generator """ if int(s.config.logLevel) <= int(acts.logging.DEBUG): acts.examples.dump_args_calls(locals()) # Preliminaries rnd = rnd or RandomNumbers(seed=228) # Input evGen = EventGenerator( level=s.config.logLevel, generators=[ EventGenerator.Generator( multiplicity=FixedMultiplicityGenerator(n=multiplicity), vertex=vtxGen or acts.examples.GaussianVertexGenerator( stddev=acts.Vector4(0, 0, 0, 0), mean=acts.Vector4(0, 0, 0, 0) ), particles=acts.examples.ParametricParticleGenerator( **acts.examples.defaultKWArgs( p=(momentumConfig.min, momentumConfig.max), pTransverse=momentumConfig.transverse, eta=(etaConfig.min, etaConfig.max), phi=(phiConfig.min, phiConfig.max), etaUniform=etaConfig.uniform, numParticles=particleConfig.num, pdg=particleConfig.pdg, randomizeCharge=particleConfig.randomizeCharge, ) ), ) ], outputParticles="particles_input", randomNumbers=rnd, ) s.addReader(evGen) if printParticles: s.addAlgorithm( ParticlesPrinter( level=s.config.logLevel, inputParticles=evGen.config.outputParticles ) ) if outputDirCsv is not None: outputDirCsv = Path(outputDirCsv) if not outputDirCsv.exists(): outputDirCsv.mkdir() s.addWriter( CsvParticleWriter( level=s.config.logLevel, inputParticles=evGen.config.outputParticles, outputDir=str(outputDirCsv), outputStem="particles", ) ) if outputDirRoot is not None: outputDirRoot = Path(outputDirRoot) if not outputDirRoot.exists(): outputDirRoot.mkdir() s.addWriter( RootParticleWriter( level=s.config.logLevel, inputParticles=evGen.config.outputParticles, filePath=str(outputDirRoot / "particles.root"), ) ) return s
def runFatras(trackingGeometry, field, outputDir, s: acts.examples.Sequencer = None): # Preliminaries rnd = acts.examples.RandomNumbers() # Input vtxGen = acts.examples.GaussianVertexGenerator() vtxGen.stddev = acts.Vector4(0, 0, 0, 0) ptclGen = acts.examples.ParametricParticleGenerator(p=(1 * u.GeV, 10 * u.GeV), eta=(-2, 2)) g = acts.examples.EventGenerator.Generator() g.multiplicity = acts.examples.FixedMultiplicityGenerator() g.vertex = vtxGen g.particles = ptclGen evGen = acts.examples.EventGenerator( level=acts.logging.INFO, generators=[g], outputParticles="particles_input", randomNumbers=rnd, ) # Selector selector = acts.examples.ParticleSelector( level=acts.logging.INFO, inputParticles=evGen.config.outputParticles, outputParticles="particles_selected", ) # Simulation alg = acts.examples.FatrasSimulation( level=acts.logging.INFO, inputParticles=selector.config.outputParticles, outputParticlesInitial="particles_initial", outputParticlesFinal="particles_final", outputSimHits="simhits", randomNumbers=rnd, trackingGeometry=trackingGeometry, magneticField=field, generateHitsOnSensitive=True, ) # Sequencer s = s or acts.examples.Sequencer( events=100, numThreads=-1, logLevel=acts.logging.INFO) s.addReader(evGen) s.addAlgorithm(selector) s.addAlgorithm(alg) # Output s.addWriter( acts.examples.CsvParticleWriter( level=acts.logging.INFO, outputDir=outputDir + "/csv", inputParticles="particles_final", outputStem="particles_final", )) s.addWriter( acts.examples.RootParticleWriter( level=acts.logging.INFO, inputParticles="particles_final", filePath=outputDir + "/fatras_particles_final.root", )) s.addWriter( acts.examples.CsvParticleWriter( level=acts.logging.INFO, outputDir=outputDir + "/csv", inputParticles="particles_initial", outputStem="particles_initial", )) s.addWriter( acts.examples.RootParticleWriter( level=acts.logging.INFO, inputParticles="particles_initial", filePath=outputDir + "/fatras_particles_initial.root", )) s.addWriter( acts.examples.CsvSimHitWriter( level=acts.logging.INFO, inputSimHits=alg.config.outputSimHits, outputDir=outputDir + "/csv", outputStem="hits", )) s.addWriter( acts.examples.RootSimHitWriter( level=acts.logging.INFO, inputSimHits=alg.config.outputSimHits, filePath=outputDir + "/hits.root", )) return s
def configureDigitization( trackingGeometry, field, outputDir: Path, particlesInput: Optional[Path] = None, outputRoot=True, outputCsv=True, s=None, ): srcdir = Path(__file__).resolve().parent.parent.parent.parent csv_dir = os.path.join(outputDir, "csv") if not os.path.exists(csv_dir): os.mkdir(csv_dir) # Input rnd = acts.examples.RandomNumbers(seed=42) particleCollection = "particles_input" if particlesInput is None: evGen = acts.examples.EventGenerator( level=acts.logging.INFO, generators=[ acts.examples.EventGenerator.Generator( multiplicity=acts.examples.FixedMultiplicityGenerator(n=2), vertex=acts.examples.GaussianVertexGenerator( stddev=acts.Vector4(0, 0, 0, 0), mean=acts.Vector4(0, 0, 0, 0) ), particles=acts.examples.ParametricParticleGenerator( p=(1 * u.GeV, 10 * u.GeV), eta=(-2, 2), phi=(0, 360 * u.degree), randomizeCharge=True, numParticles=4, ), ) ], outputParticles=particleCollection, randomNumbers=rnd, ) else: # Read input from input collection (e.g. Pythia8 output) evGen = acts.examples.RootParticleReader( level=acts.logging.INFO, particleCollection=particleCollection, filePath=str(particlesInput), orderedEvents=False, ) # Simulation simAlg = acts.examples.FatrasSimulation( level=acts.logging.INFO, inputParticles=particleCollection, outputParticlesInitial="particles_initial", outputParticlesFinal="particles_final", outputSimHits="simhits", randomNumbers=rnd, trackingGeometry=trackingGeometry, magneticField=field, generateHitsOnSensitive=True, ) # Digitization digiCfg = acts.examples.DigitizationConfig( acts.examples.readDigiConfigFromJson( str( srcdir / "Examples/Algorithms/Digitization/share/default-smearing-config-generic.json" ) ), trackingGeometry=trackingGeometry, randomNumbers=rnd, inputSimHits=simAlg.config.outputSimHits, ) digiAlg = acts.examples.DigitizationAlgorithm(digiCfg, acts.logging.INFO) s = s or acts.examples.Sequencer( events=100, numThreads=-1, logLevel=acts.logging.INFO ) s.addReader(evGen) s.addAlgorithm(simAlg) s.addAlgorithm(digiAlg) if outputRoot: rmwConfig = acts.examples.RootMeasurementWriter.Config( inputMeasurements=digiAlg.config.outputMeasurements, inputClusters=digiAlg.config.outputClusters, inputSimHits=simAlg.config.outputSimHits, inputMeasurementSimHitsMap=digiAlg.config.outputMeasurementSimHitsMap, filePath=str(outputDir / f"{digiAlg.config.outputMeasurements}.root"), trackingGeometry=trackingGeometry, ) rmwConfig.addBoundIndicesFromDigiConfig(digiAlg.config) s.addWriter(acts.examples.RootMeasurementWriter(rmwConfig, acts.logging.INFO)) if outputCsv: csv_dir = outputDir / "csv" csv_dir.mkdir(parents=True, exist_ok=True) s.addWriter( acts.examples.CsvMeasurementWriter( level=acts.logging.VERBOSE, inputMeasurements=digiAlg.config.outputMeasurements, inputClusters=digiAlg.config.outputClusters, inputSimHits=simAlg.config.outputSimHits, inputMeasurementSimHitsMap=digiAlg.config.outputMeasurementSimHitsMap, outputDir=str(csv_dir), ) ) return s