"""Explicit units for recording, performance and daily recovery observations.""" METRICS = {} UNITS = {} def metric(key, label, unit, definition, conversions=None): METRICS[key] = (label, unit, definition) UNITS[key] = conversions or {unit: 1} for key, label in (("elapsed", "Elapsed recording offset"), ("moving_offset", "Moving-time offset"), ("matched_minutes", "Matched moving minutes")): metric(key, label, "min", "Minutes since recording start, or usable matched moving time.", {"min": 1, "s": 1 / 60, "h": 60}) for key, label in (("grade", "Smoothed grade"), ("grade_variability", "Grade variation"), ("terrain_coverage", "Terrain coverage"), ("joint_coverage", "Joint HR and terrain coverage"), ("hr_artifact_percent", "Suspect HR time"), ("long_run_share", "Largest run share of 7-day volume")): metric(key, label, "%", "Recording-derived percentage; missing observations stay missing.") metric("matched_windows", "Matched windows", "windows", "Usable continuous recording windows.") metric("sessions", "Sessions", "runs", "Number of recorded running sessions on this local day.") metric("effort_time", "Best effort time", "time", "Elapsed recorded best-effort window, in seconds.", {"s": 1, "min": 60}) for key, label, unit in (("resting_hr", "Resting HR", "bpm"), ("hrv", "Overnight HRV", "ms"), ("sleep_hours", "Sleep", "h"), ("stress", "Daily stress", "score"), ("perceived_effort", "Perceived effort", "score"), ("fatigue", "Reported fatigue", "score")): metric(key, label, unit, "Private recorded daily observation or owner-entered session context; no diagnosis.") for sensor, unit in (("cadence", "spm"), ("power", "W"), ("ground_contact", "ms"), ("stride_length", "m"), ("vertical_oscillation", "cm")): metric(sensor + "_coverage", sensor.replace("_", " ").title() + " coverage", "%", "Percent of this continuous moving window with a usable positive sensor measurement.") for band in ("lower", "middle", "upper"): metric(band + "_hr_minutes", band.title() + " HR minutes", "min", "Time in individually configured HR bands; unavailable until thresholds are set.")