Skip to content

Commit 2ff6769

Browse files
authored
Merge branch 'main' into feat-index-grid-navigation-policy
2 parents bb40f2e + 5a7d7c7 commit 2ff6769

File tree

13 files changed

+159
-73
lines changed

13 files changed

+159
-73
lines changed

CI/physmon/phys_perf_mon.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ echo "::group::Generate validation dataset"
142142
if [[ "$mode" == "all" || "$mode" == "simulation" ]]; then
143143
run_physmon_gen "Simulation" "simulation"
144144
fi
145+
if [[ "$mode" == "all" || "$mode" == "gsf" || "$mode" == "refit_gsf" ]]; then
146+
run_physmon_gen "Geant4 Sim for GSF" "simulation_gsf"
147+
fi
145148
if [[ "$mode" == "all" || "$mode" == "kf" ]]; then
146149
run_physmon_gen "Truth Tracking KF" "trackfitting_kf"
147150
fi
Binary file not shown.
Binary file not shown.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#!/usr/bin/env python3
2+
3+
from pathlib import Path
4+
import acts
5+
from acts.examples.simulation import (
6+
addParticleGun,
7+
ParticleConfig,
8+
EtaConfig,
9+
PhiConfig,
10+
MomentumConfig,
11+
addGeant4,
12+
)
13+
from physmon_common import makeSetup
14+
15+
u = acts.UnitConstants
16+
setup = makeSetup()
17+
18+
# Create output directory for simulation files
19+
outputDir = setup.outdir / "simulation"
20+
outputDir.mkdir(exist_ok=True)
21+
22+
# Single-threaded sequencer (Geant4 requirement)
23+
s = acts.examples.Sequencer(
24+
events=10000,
25+
numThreads=1, # Geant4 must run single-threaded
26+
logLevel=acts.logging.INFO,
27+
)
28+
29+
# Add context decorators
30+
for d in setup.decorators:
31+
s.addContextDecorator(d)
32+
33+
rnd = acts.examples.RandomNumbers(seed=42)
34+
35+
# Particle gun: electrons, matching truth_tracking_gsf.py configuration
36+
addParticleGun(
37+
s,
38+
ParticleConfig(num=1, pdg=acts.PdgParticle.eElectron, randomizeCharge=True),
39+
EtaConfig(-3.0, 3.0, uniform=True),
40+
MomentumConfig(1.0 * u.GeV, 100.0 * u.GeV, transverse=True),
41+
PhiConfig(0.0, 360.0 * u.degree),
42+
vtxGen=acts.examples.GaussianVertexGenerator(
43+
mean=acts.Vector4(0, 0, 0, 0),
44+
stddev=acts.Vector4(0, 0, 0, 0),
45+
),
46+
multiplicity=1,
47+
rnd=rnd,
48+
)
49+
50+
# Geant4 simulation
51+
addGeant4(
52+
s,
53+
setup.detector,
54+
setup.trackingGeometry,
55+
setup.field,
56+
rnd,
57+
killVolume=setup.trackingGeometry.highestTrackingVolume,
58+
killAfterTime=25 * u.ns,
59+
killSecondaries=True,
60+
outputDirRoot=outputDir, # Enable ROOT output
61+
)
62+
63+
# Run simulation
64+
s.run()
65+
66+
print(f"Simulation complete. Output files:")
67+
print(f" - {outputDir / 'particles_simulation.root'}")
68+
print(f" - {outputDir / 'hits.root'}")

CI/physmon/workflows/physmon_trackfitting_gsf.py

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,19 @@
1111

1212
setup = makeSetup()
1313

14+
# Paths to pre-simulated data (from physmon_simulation_gsf.py)
15+
simDir = (setup.outdir / "../simulation_gsf/simulation").resolve()
16+
particlesPath = simDir / "particles_simulation.root"
17+
simhitsPath = simDir / "hits.root"
18+
19+
# Verify simulation files exist
20+
assert particlesPath.exists(), f"Simulation not found: {particlesPath}"
21+
assert simhitsPath.exists(), f"SimHits not found: {simhitsPath}"
22+
1423
with tempfile.TemporaryDirectory() as temp:
1524
s = acts.examples.Sequencer(
1625
events=10000,
17-
numThreads=-1,
26+
numThreads=-1, # Multi-threaded now!
1827
logLevel=acts.logging.INFO,
1928
)
2029

@@ -24,6 +33,9 @@
2433
field=setup.field,
2534
digiConfigFile=setup.digiConfig,
2635
outputDir=tp,
36+
inputParticlePath=particlesPath,
37+
inputSimHitsPath=simhitsPath,
38+
decorators=setup.decorators,
2739
s=s,
2840
)
2941

