Fix opportunity competing-risk evaluation
This commit is contained in:
@@ -30,7 +30,10 @@ def reviewed_row(
|
||||
region_start: float,
|
||||
region_end: float,
|
||||
selected_release: float | None = None,
|
||||
selected_release_uid: str | None = None,
|
||||
nearby: list[dict[str, object]] | None = None,
|
||||
opportunity_options: list[dict[str, object]] | None = None,
|
||||
gap_other_intervals: list[dict[str, object]] | None = None,
|
||||
candidate_source: str | None = None,
|
||||
) -> dict[str, object]:
|
||||
event_type = None
|
||||
@@ -45,6 +48,7 @@ def reviewed_row(
|
||||
"human_verdict": verdict,
|
||||
"human_event_type": event_type,
|
||||
"human_subtype": subtype,
|
||||
"selected_opportunity_uid": selected_release_uid,
|
||||
"selected_opportunity_seconds": selected_release,
|
||||
"boundary_correction_seconds": 0,
|
||||
},
|
||||
@@ -59,6 +63,8 @@ def reviewed_row(
|
||||
"behavior_anchor_seconds": anchor,
|
||||
"wearer_offset_seconds": anchor,
|
||||
"nearby_other_intervals": nearby or [],
|
||||
"opportunity_options": opportunity_options or [],
|
||||
"gap_other_intervals": gap_other_intervals or [],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -119,7 +125,7 @@ class OpportunityEventTests(unittest.TestCase):
|
||||
diagnostics["skipped"]["entry_backchannel_separate_diagnostic"], 1
|
||||
)
|
||||
|
||||
def test_loader_selects_latest_crossing_other_for_int(self) -> None:
|
||||
def test_loader_excludes_ambiguous_crossing_others_for_int(self) -> None:
|
||||
nearby = [
|
||||
{
|
||||
"onset_seconds": 1.0,
|
||||
@@ -145,11 +151,91 @@ class OpportunityEventTests(unittest.TestCase):
|
||||
)
|
||||
])
|
||||
self.addCleanup(temporary.cleanup)
|
||||
events, _ = load_opportunity_events([path], ["Session_4"])
|
||||
self.assertEqual(len(events), 1)
|
||||
self.assertEqual(events[0].opportunity_anchor_seconds, 2.0)
|
||||
self.assertEqual(events[0].censor_seconds, 3.8)
|
||||
self.assertEqual(events[0].competing_intervals, 2)
|
||||
events, diagnostics = load_opportunity_events([path], ["Session_4"])
|
||||
self.assertEqual(events, [])
|
||||
self.assertEqual(
|
||||
diagnostics["skipped"]["int_positive_ambiguous_competing_others"],
|
||||
1,
|
||||
)
|
||||
|
||||
def test_loader_excludes_entry_positive_at_competing_other_onset(self) -> None:
|
||||
rows = [
|
||||
reviewed_row(
|
||||
"entry-competed",
|
||||
family="entry",
|
||||
verdict="POSITIVE",
|
||||
subtype=None,
|
||||
anchor=1.6,
|
||||
region_start=0.0,
|
||||
region_end=3.0,
|
||||
selected_release=1.0,
|
||||
selected_release_uid="release",
|
||||
opportunity_options=[
|
||||
{
|
||||
"uid": "release",
|
||||
"anchor_seconds": 1.0,
|
||||
"wearer_active_between_release_and_onset": False,
|
||||
"other_onset_between_release_and_onset": True,
|
||||
}
|
||||
],
|
||||
gap_other_intervals=[
|
||||
{"uid": "competitor", "onset_seconds": 1.4}
|
||||
],
|
||||
),
|
||||
reviewed_row(
|
||||
"entry-simultaneous",
|
||||
family="entry",
|
||||
verdict="POSITIVE",
|
||||
subtype=None,
|
||||
anchor=4.0,
|
||||
region_start=3.0,
|
||||
region_end=5.0,
|
||||
selected_release=3.2,
|
||||
gap_other_intervals=[
|
||||
{"uid": "competitor", "onset_seconds": 4.0}
|
||||
],
|
||||
),
|
||||
]
|
||||
temporary, path = self.write_reviews(rows)
|
||||
self.addCleanup(temporary.cleanup)
|
||||
events, diagnostics = load_opportunity_events([path], ["Session_4"])
|
||||
self.assertEqual(events, [])
|
||||
self.assertEqual(
|
||||
diagnostics["skipped"]["entry_positive_competed_before_behavior"],
|
||||
2,
|
||||
)
|
||||
|
||||
def test_loader_excludes_entry_positive_after_prior_wearer_activity(self) -> None:
|
||||
temporary, path = self.write_reviews([
|
||||
reviewed_row(
|
||||
"entry-post-outcome",
|
||||
family="entry",
|
||||
verdict="POSITIVE",
|
||||
subtype=None,
|
||||
anchor=2.0,
|
||||
region_start=0.0,
|
||||
region_end=3.0,
|
||||
selected_release=1.0,
|
||||
selected_release_uid="release",
|
||||
opportunity_options=[
|
||||
{
|
||||
"uid": "release",
|
||||
"anchor_seconds": 1.0,
|
||||
"wearer_active_between_release_and_onset": True,
|
||||
"other_onset_between_release_and_onset": False,
|
||||
}
|
||||
],
|
||||
)
|
||||
])
|
||||
self.addCleanup(temporary.cleanup)
|
||||
events, diagnostics = load_opportunity_events([path], ["Session_4"])
|
||||
self.assertEqual(events, [])
|
||||
self.assertEqual(
|
||||
diagnostics["skipped"][
|
||||
"entry_positive_post_outcome_wearer_activity"
|
||||
],
|
||||
1,
|
||||
)
|
||||
|
||||
def test_entry_hn_requires_matching_independently_mined_source(self) -> None:
|
||||
rows = [
|
||||
@@ -385,7 +471,7 @@ class OpportunityEventTests(unittest.TestCase):
|
||||
payload = json.loads(output.read_text(encoding="utf-8"))
|
||||
self.assertEqual(
|
||||
payload["protocol"],
|
||||
"egospeak-opportunity-conditioned-floor-actions-v1",
|
||||
"egospeak-opportunity-conditioned-floor-actions-v2",
|
||||
)
|
||||
self.assertTrue((root / "summary_metrics.csv").is_file())
|
||||
self.assertTrue((root / "summary_events.csv").is_file())
|
||||
|
||||
Reference in New Issue
Block a user