cfb40 / scripts /test_opening_kickoff_fix.py
andytaylor-smg's picture
documenting texas
f7a96ab
#!/usr/bin/env python3
"""
Test script to verify the opening kickoff detection fix.
Tests:
1. Tennessee: Opening kickoff should be detected around 117s
2. Oregon: Opening kickoff should be detected around 332s
3. Texas: Should REJECT the fake kickoff at 20.5s and detect real game start around 444s
The fix requires:
- k=3 consecutive clock readings to confirm kickoff start
- Maximum kickoff duration of 90s (rejects if too long)
"""
import sys
import logging
from pathlib import Path
# Add src to path
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
from config import SessionConfig, load_session_config, get_video_basename, OUTPUT_DIR
from pipeline import run_extraction
# Configure logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s")
logger = logging.getLogger(__name__)
def test_video(video_name: str, video_path: str, start_time: float, end_time: float, expected_kickoff_start: float, expected_kickoff_tolerance: float = 30.0):
"""
Test opening kickoff detection on a video segment.
Args:
video_name: Name for display
video_path: Path to video file
start_time: Start time in seconds
end_time: End time in seconds
expected_kickoff_start: Expected kickoff start time (within video segment)
expected_kickoff_tolerance: Tolerance for kickoff timing match
"""
print(f"\n{'=' * 60}")
print(f"Testing: {video_name}")
print(f"Video: {video_path}")
print(f"Time range: {start_time}s - {end_time}s")
print(f"Expected kickoff around: {expected_kickoff_start}s (Β±{expected_kickoff_tolerance}s)")
print("=" * 60)
try:
# Load existing session config for this video
video_basename = get_video_basename(video_path, testing_mode=False)
config_path = OUTPUT_DIR / f"{video_basename}_config.json"
if not config_path.exists():
logger.error(f"Config not found: {config_path}")
logger.error("Run main.py with --use-saved-regions first")
return False
# Load config and update time bounds
session_config = load_session_config(str(config_path))
session_config.video_path = video_path
session_config.start_time = start_time
session_config.end_time = end_time
session_config.video_basename = video_basename
# Run extraction
results = run_extraction(session_config, OUTPUT_DIR, num_workers=1)
# Analyze results - plays are dicts, not objects
plays = results.get("plays", [])
kickoff_plays = [p for p in plays if p.get("play_type") == "kickoff"]
print(f"\nResults:")
print(f" Total plays detected: {len(plays)}")
print(f" Kickoff plays: {len(kickoff_plays)}")
success = True
if kickoff_plays:
for kp in kickoff_plays:
start = kp.get("start_time", 0)
end = kp.get("end_time", 0)
print(f"\n Kickoff found:")
print(f" Start: {start:.1f}s")
print(f" End: {end:.1f}s")
print(f" Duration: {end - start:.1f}s")
# Check if within expected range
diff = abs(start - expected_kickoff_start)
if diff <= expected_kickoff_tolerance:
print(f" βœ… PASS: Within expected range ({diff:.1f}s from expected)")
else:
print(f" ❌ FAIL: Outside expected range ({diff:.1f}s from expected)")
success = False
else:
print(f"\n ❌ No kickoff detected!")
success = False
# Show first few plays for context
print(f"\nFirst 5 plays:")
for p in plays[:5]:
pnum = p.get("play_number", "?")
pstart = p.get("start_time", 0)
pend = p.get("end_time", 0)
ptype = p.get("play_type", "?")
pmethod = p.get("start_method", "?")
print(f" Play #{pnum}: {pstart:.1f}s - {pend:.1f}s ({ptype}, {pmethod})")
return success
except Exception as e:
logger.error(f"Error testing {video_name}: {e}")
import traceback
traceback.print_exc()
return False
def main():
"""Run all tests."""
base_path = Path("/Users/andytaylor/Documents/Personal/cfb40/full_videos")
# Test configurations
tests = [
{
"video_name": "Tennessee (baseline - should pass)",
"video_path": str(base_path / "OSU vs Tenn 12.21.24.mkv"),
"start_time": 0,
"end_time": 300, # First 5 minutes
"expected_kickoff_start": 117, # ~1:57 video time
"expected_kickoff_tolerance": 30,
},
{
"video_name": "Oregon (baseline - should pass)",
"video_path": str(base_path / "OSU vs Oregon 01.01.25.mkv"),
"start_time": 200,
"end_time": 500, # Around kickoff time
"expected_kickoff_start": 332, # ~5:32 video time
"expected_kickoff_tolerance": 30,
},
{
"video_name": "Texas (fix test - should reject fake kickoff at 20s)",
"video_path": str(base_path / "OSU vs Texas 01.10.25.mkv"),
"start_time": 0,
"end_time": 600, # First 10 minutes
"expected_kickoff_start": 444, # Real game starts ~7:24
"expected_kickoff_tolerance": 30,
},
]
print("\n" + "=" * 60)
print("OPENING KICKOFF DETECTION FIX TEST")
print("=" * 60)
results = []
for test_config in tests:
success = test_video(**test_config)
results.append((test_config["video_name"], success))
# Summary
print("\n" + "=" * 60)
print("TEST SUMMARY")
print("=" * 60)
for name, success in results:
status = "βœ… PASS" if success else "❌ FAIL"
print(f" {status}: {name}")
if __name__ == "__main__":
main()