Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ Collect data simultaneously:
(ssoss_virtual_env) ssoss --video_file 09-15-2023--14-12-24.123-UTC.mov \
--autosync
```
The timezone portion of the filename is preserved as an offset; the
timestamp itself is not shifted.

#### Sync GPX & Video Process
Synchronizing the GPX file and the video could be one of the largest sources of error. The ProcessVideo Class has
Expand Down
90 changes: 20 additions & 70 deletions src/ssoss/ssoss_cli.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import argparse
import re

from datetime import datetime
from pathlib import Path
from zoneinfo import ZoneInfo
Expand All @@ -15,12 +16,16 @@
from . import process_video




def _timestamp_from_filename(path: str) -> str:
"""Extract ISO 8601 timestamp from ``path``.

The filename should contain a timestamp formatted as
``MM-DD-YYYY--HH-MM-SS.sss-ZZZ`` where ``ZZZ`` is a timezone
abbreviation such as ``UTC`` or ``PDT``.
abbreviation such as ``UTC`` or ``PDT``. The time itself is not shifted
based on the timezone; the offset is simply attached to the parsed
timestamp.
"""

base = Path(path).stem
Expand All @@ -35,79 +40,24 @@ def _timestamp_from_filename(path: str) -> str:
zone = m.group("zone")

dt = datetime.strptime(ts_str, "%m-%d-%Y--%H-%M-%S.%f")
zone_map = {
"UTC": "UTC",
"PST": "America/Los_Angeles",
"PDT": "America/Los_Angeles",
"MST": "America/Denver",
"MDT": "America/Denver",
"CST": "America/Chicago",
"CDT": "America/Chicago",
"EST": "America/New_York",
"EDT": "America/New_York",
zone = zone.upper()
offset_map = {
"UTC": 0,
"PST": -8,
"PDT": -7,
"MST": -7,
"MDT": -6,
"CST": -6,
"CDT": -5,
"EST": -5,
"EDT": -4,
}
tz_name = zone_map.get(zone.upper(), "UTC")
dt = dt.replace(tzinfo=ZoneInfo(tz_name))
hours = offset_map.get(zone, 0)
tz = timezone(timedelta(hours=hours))
dt = dt.replace(tzinfo=tz)
return dt.isoformat()


def cli_summary(descriptions, project, video):
"""Print a summary of extracted images and processing stats."""

width = 70

title = "SSOSS Summary Information"

symbol = "="

num_images = len(descriptions)
gpx_dur = project.get_end_timestamp() - project.get_start_timestamp()
vid_dur = video.get_duration()

avg_gpx = gpx_dur / num_images if num_images else 0
avg_vid = vid_dur / num_images if num_images else 0

intersections = {}
for desc in descriptions:
prefix = desc.split("-", 1)[0]
parts = prefix.split(".")
if len(parts) >= 2:
int_id = int(parts[0])
bearing = int(parts[1])
intersections.setdefault(int_id, set()).add(bearing)


num_inters_found = len(intersections)
total_input_inters = (
len(project.intersection_listDF.index)
if getattr(project, "intersection_listDF", None) is not None
else 0
)
inters_pct = (
num_inters_found / total_input_inters * 100
if total_input_inters
else 0
)


multiplier = (18 * 60 / avg_vid) if avg_vid else 0

summary = f"""
{symbol * width}
{" " * (int(width/2)-int(len(title)/2))}{title}
{symbol * width}
# Number of Images: {num_images}

# Number of Intersections: {num_inters_found} ({inters_pct:.1f}%)

# Avg Time per Image (GPX): {project.hr_min_sec(avg_gpx)}
# Avg Time per Image (Video): {project.hr_min_sec(avg_vid)}
# SSOSS Multiplier: {multiplier:.1f}X compared to field check
{symbol * width}
"""
print(summary)


def args_static_obj_gpx_video(
generic_so_file="",
gpx_file="",
Expand Down
11 changes: 11 additions & 0 deletions tests/test_ssoss_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,14 @@ def test_autosync_uses_filename(run_cli, tmp_path):
assert result["vid_sync"][0] == 1
assert result["vid_sync"][1].startswith("2023-09-15T14:12:24.123000")



def test_autosync_preserves_timezone_offset(run_cli, tmp_path):
vid = tmp_path / "09-15-2023--14-12-24.123-PST.mov"
vid.write_text("data")

result = run_cli(["--video_file", str(vid), "--autosync"])

assert result["vid_sync"][1].endswith("-08:00")


Loading