### Purpose Perform deterministic workout analysis and generate reports/charts ### Core Requirements - **Analysis Capabilities** - FIT/TCX/GPX file parsing - Power, heart rate, and speed analysis - Training metrics calculation (TSS, IF, NP) - Zone distribution analysis - Chart generation (power curves, elevation profiles) - docs defining each analysis function - **Re-usable components** - **Parsing**: `Garmin_Analyser/parsers/file_parser.py::FileParser` - **Analysis**: `Garmin_Analyser/analyzers/workout_analyzer.py::WorkoutAnalyzer` - **Data Models**: `Garmin_Analyser/models/workout.py` and `Garmin_Analyser/models/zones.py` - **Reporting**: `Garmin_Analyser/visualizers/report_generator.py::ReportGenerator` - **Charting**: `Garmin_Analyser/visualizers/chart_generator.py::ChartGenerator` - **Power Estimation**: `Garmin_Analyser/analyzers/workout_analyzer.py::_estimate_power` - **Gear Estimation**: `Garmin_Analyser/utils/gear_estimation.py` and `Garmin_Analyser/analyzers/workout_analyzer.py::_analyze_gear` - Version 1 List of analysis functions to implement: * `FileParser.parse_file` - **Purpose**: Parses FIT, TCX, and GPX files and extracts workout data into a structured `WorkoutData` object. - **Inputs**: `file_path` (str). - **Outputs**: A `WorkoutData` object. * `WorkoutAnalyzer.analyze_workout` - **Purpose**: Orchestrates the entire analysis process for a given workout. - **Inputs**: `workout` (WorkoutData object). - **Outputs**: A dictionary containing a comprehensive analysis of the workout. * `ReportGenerator.generate_workout_report` - **Purpose**: Generates a complete workout report in various formats (HTML, PDF, Markdown). - **Inputs**: `analysis_data` (dict), `output_format` (str). - **Outputs**: A generated report file. * `ChartGenerator.generate_workout_charts` - **Purpose**: Generates a suite of charts for a workout. - **Inputs**: `analysis_data` (dict). - **Outputs**: A set of chart files (e.g., PNG). * `_calculate_summary_metrics` - **Purpose**: Calculates core summary metrics for a workout, including duration, distance, average/max speed, average/max power, average/max heart rate, elevation gain, calories, work in kJ, normalized power, intensity factor, and training stress score. - **Inputs**: `workout` (WorkoutData object), `estimated_power` (Optional[List[float]]). - **Outputs**: A dictionary containing various summary metrics. * `_analyze_power` - **Purpose**: Analyzes power data to calculate average, max, min power, standard deviation, variability, normalized power, power zones, power spikes, and power distribution. - **Inputs**: `workout` (WorkoutData object), `estimated_power` (Optional[List[float]]). - **Outputs**: A dictionary with power analysis metrics. * `_analyze_heart_rate` - **Purpose**: Analyzes heart rate data to calculate average, max, min heart rate, standard deviation, heart rate zones, heart rate recovery (currently not implemented), and heart rate distribution. - **Inputs**: `workout` (WorkoutData object). - **Outputs**: A dictionary with heart rate analysis metrics. * `_analyze_speed` - **Purpose**: Analyzes speed data to calculate average, max, min speed, standard deviation, moving time, distance, speed zones, and speed distribution. - **Inputs**: `workout` (WorkoutData object). - **Outputs**: A dictionary with speed analysis metrics. * `_analyze_elevation` - **Purpose**: Analyzes elevation data to calculate elevation gain/loss, max/min elevation, average/max/min gradient, and climbing ratio. - **Inputs**: `workout` (WorkoutData object). - **Outputs**: A dictionary with elevation analysis metrics. * `_detect_intervals` - **Purpose**: Detects high-intensity intervals in the workout based on power values. - **Inputs**: `workout` (WorkoutData object), `estimated_power` (Optional[List[float]]). - **Outputs**: A list of dictionaries, each representing an interval with start/end indices, duration, average/max power, and type. * `_calculate_zone_distribution` - **Purpose**: Calculates the time spent in different power, heart rate, and speed training zones. - **Inputs**: `workout` (WorkoutData object), `estimated_power` (Optional[List[float]]). - **Outputs**: A dictionary with zone distributions for power, heart rate, and speed. * `_calculate_efficiency_metrics` - **Purpose**: Calculates efficiency metrics such as power-to-heart rate ratio and decoupling (power vs. heart rate drift). - **Inputs**: `workout` (WorkoutData object), `estimated_power` (Optional[List[float]]). - **Outputs**: A dictionary with efficiency metrics. * `_calculate_normalized_power` - **Purpose**: Calculates normalized power (NP) using a 30-second rolling average. - **Inputs**: `power_values` (List[float]). - **Outputs**: A float representing the normalized power. * `_detect_power_spikes` - **Purpose**: Detects power spikes in the data, defined as power values more than 2 standard deviations above the mean. - **Inputs**: `power_values` (List[float]). - **Outputs**: A list of dictionaries, each representing a spike with its index, power value, and deviation. * `_calculate_power_distribution` - **Purpose**: Calculates power distribution statistics, specifically the 5th, 25th, 50th, 75th, and 95th percentiles. - **Inputs**: `power_values` (List[float]). - **Outputs**: A dictionary with power percentile values. * `_calculate_hr_distribution` - **Purpose**: Calculates heart rate distribution statistics, specifically the 5th, 25th, 50th, 75th, and 95th percentiles. - **Inputs**: `hr_values` (List[float]). - **Outputs**: A dictionary with heart rate percentile values. * `_calculate_speed_distribution` - **Purpose**: Calculates speed distribution statistics, specifically the 5th, 25th, 50th, 75th, and 95th percentiles. - **Inputs**: `speed_values` (List[float]). - **Outputs**: A dictionary with speed percentile values. * `_calculate_hr_recovery` - **Purpose**: Placeholder for calculating heart rate recovery. Currently not implemented. - **Inputs**: `workout` (WorkoutData object). - **Outputs**: `None`. * `_calculate_climbing_ratio` - **Purpose**: Calculates the climbing ratio (elevation gain per kilometer). - **Inputs**: `elevation_values` (List[float]). - **Outputs**: A float representing the climbing ratio in m/km. * `_analyze_gear` - **Purpose**: Analyzes gear data to provide statistics such as time in top gear, top gears used, unique gear count, and gear distribution. - **Inputs**: `workout` (WorkoutData object). - **Outputs**: A dictionary with gear analysis metrics. * `_analyze_cadence` - **Purpose**: Analyzes cadence data to calculate average, max, min cadence, and standard deviation. - **Inputs**: `workout` (WorkoutData object). - **Outputs**: A dictionary with cadence analysis metrics. * `_estimate_power` - **Purpose**: Estimates power using a physics-based model for both indoor and outdoor workouts. - **Inputs**: `workout` (WorkoutData object), `cog_size` (int, default 16). - **Outputs**: A list of estimated power values (floats). * `SinglespeedAnalyzer.analyze_gear_ratio` - **Purpose**: Determines the most likely singlespeed gear ratio (chainring and cog combination) from speed, cadence, and gradient data. It also calculates related gear metrics like gear inches and development in meters. - **Inputs**: - `speed_data`: List of speed values. - `cadence_data`: List of cadence values. - `gradient_data`: List of gradient values. - **Outputs**: A dictionary containing the estimated gear ratio and related metrics. * `PowerEstimator.estimate_peak_power` - **Purpose**: Calculates peak power for various durations. (Currently a placeholder, marked for Phase 3 implementation). - **Inputs**: `power_values` (List[float]), `durations` (List[int]). - **Outputs**: A dictionary where keys are durations and values are corresponding peak power. - **API Endpoints** - `POST /api/analyze/workout` - Analyze single workout - `POST /api/analyze/batch` - Analyze multiple workouts - `GET /api/analysis/{id}/charts` - Generate charts - `GET /api/analysis/{id}/summary` - LLM-ready summary - **Technical** - CPU-intensive processing isolation - Support for existing GarminAnalyser codebase - Chart generation (PNG, HTML, PDF) - Standardized output format for LLM consumption - Result caching - **Existing Code** - Use @GarminAnalyser.md to pull code from the existing implementation - use @DB_API_SPEC.json to get the API spec for the CentralDB that will store the Activity files and artifacts that we create