CI/physmon/workflows/physmon_trackrefitting_gsf.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@
1111

1212
setup = makeSetup()
1313

14+
# Paths to pre-simulated data (same as fitting workflow)
15+
simDir = (setup.outdir / "../simulation_gsf/simulation").resolve()
16+
particlesPath = simDir / "particles_simulation.root"
17+
simhitsPath = simDir / "hits.root"
18+
19+
# Verify simulation files exist
20+
assert particlesPath.exists(), f"Simulation not found: {particlesPath}"
21+
assert simhitsPath.exists(), f"SimHits not found: {simhitsPath}"
22+
1423
with tempfile.TemporaryDirectory() as temp:
1524
s = acts.examples.Sequencer(
1625
events=10000,
@@ -24,6 +33,9 @@
2433
field=setup.field,
2534
digiConfigFile=setup.digiConfig,
2635
outputDir=tp,
36+
inputParticlePath=particlesPath,
37+
inputSimHitsPath=simhitsPath,
38+
decorators=setup.decorators,
2739
s=s,
2840
)
2941

CI/requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pygments==2.6.1
3131
# via rich
3232
pyjwt==1.7.1
3333
# via pygithub
34-
pyyaml==5.3.1
34+
pyyaml==5.4.1
3535
# via acts-ci (pyproject.toml)
3636
requests==2.24.0
3737
# via pygithub

Examples/Python/tests/root_file_hashes.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ test_truth_tracking_gsf[generic]__trackstates_gsf.root: 47c4028af2dae7127176f82c
2222
test_truth_tracking_gsf[generic]__tracksummary_gsf.root: 5e64bc5c31886f5ab520faae297e664edc22a3b27a128b2e10c8cc5cd176b1f7
2323
test_truth_tracking_gsf[odd]__trackstates_gsf.root: 715700df9f886412cbb2f066e83a593cf4869b3f6b15371ab43ed8bc9d7a0b57
2424
test_truth_tracking_gsf[odd]__tracksummary_gsf.root: 1d6110cf3410ee92153d3434f6ecd0a167d369499cd40b1a89122f974bda41d9
25+
test_refitting[generic]__trackstates_gsf_refit.root: 224e4f0fbe7db3732d1013fa59f360b12cae5a677242104911f4b6c7b49154a5
26+
test_refitting[generic]__tracksummary_gsf_refit.root: df16e25bd04488ba94887f378446c3edc29746d130871bae0cf2c6e3f1028829
27+
test_refitting[odd]__trackstates_gsf_refit.root: 2ce39e602f3b981d0cd54c999af6850096ea615fb6e7d17b7b4be445014b002d
28+
test_refitting[odd]__tracksummary_gsf_refit.root: 056fa6c6e8eaa1c927addacb48b61b1d157db965cc231943ee8919a3ed969811
2529
test_particle_gun__particles.root: 967b17b2b2c92126d82b847f65176b35024cbf12c1d6c1523abb8c1b6bc9dae4
2630
test_material_mapping__material-map_tracks.root: a01c5b2742ed0ff2d5ceeae8e2a06dd6f7748832538c475a3b2fdb725a39da73
2731
test_material_mapping__propagation-material.root: 8e8eb393b0a5d8a7fd9c1c6933cbe3a196b4e448a98f52740e34c50b95cc156a
@@ -75,10 +79,6 @@ test_gnn_metric_learning[gpu-torch]__performance_track_finding.root: 3f0fb36af55
7579
test_gnn_module_map[gpu-torch]__performance_track_finding.root: 52d513882c4cdf611de44fa074f6aebbb86e074b3325737643369571650a8c59
7680
test_gnn_module_map[gpu-onnx]__performance_track_finding.root: 9aba4205933817a1f16fe41a2c80363aaca2b74294204b90dc9d4ae8435feac5
7781
test_ML_Ambiguity_Solver__performance_finding_ambiML.root: c17fb877bb165e28db0a2b99881763093e7fc9a707c045feb6a6a6b68e0dd660
78-
test_refitting[generic]__trackstates_gsf_refit.root: 979e5aac75c4748d84be1144b8c63ba3b1b735dcd01c2f821b4b79eb12a967ca
79-
test_refitting[generic]__tracksummary_gsf_refit.root: 96ba5a474b25454cc8c00f8bf0116d3d8f8c316bbac0f9d2b8c08d89d46b240a
80-
test_refitting[odd]__trackstates_gsf_refit.root: bd2fde3872d74914cebfea98753b3323f683cc9be99865e43fdfe10b4ab87edc
81-
test_refitting[odd]__tracksummary_gsf_refit.root: 0d055ae3a68224a33fc3fed0074c39b651da79bb02b8d8822b673ec68498d0e9
8282
test_truth_tracking_kalman[generic-0.0]__trackstates_kf.root: 9039635bd998ee16ccdefdabcfea06070c96de39ce54ec2156d0404f825dbb76
8383
test_truth_tracking_kalman[generic-0.0]__tracksummary_kf.root: 1af2e6a94757eb158c216aa0456a915e062c3c900e70de831d01a7c89ea791ed
8484
test_truth_tracking_kalman[generic-1000.0]__trackstates_kf.root: ba26dc37428a7aff32671f2f646165d0807b4b44e1a8bf4c51c5d01ad0165515

