Add ProcessRouter for physics-process-based expert gating
Routes on the physics process (Compton, phot, brems, ...) that ends a step, supervised by a small classifier since process is a post-step outcome unobservable at gate time. Threads a process label end-to-end through the data pipeline (loader, build_features, dataset batches, training loss/checkpointing) alongside the existing EnergyRouter.
This commit is contained in:
@@ -235,7 +235,48 @@ def test_build_features_clamps_n_sec_label_to_k_max():
|
||||
pdg_map = {11: 0}
|
||||
mat_map = {"PbWO4": 0}
|
||||
|
||||
_, _, _, n_sec, _, _, _, _ = build_features(data, pdg_map, mat_map)
|
||||
_, _, _, n_sec, _, _, _, _, _ = build_features(data, pdg_map, mat_map)
|
||||
|
||||
assert n_sec.max() <= K_MAX
|
||||
np.testing.assert_array_equal(n_sec, [0, 5, K_MAX])
|
||||
|
||||
|
||||
def _minimal_step_data(N: int, process: np.ndarray | None = None) -> dict:
|
||||
rng = np.random.default_rng(0)
|
||||
data = {
|
||||
"pdg": np.full(N, 11, dtype=np.int32),
|
||||
"material": np.full(N, "PbWO4", dtype=object),
|
||||
"pre_pos": rng.standard_normal((N, 3)).astype(np.float32),
|
||||
"pre_E": np.full(N, 10.0, dtype=np.float32),
|
||||
"pre_dir": np.tile(np.array([0, 0, 1], dtype=np.float32), (N, 1)),
|
||||
"layer_id": np.zeros(N, dtype=np.int32),
|
||||
"n_sec": np.zeros(N, dtype=np.int32),
|
||||
"e_sec": np.full(N, 1.0, dtype=np.float32),
|
||||
"step_length": np.full(N, 1.0, dtype=np.float32),
|
||||
"post_E": np.full(N, 9.0, dtype=np.float32),
|
||||
"edep": np.full(N, 1.0, dtype=np.float32),
|
||||
"post_dir": np.tile(np.array([0, 0, 1], dtype=np.float32), (N, 1)),
|
||||
"post_pos": rng.standard_normal((N, 3)).astype(np.float32),
|
||||
}
|
||||
if process is not None:
|
||||
data["process"] = process
|
||||
return data
|
||||
|
||||
|
||||
def test_build_features_proc_idx_zero_without_proc_map():
|
||||
data = _minimal_step_data(3, process=np.array(["compt", "phot", "eIoni"], dtype=object))
|
||||
pdg_map, mat_map = {11: 0}, {"PbWO4": 0}
|
||||
|
||||
*_, proc_idx, _, _ = build_features(data, pdg_map, mat_map)
|
||||
|
||||
np.testing.assert_array_equal(proc_idx, [0, 0, 0])
|
||||
|
||||
|
||||
def test_build_features_proc_idx_looks_up_proc_map():
|
||||
data = _minimal_step_data(3, process=np.array(["compt", "phot", "eIoni"], dtype=object))
|
||||
pdg_map, mat_map = {11: 0}, {"PbWO4": 0}
|
||||
proc_map = {"compt": 0, "phot": 1, "eIoni": 2}
|
||||
|
||||
*_, proc_idx, _, _ = build_features(data, pdg_map, mat_map, proc_map=proc_map)
|
||||
|
||||
np.testing.assert_array_equal(proc_idx, [0, 1, 2])
|
||||
|
||||
Reference in New Issue
Block a user