Module: Vo2maxEstimator

Included in:
Calcpace
Defined in:
lib/calcpace/vo2max_estimator.rb

Overview

Module for estimating VO2max from a race performance

Uses the Daniels & Gilbert formula (1979), which relates running velocity and exercise duration to oxygen consumption as a percentage of VO2max.

Formula:

velocity (m/min)  = distance_m / time_min
VO2               = -4.60 + 0.182258 * v + 0.000104 * v²
%VO2max           = 0.8 + 0.1894393·e^(-0.012778·t) + 0.2989558·e^(-0.1932605·t)
VO2max            = VO2 / %VO2max

Accuracy: ±3–5 ml/kg/min vs laboratory testing. Best results with efforts between 5 and 60 minutes at race pace (i.e. near-maximal effort).

Defined Under Namespace

Classes: Vo2maxResult

Constant Summary collapse

VO2MAX_LABELS =

Classification thresholds based on: Daniels, J. (2014). Daniels’ Running Formula (3rd ed.). Human Kinetics. General ranges are consistent with ACSM guidelines and widely cited in exercise physiology literature (McArdle, Katch & Katch, 2015).

[
  { min: 70, label: 'Elite' },
  { min: 60, label: 'Excellent' },
  { min: 50, label: 'Very Good' },
  { min: 40, label: 'Good' },
  { min: 30, label: 'Fair' },
  { min: 0,  label: 'Beginner' }
].freeze

Instance Method Summary collapse

Instance Method Details

#estimate_detailed_vo2max(distance_km, time, elevation_gain_m: 0, hr_avg: nil, hr_max: nil) ⇒ Vo2maxResult

Estimates a detailed and contextualized VO2max

Parameters:

  • distance_km (Numeric)

    race distance in kilometres

  • time (String, Integer)

    finish time

  • elevation_gain_m (Numeric) (defaults to: 0)

    total elevation gain in metres

  • hr_avg (Numeric) (defaults to: nil)

    average heart rate during the effort

  • hr_max (Numeric) (defaults to: nil)

    athlete’s maximum heart rate

Returns:

  • (Vo2maxResult)

    structured result with value and metadata



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/calcpace/vo2max_estimator.rb', line 66

def estimate_detailed_vo2max(distance_km, time, elevation_gain_m: 0, hr_avg: nil, hr_max: nil)
  adj_dist_km = adjusted_distance_for_vo2(distance_km, elevation_gain_m)
  vo2max_val  = estimate_vo2max(adj_dist_km, time)
  confidence  = calculate_time_confidence(parse_time_minutes(time))

  hr_data = validate_and_analyze_hr(hr_avg, hr_max)
  confidence = :low if hr_data[:sub_maximal]

  Vo2maxResult.new(
    value: vo2max_val,
    confidence: confidence,
    sub_maximal: hr_data[:sub_maximal],
    adjusted_distance_km: adj_dist_km.round(2)
  )
end

#estimate_vo2max(distance_km, time) ⇒ Float

Estimates VO2max from a race performance using Daniels & Gilbert formula

Examples:

10 km in 40:00 → ~51.9 ml/kg/min

calc = Calcpace.new
calc.estimate_vo2max(10.0, '00:40:00') #=> 51.9

Parameters:

  • distance_km (Numeric)

    race distance in kilometres (must be > 0)

  • time (String, Integer)

    finish time as “HH:MM:SS” / “MM:SS”, or total seconds (must be > 0)

Returns:

  • (Float)

    estimated VO2max in ml/kg/min, rounded to one decimal place

Raises:



44
45
46
47
48
49
50
51
52
53
54
55
56
# File 'lib/calcpace/vo2max_estimator.rb', line 44

def estimate_vo2max(distance_km, time)
  distance_m = distance_km.to_f * 1000
  time_min   = parse_time_minutes(time)

  check_positive(distance_m, 'Distance')
  check_positive(time_min,   'Time')

  velocity    = distance_m / time_min
  vo2         = vo2_at_velocity(velocity)
  pct_vo2max  = percent_vo2max(time_min)

  (vo2 / pct_vo2max).round(1)
end

#vo2max_label(value) ⇒ String

Returns a descriptive label for a given VO2max value

Examples:

calc.vo2max_label(51.9) #=> "Very Good"

Parameters:

  • value (Numeric)

    VO2max in ml/kg/min

Returns:

  • (String)

    label: “Beginner”, “Fair”, “Good”, “Very Good”, “Excellent”, or “Elite”

Raises:

  • (ArgumentError)

    if value is not positive



90
91
92
93
94
# File 'lib/calcpace/vo2max_estimator.rb', line 90

def vo2max_label(value)
  check_positive(value.to_f, 'VO2max value')

  VO2MAX_LABELS.find { |entry| value.to_f >= entry[:min] }[:label]
end