Examples/Scripts/Python/truth_tracking_gsf.py

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55

66
import acts
77
import acts.examples
8+
from acts.examples.root import (
9+
RootParticleReader,
10+
RootSimHitReader,
11+
)
812

913
u = acts.UnitConstants
1014

@@ -15,6 +19,7 @@ def runTruthTrackingGsf(
1519
digiConfigFile: Path,
1620
outputDir: Path,
1721
inputParticlePath: Optional[Path] = None,
22+
inputSimHitsPath: Optional[Path] = None,
1823
decorators=[],
1924
s: acts.examples.Sequencer = None,
2025
):
@@ -51,6 +56,7 @@ def runTruthTrackingGsf(
5156

5257
rnd = acts.examples.RandomNumbers(seed=42)
5358
outputDir = Path(outputDir)
59+
logger = acts.logging.getLogger("GSF Example")
5460

5561
if inputParticlePath is None:
5662
addParticleGun(
@@ -67,9 +73,7 @@ def runTruthTrackingGsf(
6773
rnd=rnd,
6874
)
6975
else:
70-
acts.logging.getLogger("GSF Example").info(
71-
"Reading particles from %s", inputParticlePath.resolve()
72-
)
76+
logger.info("Reading particles from %s", inputParticlePath.resolve())
7377
assert inputParticlePath.exists()
7478
s.addReader(
7579
RootParticleReader(
@@ -78,14 +82,26 @@ def runTruthTrackingGsf(
7882
outputParticles="particles_generated",
7983
)
8084
)
85+
s.addWhiteboardAlias("particles", "particles_generated")
8186

82-
addFatras(
83-
s,
84-
trackingGeometry,
85-
field,
86-
rnd=rnd,
87-
enableInteractions=True,
88-
)
87+
if inputSimHitsPath is None:
88+
addFatras(
89+
s,
90+
trackingGeometry,
91+
field,
92+
rnd=rnd,
93+
enableInteractions=True,
94+
)
95+
else:
96+
logger.info("Reading hits from %s", inputSimHitsPath.resolve())
97+
s.addReader(
98+
RootSimHitReader(
99+
level=acts.logging.INFO,
100+
filePath=str(inputSimHitsPath.resolve()),
101+
outputSimHits="simhits",
102+
)
103+
)
104+
s.addWhiteboardAlias("particles_simulated_selected", "particles_generated")
89105

90106
addDigitization(
91107
s,

Examples/Scripts/Python/truth_tracking_gsf_refitting.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#!/usr/bin/env python3
22

33
from pathlib import Path
4+
from typing import Optional
45

56
import acts
67
import acts.examples
@@ -20,13 +21,23 @@ def runRefittingGsf(
2021
field: acts.MagneticFieldProvider,
2122
digiConfigFile: Path,
2223
outputDir: Path,
24+
inputParticlePath: Optional[Path] = None,
25+
inputSimHitsPath: Optional[Path] = None,
26+
decorators=[],
2327
s: acts.examples.Sequencer = None,
2428
):
29+
outputDir = Path(outputDir)
30+
31+
# Run Kalman tracking to produce initial tracks for refitting
2532
s = runTruthTrackingKalman(
2633
trackingGeometry,
2734
field,
2835
digiConfigFile=digiConfigFile,
2936
outputDir=outputDir,
37+
inputParticlePath=inputParticlePath,
38+
inputHitsPath=inputSimHitsPath,
39+
decorators=decorators,
40+
generatedParticleType=acts.PdgParticle.eElectron,
3041
reverseFilteringMomThreshold=0.0,
3142
reverseFilteringCovarianceScaling=1.0,
3243
s=s,
@@ -50,7 +61,7 @@ def runRefittingGsf(
5061
s.addAlgorithm(
5162
acts.examples.RefittingAlgorithm(
5263
acts.logging.INFO,
53-
inputTracks="kf_tracks",
64+
inputTracks="tracks",
5465
outputTracks="gsf_refit_tracks",
5566
initialVarInflation=6 * [100.0],
5667
fit=acts.examples.makeGsfFitterFunction(

0 commit comments

Comments
 (0)