Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:10:07

0001 import pytest
0002 import os
0003 from pathlib import Path
0004 import multiprocessing
0005 
0006 from helpers import (
0007     geant4Enabled,
0008     edm4hepEnabled,
0009     AssertCollectionExistsAlg,
0010 )
0011 
0012 import acts
0013 from acts import PlanarModuleStepper, UnitConstants as u
0014 from acts.examples import (
0015     RootParticleWriter,
0016     RootParticleReader,
0017     RootMaterialTrackReader,
0018     RootTrackSummaryReader,
0019     CsvParticleWriter,
0020     CsvParticleReader,
0021     CsvMeasurementWriter,
0022     CsvMeasurementReader,
0023     CsvSimHitWriter,
0024     CsvSimHitReader,
0025     CsvPlanarClusterWriter,
0026     CsvPlanarClusterReader,
0027     PlanarSteppingAlgorithm,
0028     Sequencer,
0029 )
0030 from acts.examples.odd import getOpenDataDetector, getOpenDataDetectorDirectory
0031 
0032 
0033 @pytest.mark.root
0034 def test_root_particle_reader(tmp_path, conf_const, ptcl_gun):
0035     # need to write out some particles first
0036     s = Sequencer(numThreads=1, events=10, logLevel=acts.logging.WARNING)
0037     evGen = ptcl_gun(s)
0038 
0039     file = tmp_path / "particles.root"
0040     s.addWriter(
0041         conf_const(
0042             RootParticleWriter,
0043             acts.logging.WARNING,
0044             inputParticles=evGen.config.outputParticles,
0045             filePath=str(file),
0046         )
0047     )
0048 
0049     s.run()
0050 
0051     del s  # to properly close the root file
0052 
0053     # reset sequencer for reading
0054 
0055     s2 = Sequencer(numThreads=1, logLevel=acts.logging.WARNING)
0056 
0057     s2.addReader(
0058         conf_const(
0059             RootParticleReader,
0060             acts.logging.WARNING,
0061             outputParticles="particles_input",
0062             filePath=str(file),
0063         )
0064     )
0065 
0066     alg = AssertCollectionExistsAlg(
0067         "particles_input", "check_alg", acts.logging.WARNING
0068     )
0069     s2.addAlgorithm(alg)
0070 
0071     s2.run()
0072 
0073     assert alg.events_seen == 10
0074 
0075 
0076 @pytest.mark.csv
0077 def test_csv_particle_reader(tmp_path, conf_const, ptcl_gun):
0078     s = Sequencer(numThreads=1, events=10, logLevel=acts.logging.WARNING)
0079     evGen = ptcl_gun(s)
0080 
0081     out = tmp_path / "csv"
0082 
0083     out.mkdir()
0084 
0085     s.addWriter(
0086         conf_const(
0087             CsvParticleWriter,
0088             acts.logging.WARNING,
0089             inputParticles=evGen.config.outputParticles,
0090             outputStem="particle",
0091             outputDir=str(out),
0092         )
0093     )
0094 
0095     s.run()
0096 
0097     # reset the seeder
0098     s = Sequencer(numThreads=1, logLevel=acts.logging.WARNING)
0099 
0100     s.addReader(
0101         conf_const(
0102             CsvParticleReader,
0103             acts.logging.WARNING,
0104             inputDir=str(out),
0105             inputStem="particle",
0106             outputParticles="input_particles",
0107         )
0108     )
0109 
0110     alg = AssertCollectionExistsAlg(
0111         "input_particles", "check_alg", acts.logging.WARNING
0112     )
0113 
0114     s.addAlgorithm(alg)
0115 
0116     s.run()
0117 
0118     assert alg.events_seen == 10
0119 
0120 
0121 @pytest.mark.parametrize(
0122     "reader",
0123     [RootParticleReader, RootTrackSummaryReader],
0124 )
0125 @pytest.mark.root
0126 def test_root_reader_interface(reader, conf_const, tmp_path):
0127     assert hasattr(reader, "Config")
0128 
0129     config = reader.Config
0130 
0131     assert hasattr(config, "filePath")
0132 
0133     kw = {"level": acts.logging.INFO, "filePath": str(tmp_path / "file.root")}
0134 
0135     assert conf_const(reader, **kw)
0136 
0137 
0138 @pytest.mark.slow
0139 @pytest.mark.root
0140 @pytest.mark.odd
0141 @pytest.mark.skipif(not geant4Enabled, reason="Geant4 not set up")
0142 def test_root_material_track_reader(material_recording):
0143     input_tracks = material_recording / "geant4_material_tracks.root"
0144     assert input_tracks.exists()
0145 
0146     s = Sequencer(numThreads=1)
0147 
0148     s.addReader(
0149         RootMaterialTrackReader(
0150             level=acts.logging.INFO,
0151             fileList=[str(input_tracks)],
0152             outputMaterialTracks="material-tracks",
0153         )
0154     )
0155 
0156     alg = AssertCollectionExistsAlg(
0157         "material-tracks", "check_alg", acts.logging.WARNING
0158     )
0159     s.addAlgorithm(alg)
0160 
0161     s.run()
0162 
0163     assert alg.events_seen == 2
0164 
0165 
0166 @pytest.mark.csv
0167 def test_csv_meas_reader(tmp_path, fatras, trk_geo, conf_const):
0168     s = Sequencer(numThreads=1, events=10)
0169     evGen, simAlg, digiAlg = fatras(s)
0170 
0171     out = tmp_path / "csv"
0172     out.mkdir()
0173 
0174     s.addWriter(
0175         CsvMeasurementWriter(
0176             level=acts.logging.INFO,
0177             inputMeasurements=digiAlg.config.outputMeasurements,
0178             inputClusters=digiAlg.config.outputClusters,
0179             inputMeasurementSimHitsMap=digiAlg.config.outputMeasurementSimHitsMap,
0180             outputDir=str(out),
0181         )
0182     )
0183 
0184     # Write hits, so we can later construct the measurement-particles-map
0185     s.addWriter(
0186         CsvSimHitWriter(
0187             level=acts.logging.INFO,
0188             inputSimHits=simAlg.config.outputSimHits,
0189             outputDir=str(out),
0190             outputStem="hits",
0191         )
0192     )
0193 
0194     s.run()
0195 
0196     # read back in
0197     s = Sequencer(numThreads=1)
0198 
0199     s.addReader(
0200         CsvSimHitReader(
0201             level=acts.logging.INFO,
0202             outputSimHits=simAlg.config.outputSimHits,
0203             inputDir=str(out),
0204             inputStem="hits",
0205         )
0206     )
0207 
0208     s.addReader(
0209         conf_const(
0210             CsvMeasurementReader,
0211             level=acts.logging.WARNING,
0212             outputMeasurements="measurements",
0213             outputMeasurementSimHitsMap="simhitsmap",
0214             outputSourceLinks="sourcelinks",
0215             outputMeasurementParticlesMap="meas_ptcl_map",
0216             inputSimHits=simAlg.config.outputSimHits,
0217             inputDir=str(out),
0218         )
0219     )
0220 
0221     algs = [
0222         AssertCollectionExistsAlg(k, f"check_alg_{k}", acts.logging.WARNING)
0223         for k in ("measurements", "simhitsmap", "sourcelinks", "meas_ptcl_map")
0224     ]
0225     for alg in algs:
0226         s.addAlgorithm(alg)
0227 
0228     s.run()
0229 
0230     for alg in algs:
0231         assert alg.events_seen == 10
0232 
0233 
0234 @pytest.mark.csv
0235 def test_csv_simhits_reader(tmp_path, fatras, conf_const):
0236     s = Sequencer(numThreads=1, events=10)
0237     evGen, simAlg, digiAlg = fatras(s)
0238 
0239     out = tmp_path / "csv"
0240     out.mkdir()
0241 
0242     s.addWriter(
0243         CsvSimHitWriter(
0244             level=acts.logging.INFO,
0245             inputSimHits=simAlg.config.outputSimHits,
0246             outputDir=str(out),
0247             outputStem="hits",
0248         )
0249     )
0250 
0251     s.run()
0252 
0253     s = Sequencer(numThreads=1)
0254 
0255     s.addReader(
0256         conf_const(
0257             CsvSimHitReader,
0258             level=acts.logging.INFO,
0259             inputDir=str(out),
0260             inputStem="hits",
0261             outputSimHits="simhits",
0262         )
0263     )
0264 
0265     alg = AssertCollectionExistsAlg("simhits", "check_alg", acts.logging.WARNING)
0266     s.addAlgorithm(alg)
0267 
0268     s.run()
0269 
0270     assert alg.events_seen == 10
0271 
0272 
0273 @pytest.mark.csv
0274 def test_csv_clusters_reader(tmp_path, fatras, conf_const, trk_geo, rng):
0275     s = Sequencer(numThreads=1, events=10)  # we're not going to use this one
0276     evGen, simAlg, _ = fatras(s)
0277     s = Sequencer(numThreads=1, events=10)
0278     s.addReader(evGen)
0279     s.addAlgorithm(simAlg)
0280     digiAlg = PlanarSteppingAlgorithm(
0281         level=acts.logging.WARNING,
0282         inputSimHits=simAlg.config.outputSimHits,
0283         outputClusters="clusters",
0284         outputSourceLinks="sourcelinks",
0285         outputDigiSourceLinks="digiSourceLink",
0286         outputMeasurements="measurements",
0287         outputMeasurementParticlesMap="meas_ptcl_map",
0288         outputMeasurementSimHitsMap="meas_sh_map",
0289         trackingGeometry=trk_geo,
0290         randomNumbers=rng,
0291         planarModuleStepper=PlanarModuleStepper(),
0292     )
0293     s.addAlgorithm(digiAlg)
0294 
0295     out = tmp_path / "csv"
0296     out.mkdir()
0297 
0298     s.addWriter(
0299         CsvPlanarClusterWriter(
0300             level=acts.logging.WARNING,
0301             outputDir=str(out),
0302             inputSimHits=simAlg.config.outputSimHits,
0303             inputClusters=digiAlg.config.outputClusters,
0304             trackingGeometry=trk_geo,
0305         )
0306     )
0307 
0308     s.run()
0309 
0310     s = Sequencer(numThreads=1)
0311 
0312     s.addReader(
0313         conf_const(
0314             CsvPlanarClusterReader,
0315             level=acts.logging.WARNING,
0316             outputClusters="clusters",
0317             inputDir=str(out),
0318             outputHitIds="hits",
0319             outputMeasurementParticlesMap="meas_ptcl_map",
0320             outputSimHits="simhits",
0321             trackingGeometry=trk_geo,
0322         )
0323     )
0324 
0325     algs = [
0326         AssertCollectionExistsAlg(k, f"check_alg_{k}", acts.logging.WARNING)
0327         for k in ("clusters", "simhits", "meas_ptcl_map")
0328     ]
0329     for alg in algs:
0330         s.addAlgorithm(alg)
0331 
0332     s.run()
0333 
0334     for alg in algs:
0335         assert alg.events_seen == 10
0336 
0337 
0338 def generate_input_test_edm4hep_simhit_reader(input, output):
0339     from DDSim.DD4hepSimulation import DD4hepSimulation
0340 
0341     ddsim = DD4hepSimulation()
0342     if isinstance(ddsim.compactFile, list):
0343         ddsim.compactFile = [input]
0344     else:
0345         ddsim.compactFile = input
0346     ddsim.enableGun = True
0347     ddsim.gun.direction = (1, 0, 0)
0348     ddsim.gun.particle = "pi-"
0349     ddsim.gun.distribution = "eta"
0350     ddsim.numberOfEvents = 10
0351     ddsim.outputFile = output
0352     ddsim.run()
0353 
0354 
0355 @pytest.mark.slow
0356 @pytest.mark.edm4hep
0357 @pytest.mark.skipif(not edm4hepEnabled, reason="EDM4hep is not set up")
0358 def test_edm4hep_simhit_particle_reader(tmp_path):
0359     from acts.examples.edm4hep import EDM4hepReader
0360 
0361     tmp_file = str(tmp_path / "output_edm4hep.root")
0362     odd_xml_file = str(getOpenDataDetectorDirectory() / "xml" / "OpenDataDetector.xml")
0363 
0364     with multiprocessing.get_context("spawn").Pool() as pool:
0365         pool.apply(generate_input_test_edm4hep_simhit_reader, (odd_xml_file, tmp_file))
0366 
0367     assert os.path.exists(tmp_file)
0368 
0369     detector, trackingGeometry, decorators = getOpenDataDetector()
0370 
0371     s = Sequencer(numThreads=1)
0372 
0373     s.addReader(
0374         EDM4hepReader(
0375             level=acts.logging.INFO,
0376             inputPath=tmp_file,
0377             inputSimHits=[
0378                 "PixelBarrelReadout",
0379                 "PixelEndcapReadout",
0380                 "ShortStripBarrelReadout",
0381                 "ShortStripEndcapReadout",
0382                 "LongStripBarrelReadout",
0383                 "LongStripEndcapReadout",
0384             ],
0385             outputParticlesGenerator="particles_input",
0386             outputParticlesInitial="particles_initial",
0387             outputParticlesFinal="particles_final",
0388             outputSimHits="simhits",
0389             dd4hepDetector=detector,
0390             trackingGeometry=trackingGeometry,
0391         )
0392     )
0393 
0394     alg = AssertCollectionExistsAlg("simhits", "check_alg", acts.logging.WARNING)
0395     s.addAlgorithm(alg)
0396 
0397     alg = AssertCollectionExistsAlg(
0398         "particles_input", "check_alg", acts.logging.WARNING
0399     )
0400     s.addAlgorithm(alg)
0401 
0402     s.run()
0403 
0404     assert alg.events_seen == 10
0405 
0406 
0407 @pytest.mark.edm4hep
0408 @pytest.mark.skipif(not edm4hepEnabled, reason="EDM4hep is not set up")
0409 def test_edm4hep_measurement_reader(tmp_path, fatras, conf_const):
0410     from acts.examples.edm4hep import (
0411         EDM4hepMeasurementWriter,
0412         EDM4hepMeasurementReader,
0413     )
0414 
0415     s = Sequencer(numThreads=1, events=10)
0416     _, simAlg, digiAlg = fatras(s)
0417 
0418     out = tmp_path / "measurements_edm4hep.root"
0419 
0420     config = EDM4hepMeasurementWriter.Config(
0421         inputMeasurements=digiAlg.config.outputMeasurements,
0422         inputClusters=digiAlg.config.outputClusters,
0423         outputPath=str(out),
0424     )
0425     s.addWriter(EDM4hepMeasurementWriter(level=acts.logging.INFO, config=config))
0426     s.run()
0427 
0428     # read back in
0429     s = Sequencer(numThreads=1)
0430 
0431     s.addReader(
0432         conf_const(
0433             EDM4hepMeasurementReader,
0434             level=acts.logging.WARNING,
0435             outputMeasurements="measurements",
0436             outputMeasurementSimHitsMap="simhitsmap",
0437             outputSourceLinks="sourcelinks",
0438             inputPath=str(out),
0439         )
0440     )
0441 
0442     algs = [
0443         AssertCollectionExistsAlg(k, f"check_alg_{k}", acts.logging.WARNING)
0444         for k in ("measurements", "simhitsmap", "sourcelinks")
0445     ]
0446     for alg in algs:
0447         s.addAlgorithm(alg)
0448 
0449     s.run()
0450 
0451     for alg in algs:
0452         assert alg.events_seen == 10
0453 
0454 
0455 @pytest.mark.edm4hep
0456 @pytest.mark.skipif(not edm4hepEnabled, reason="EDM4hep is not set up")
0457 def test_edm4hep_tracks_reader(tmp_path):
0458     from acts.examples.edm4hep import EDM4hepTrackWriter, EDM4hepTrackReader
0459 
0460     detector, trackingGeometry, decorators = acts.examples.GenericDetector.create()
0461     field = acts.ConstantBField(acts.Vector3(0, 0, 2 * u.T))
0462 
0463     from truth_tracking_kalman import runTruthTrackingKalman
0464 
0465     s = Sequencer(numThreads=1, events=10)
0466     runTruthTrackingKalman(
0467         trackingGeometry,
0468         field,
0469         digiConfigFile=Path(
0470             str(
0471                 Path(__file__).parent.parent.parent.parent
0472                 / "Examples/Algorithms/Digitization/share/default-smearing-config-generic.json"
0473             )
0474         ),
0475         outputDir=tmp_path,
0476         s=s,
0477     )
0478 
0479     out = tmp_path / "tracks_edm4hep.root"
0480 
0481     s.addWriter(
0482         EDM4hepTrackWriter(
0483             level=acts.logging.VERBOSE,
0484             inputTracks="kf_tracks",
0485             outputPath=str(out),
0486             Bz=2 * u.T,
0487         )
0488     )
0489 
0490     s.run()
0491 
0492     del s
0493 
0494     s = Sequencer(numThreads=1)
0495     s.addReader(
0496         EDM4hepTrackReader(
0497             level=acts.logging.VERBOSE,
0498             outputTracks="kf_tracks",
0499             inputPath=str(out),
0500             Bz=2 * u.T,
0501         )
0502     )
0503 
0504     s.run()