Add floor-event timing objective and addressee diagnostics

This commit is contained in:
Xin Wang
2026-09-11 00:15:34 +08:00
parent 5937971222
commit a57e827606
14 changed files with 2144 additions and 234 deletions
+80
View File
@@ -14,6 +14,7 @@ import numpy as np
from evaluate_floor_state_changes import (
NUM_CLASSES,
NUM_HORIZONS,
collect_floor_event_candidates,
evaluate_event_horizon,
evaluate_horizon,
load_arrays,
@@ -29,6 +30,85 @@ def activity(wearer: int, others: int) -> list[int]:
class FloorStateMetricTests(unittest.TestCase):
def test_post_boundary_candidate_uses_first_post_transition_row(self) -> None:
target = np.asarray(
[
activity(0, 1),
activity(0, 0), # observed other offset
activity(1, 0), # wearer response
activity(1, 0),
],
dtype=np.float32,
)
session_ids = np.zeros(len(target), dtype=np.int32)
pre, _ = collect_floor_event_candidates(
target,
session_ids,
1,
event_type="response",
decision_timing="pre-boundary",
)
post, diagnostics = collect_floor_event_candidates(
target,
session_ids,
1,
event_type="response",
decision_timing="post-boundary",
)
self.assertEqual([(item.source_row, item.label) for item in pre], [(0, True)])
self.assertEqual([(item.source_row, item.label) for item in post], [(1, True)])
self.assertEqual(diagnostics["num_simultaneous_boundary_outcomes_excluded"], 0)
def test_post_boundary_excludes_outcome_that_already_happened_at_anchor(self) -> None:
target = np.asarray(
[
activity(0, 1),
activity(1, 0), # simultaneous other offset and wearer onset
activity(1, 0),
],
dtype=np.float32,
)
session_ids = np.zeros(len(target), dtype=np.int32)
pre, _ = collect_floor_event_candidates(
target,
session_ids,
0,
event_type="response",
decision_timing="pre-boundary",
)
post, diagnostics = collect_floor_event_candidates(
target,
session_ids,
0,
event_type="response",
decision_timing="post-boundary",
)
self.assertEqual(len(pre), 1)
self.assertTrue(pre[0].label)
self.assertEqual(post, [])
self.assertEqual(diagnostics["num_source_boundaries"], 1)
self.assertEqual(diagnostics["num_simultaneous_boundary_outcomes_excluded"], 1)
def test_post_boundary_reports_competitor_with_no_observable_bin(self) -> None:
target = np.asarray(
[
activity(0, 1),
activity(0, 0),
activity(0, 1), # immediate restart after reactive source
activity(0, 1),
],
dtype=np.float32,
)
candidates, diagnostics = collect_floor_event_candidates(
target,
np.zeros(len(target), dtype=np.int32),
1,
event_type="response",
decision_timing="post-boundary",
)
self.assertEqual(candidates, [])
self.assertEqual(diagnostics["num_zero_window_competing_risk"], 1)
def test_response_window_stops_before_next_other_onset(self) -> None:
target = np.asarray(
[