File indexing completed on 2026-08-17 08:19:24
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 from pathlib import Path
0011
0012 import acts
0013 import acts.examples
0014 from acts import UnitConstants as u
0015
0016
0017 def runPypiFindingFittingDemo(
0018 trackingGeometry,
0019 field,
0020 digiConfigFile,
0021 geoSelectionConfigFile,
0022 outputDir,
0023 decorators=[],
0024 s=None,
0025 ):
0026 from acts.examples.simulation import (
0027 addParticleGun,
0028 MomentumConfig,
0029 EtaConfig,
0030 PhiConfig,
0031 ParticleConfig,
0032 addFatras,
0033 addDigitization,
0034 )
0035
0036 s = s or acts.examples.Sequencer(events=1, numThreads=1, logLevel=acts.logging.INFO)
0037 outputDir = Path(outputDir)
0038 rnd = acts.examples.RandomNumbers(seed=42)
0039
0040 for d in decorators:
0041 s.addContextDecorator(d)
0042
0043 addParticleGun(
0044 s,
0045 MomentumConfig(1.0 * u.GeV, 10.0 * u.GeV, transverse=True),
0046 EtaConfig(-2.0, 2.0, uniform=True),
0047 PhiConfig(0.0, 360.0 * u.degree),
0048 ParticleConfig(1, acts.PdgParticle.eMuon, randomizeCharge=True),
0049 rnd=rnd,
0050 )
0051
0052 addFatras(
0053 s,
0054 trackingGeometry,
0055 field,
0056 rnd=rnd,
0057 )
0058
0059 addDigitization(
0060 s,
0061 trackingGeometry,
0062 field,
0063 digiConfigFile=digiConfigFile,
0064 rnd=rnd,
0065 )
0066
0067 s.addAlgorithm(
0068 acts.examples.SpacePointMaker(
0069 level=acts.logging.INFO,
0070 trackingGeometry=trackingGeometry,
0071 inputMeasurements="measurement_subset",
0072 outputSpacePoints="spacepoints",
0073 geometrySelection=acts.examples.json.readJsonGeometryList(
0074 str(geoSelectionConfigFile)
0075 ),
0076 )
0077 )
0078
0079
0080 class PythonTrackFinder(acts.examples.IAlgorithm):
0081 def __init__(self, name, level):
0082 acts.examples.IAlgorithm.__init__(self, name, level)
0083
0084 self.spacepoints = acts.examples.ReadDataHandle(
0085 self, acts.SpacePointContainer, "Spacepoints"
0086 )
0087 self.spacepoints.initialize("spacepoints")
0088
0089 self.prototracks = acts.examples.WriteDataHandle(
0090 self, acts.examples.ProtoTrackContainer, "Prototracks"
0091 )
0092 self.prototracks.initialize("prototracks")
0093
0094 def execute(self, context):
0095 spacepoints = self.spacepoints(context.eventStore)
0096
0097 track = acts.examples.ProtoTrack()
0098 for sp in sorted(spacepoints, key=lambda sp: sp.r):
0099 for sl in sp.sourceLinks:
0100 isl = acts.examples.IndexSourceLink.fromSourceLink(sl)
0101 track.append(isl.index())
0102
0103 prototracks = acts.examples.ProtoTrackContainer()
0104 prototracks.append(track)
0105
0106 self.prototracks(context, prototracks)
0107 return acts.examples.ProcessCode.SUCCESS
0108
0109 s.addAlgorithm(PythonTrackFinder("PythonTrackFinder", acts.logging.INFO))
0110
0111
0112 truthTrkFndAlg = acts.examples.TruthTrackFinder(
0113 level=acts.logging.INFO,
0114 inputParticles="particles_generated_selected",
0115 inputMeasurements="measurements",
0116 inputParticleMeasurementsMap="particle_measurements_map",
0117 inputSimHits="simhits",
0118 inputMeasurementSimHitsMap="measurement_simhits_map",
0119 outputProtoTracks="prototracks",
0120 )
0121
0122
0123 class PythonTrackFitter(acts.examples.IAlgorithm):
0124 def __init__(self, name, level):
0125 acts.examples.IAlgorithm.__init__(self, name, level)
0126
0127 self.prototracks = acts.examples.ReadDataHandle(
0128 self, acts.examples.ProtoTrackContainer, "Prototracks"
0129 )
0130 self.prototracks.initialize("prototracks")
0131
0132 self.tracks = acts.examples.WriteDataHandle(
0133 self, acts.examples.ConstTrackContainer, "Tracks"
0134 )
0135 self.tracks.initialize("fitted_tracks")
0136
0137 self.spacepoints = acts.examples.ReadDataHandle(
0138 self, acts.SpacePointContainer, "Spacepoints"
0139 )
0140 self.spacepoints.initialize("spacepoints")
0141
0142 def execute(self, context):
0143 prototracks = self.prototracks(context.eventStore)
0144 spacepoints = self.spacepoints(context.eventStore)
0145
0146 measurement_to_spacepoint = {}
0147 measurement_to_sourcelink = {}
0148 for sp in spacepoints:
0149 for sl in sp.sourceLinks:
0150 isl = acts.examples.IndexSourceLink.fromSourceLink(sl)
0151 meas_id = isl.index()
0152 measurement_to_spacepoint[meas_id] = sp
0153 measurement_to_sourcelink[meas_id] = sl
0154 surface_map = trackingGeometry.geoIdSurfaceMap()
0155
0156 container = acts.examples.TrackContainer()
0157 for prototrack in prototracks:
0158 track = container.makeTrack()
0159 track.parameters = acts.BoundVector(1.0, 1.0, 1.0, 1.0, 1.0, 1.0)
0160 track.nMeasurements = len(prototrack)
0161
0162 for meas_id in prototrack:
0163 sp = measurement_to_spacepoint[meas_id]
0164 sl = measurement_to_sourcelink[meas_id]
0165 isl = acts.examples.IndexSourceLink.fromSourceLink(sl)
0166 sf = surface_map[isl.geometryId()]
0167
0168 trackState = track.appendTrackState()
0169 trackState.typeFlags.isMeasurement = True
0170 trackState.uncalibratedSourceLink = sl
0171 trackState.referenceSurface = sf
0172
0173 self.tracks(context, container.makeConst())
0174 return acts.examples.ProcessCode.SUCCESS
0175
0176 s.addAlgorithm(PythonTrackFitter("PythonTrackFitter", acts.logging.INFO))
0177
0178 s.addAlgorithm(
0179 acts.examples.TrackTruthMatcher(
0180 level=acts.logging.INFO,
0181 inputTracks="fitted_tracks",
0182 inputParticles="particles",
0183 inputMeasurementParticlesMap="measurement_particles_map",
0184 outputTrackParticleMatching="track_particle_matching",
0185 outputParticleTrackMatching="particle_track_matching",
0186 doubleMatching=True,
0187 )
0188 )
0189
0190
0191 cfg_finder = acts.examples.PythonPatternRecognitionPerformanceWriter.Config()
0192 cfg_finder.inputTracks = "fitted_tracks"
0193 cfg_finder.inputParticles = "particles"
0194 cfg_finder.inputTrackParticleMatching = "track_particle_matching"
0195 cfg_finder.inputParticleTrackMatching = "particle_track_matching"
0196 cfg_finder.inputParticleMeasurementsMap = "particle_measurements_map"
0197 perfWriterFinder = acts.examples.PythonPatternRecognitionPerformanceWriter(
0198 cfg_finder, acts.logging.INFO
0199 )
0200 s.addWriter(perfWriterFinder)
0201
0202
0203 cfg_fitter = acts.examples.PythonTrackParameterPerformanceWriter.Config()
0204 cfg_fitter.inputTracks = "fitted_tracks"
0205 cfg_fitter.inputParticles = "particles"
0206 cfg_fitter.inputTrackParticleMatching = "track_particle_matching"
0207 perfWriterFitter = acts.examples.PythonTrackParameterPerformanceWriter(
0208 cfg_fitter, acts.logging.INFO
0209 )
0210 s.addWriter(perfWriterFitter)
0211
0212 return s, perfWriterFinder, perfWriterFitter
0213
0214
0215 if __name__ == "__main__":
0216 srcdir = Path(__file__).resolve().parent.parent.parent.parent
0217
0218 detector = acts.examples.GenericDetector(acts.examples.GenericDetector.Config())
0219 trackingGeometry = detector.trackingGeometry()
0220 decorators = detector.contextDecorators()
0221
0222 field = acts.ConstantBField(acts.Vector3(0.0, 0.0, 2.0 * u.T))
0223
0224 digiConfigFile = srcdir / "Examples/Configs/generic-digi-smearing-config.json"
0225 geoSelectionConfigFile = (
0226 srcdir / "Examples/Configs/generic-pixel-sstrips-lstrips-spacepoints.json"
0227 )
0228
0229 outputDir = Path.cwd() / "output_pypi_finding_fitting_demo"
0230 outputDir.mkdir(exist_ok=True)
0231
0232 s, perfWriterFinder, perfWriterFitter = runPypiFindingFittingDemo(
0233 trackingGeometry=trackingGeometry,
0234 field=field,
0235 digiConfigFile=digiConfigFile,
0236 geoSelectionConfigFile=geoSelectionConfigFile,
0237 outputDir=outputDir,
0238 decorators=decorators,
0239 )
0240 s.run()
0241
0242 histograms_finder = perfWriterFinder.histograms()
0243 print(
0244 f"Retrieved {len(histograms_finder)} finder performance histograms: {list(histograms_finder.keys())}"
0245 )
0246
0247 histograms_fitter = perfWriterFitter.histograms()
0248 print(
0249 f"Retrieved {len(histograms_fitter)} fitter performance histograms: {list(histograms_fitter.keys())}"
0250 )