116 lines
4.6 KiB
Python
116 lines
4.6 KiB
Python
"""Tests for manuscript-aligned EasyCom EOT/INT review regions."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import unittest
|
|
|
|
from derive_easycom_interaction_events import Clip, Utterance
|
|
from prepare_easycom_eot_int_review import derive_protocol_candidates
|
|
|
|
|
|
def utterance(uid: str, participant: int, start: float, end: float, text: str) -> Utterance:
|
|
return Utterance(
|
|
uid=uid,
|
|
session="Session_4",
|
|
clip_stem="00-00-000",
|
|
clip_index=0,
|
|
segment_id=0,
|
|
participant_id=participant,
|
|
target_of_speech=("Group",),
|
|
transcription=text,
|
|
source_start_frame=round(start * 20) + 1,
|
|
source_end_frame=round(end * 20),
|
|
dense_start_frame=round(start * 20),
|
|
dense_end_frame_exclusive=round(end * 20),
|
|
dense_start_seconds=start,
|
|
dense_end_seconds=end,
|
|
duration_seconds=end - start,
|
|
starts_at_clip_boundary=start == 0,
|
|
ends_at_clip_boundary=False,
|
|
annotation_end_frame_clamped_by=0,
|
|
is_cross_clip_continuation=False,
|
|
)
|
|
|
|
|
|
def clip(seconds: float = 5.0) -> Clip:
|
|
return Clip(
|
|
path="/dataset/Main/Video_Compressed/Session_4/00-00-000.mp4",
|
|
transcript_path="/dataset/Main/Speech_Transcriptions/Session_4/00-00-000.json",
|
|
stem="00-00-000",
|
|
source_start_seconds=0.0,
|
|
source_end_seconds=seconds,
|
|
dense_start_frame=0,
|
|
num_frames=round(seconds * 20),
|
|
segment_id=0,
|
|
discontinuity_before_seconds=None,
|
|
)
|
|
|
|
|
|
class EOTINTReviewCandidateTests(unittest.TestCase):
|
|
def derive(self, rows: list[Utterance]):
|
|
return derive_protocol_candidates(rows, [clip()], session="Session_4")
|
|
|
|
def test_eot_response_is_anchored_by_wearer_onset(self) -> None:
|
|
rows = [
|
|
utterance("other", 4, 0.0, 1.0, "Your turn."),
|
|
utterance("wearer", 2, 1.2, 2.0, "My response."),
|
|
]
|
|
event = next(row for row in self.derive(rows) if row.task == "eot_response")
|
|
self.assertEqual(event.automatic_protocol_label, "positive")
|
|
self.assertEqual(event.anchor_type, "other_offset")
|
|
self.assertEqual(event.behavior_anchor_type, "wearer_onset")
|
|
self.assertAlmostEqual(event.anchor_dense_seconds, 1.0)
|
|
self.assertAlmostEqual(event.behavior_seconds or -1, 1.2)
|
|
|
|
def test_same_other_resume_is_eot_midturn_hard_negative(self) -> None:
|
|
rows = [
|
|
utterance("first", 4, 0.0, 1.0, "First clause."),
|
|
utterance("resume", 4, 1.3, 2.5, "Same turn continues."),
|
|
]
|
|
event = next(
|
|
row
|
|
for row in self.derive(rows)
|
|
if row.task == "eot_response" and row.anchor_dense_seconds == 1.0
|
|
)
|
|
self.assertEqual(event.automatic_protocol_label, "hard_negative")
|
|
self.assertEqual(event.automatic_hard_negative_type, "eot_midturn_pause")
|
|
self.assertEqual(event.region_end_reason, "competing_other_onset")
|
|
|
|
def test_other_to_other_transfer_is_eot_hard_negative(self) -> None:
|
|
rows = [
|
|
utterance("first", 4, 0.0, 1.0, "First speaker."),
|
|
utterance("next", 3, 1.2, 2.5, "Second speaker."),
|
|
]
|
|
event = next(
|
|
row
|
|
for row in self.derive(rows)
|
|
if row.task == "eot_response" and row.anchor_dense_seconds == 1.0
|
|
)
|
|
self.assertEqual(event.automatic_protocol_label, "hard_negative")
|
|
self.assertEqual(event.automatic_hard_negative_type, "eot_other_to_other")
|
|
|
|
def test_int_yield_is_anchored_by_wearer_offset(self) -> None:
|
|
rows = [
|
|
utterance("wearer", 2, 0.0, 2.0, "Wearer is speaking."),
|
|
utterance("other", 4, 1.0, 3.0, "I will take over now."),
|
|
]
|
|
event = next(row for row in self.derive(rows) if row.task == "int_yield")
|
|
self.assertEqual(event.automatic_protocol_label, "positive")
|
|
self.assertEqual(event.anchor_type, "other_onset")
|
|
self.assertEqual(event.behavior_anchor_type, "wearer_offset")
|
|
self.assertAlmostEqual(event.behavior_seconds or -1, 2.0)
|
|
|
|
def test_brief_feedback_is_int_backchannel_hard_negative(self) -> None:
|
|
rows = [
|
|
utterance("wearer", 2, 0.0, 3.0, "Wearer keeps the floor."),
|
|
utterance("other", 4, 1.0, 1.4, "Yeah."),
|
|
]
|
|
event = next(row for row in self.derive(rows) if row.task == "int_yield")
|
|
self.assertEqual(event.automatic_protocol_label, "hard_negative")
|
|
self.assertEqual(event.automatic_hard_negative_type, "int_backchannel")
|
|
self.assertEqual(event.region_end_reason, "competing_other_offset")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|