This commit is contained in:
bolade
2025-11-21 14:20:15 +01:00
parent dbee12341a
commit 974699dd81
3 changed files with 23 additions and 11 deletions
+23 -11
View File
@@ -235,19 +235,27 @@ class ContextGenerator:
return metrics
def _detect_thresholds(self) -> Tuple[Optional[Dict], Optional[Dict]]:
"""Detect VT1 and VT2 thresholds"""
"""Detect VT1 and VT2 thresholds (matching notebook logic)"""
# VT1: First index where carb burn > fat burn AND remains higher
condition = self.pnoe_df["CHO_smoothed"] > self.pnoe_df["FAT_smoothed"]
crossover_indices = condition[condition].index
vt1 = None
if len(crossover_indices) > 0:
vt1_idx = crossover_indices[0]
vt1_row = self.pnoe_df.loc[vt1_idx]
vt1 = {
"HeartRate": vt1_row["HR(bpm)_smoothed"],
"Speed": vt1_row["Speed"],
"Time": vt1_row["T(sec)"],
}
# Find first crossover where carbs remain higher for the rest
for idx in crossover_indices:
if all(
self.pnoe_df.loc[idx:]["CHO_smoothed"]
> self.pnoe_df.loc[idx:]["FAT_smoothed"]
):
vt1_idx = idx
vt1_row = self.pnoe_df.loc[vt1_idx]
vt1 = {
"HeartRate": vt1_row["HR(bpm)_smoothed"],
"Speed": vt1_row["Speed"],
"Time": vt1_row["T(sec)"],
}
break
ve_slope = self.pnoe_df["VE(l/min)_smoothed"].diff()
second_derivative = ve_slope.diff()
@@ -745,9 +753,13 @@ class ContextGenerator:
"""Calculate detailed metrics for each heart rate zone based on actual data"""
import math
# Get zone boundaries
fat_max_idx = self.pnoe_df["FAT_smoothed"].idxmax()
optimal_row = self.pnoe_df.loc[fat_max_idx]
# Get zone boundaries - use optimal fat burning zone (highest fat:carb ratio)
# matching notebook logic
self.pnoe_df["fat_carb_ratio"] = self.pnoe_df["FAT_smoothed"] / (
self.pnoe_df["CHO_smoothed"] + 0.00000001
)
optimal_fat_idx = self.pnoe_df["fat_carb_ratio"].idxmax()
optimal_row = self.pnoe_df.loc[optimal_fat_idx]
# Detect VT1 and VT2
vt1 = pnoe_metrics.get("vt1")