Add total length traveled per event to event observables

sum(step_length) per event_id, alongside the existing total deposited
energy, since path length and energy deposit aren't interchangeable once
tracks scatter. Adds plot_total_length and a matching notebook cell.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-22 16:47:51 +02:00
co-authored by Claude Sonnet 4.6
parent 6d839a983f
commit 453f9f9e20
3 changed files with 129 additions and 42 deletions
+36 -12
View File
@@ -29,6 +29,7 @@ from giant.analysis import (
plot_pairwise,
plot_shower_max_depth,
plot_total_energy,
plot_total_length,
plot_transverse_profile,
)
from giant.constants import (
@@ -454,16 +455,21 @@ def _expected_event_table(
disp = post_pos - entry_pos
depth = disp @ axis_dir
transverse = np.linalg.norm(disp - depth[:, None] * axis_dir, axis=1)
total = float(edep.sum())
centroid = float((edep * depth).sum() / total)
rms = float(np.sqrt((edep * transverse**2).sum() / total))
return total, centroid, rms
total_edep = float(edep.sum())
total_length = float(step_length.sum())
centroid = float((edep * depth).sum() / total_edep)
rms = float(np.sqrt((edep * transverse**2).sum() / total_edep))
return total_edep, total_length, centroid, rms
real_total, real_centroid, real_rms = agg(true_log_local)
gen_total, gen_centroid, gen_rms = agg(pred_log_local)
real_total_edep, real_total_length, real_centroid, real_rms = agg(
true_log_local
)
gen_total_edep, gen_total_length, gen_centroid, gen_rms = agg(pred_log_local)
expected[e] = (
real_total,
gen_total,
real_total_edep,
gen_total_edep,
real_total_length,
gen_total_length,
real_centroid,
gen_centroid,
real_rms,
@@ -485,11 +491,28 @@ def test_compute_event_observables_pl_matches_manual_reconstruction(tmp_path):
table = obs.event_table.sort("event_id")
for i, eid in enumerate(table["event_id"].to_list()):
real_total, gen_total, real_centroid, gen_centroid, real_rms, gen_rms = (
expected[eid]
(
real_total_edep,
gen_total_edep,
real_total_length,
gen_total_length,
real_centroid,
gen_centroid,
real_rms,
gen_rms,
) = expected[eid]
np.testing.assert_allclose(
table["real_total_edep"][i], real_total_edep, rtol=1e-4
)
np.testing.assert_allclose(
table["gen_total_edep"][i], gen_total_edep, rtol=1e-4
)
np.testing.assert_allclose(
table["real_total_length"][i], real_total_length, rtol=1e-4
)
np.testing.assert_allclose(
table["gen_total_length"][i], gen_total_length, rtol=1e-4
)
np.testing.assert_allclose(table["real_total_edep"][i], real_total, rtol=1e-4)
np.testing.assert_allclose(table["gen_total_edep"][i], gen_total, rtol=1e-4)
np.testing.assert_allclose(
table["real_centroid_depth"][i], real_centroid, rtol=1e-3, atol=1e-4
)
@@ -539,6 +562,7 @@ def test_event_level_plots_run_without_error(tmp_path):
obs = compute_event_observables_pl(path, depth_bins=5, transverse_bins=5)
assert plot_total_energy(obs) is not None
assert plot_total_length(obs) is not None
assert plot_longitudinal_profile(obs) is not None
assert plot_transverse_profile(obs) is not None
assert plot_shower_max_depth(obs) is not None