Skip to main content

NRCD performance standardization formulas (cross country, track, road)

Project description

nrcd

Python library for National Running Club Database (NRCD) performance standardization (cross country, track, road). Implements the formulas documented in the NRCD resource paper.

GitHub Python 3.10+ PyPI License: MIT CI

Use this to standardize your own race results — no NRCD dataset download required.

Quick start

Times can be seconds or clock strings ("22:15", "4:12.00", "10.52"). XC distances accept m/km/mi or labels like "5k". Invalid time, distance, or unit strings raise ValueError with a short hint (they do not return NaN silently).

Cross country — 5K in 22:15

from nrcd import standardize_xc  # or: from nrcd.standardize import standardize_xc

std = standardize_xc("22:15", gender="M", reported_distance="5k")

Cross country — 8 km with weather, grade, altitude

std = standardize_xc(
    "27:30",
    gender="M",
    reported_distance=8,
    distance_unit="km",
    actual_distance=8.01,
    temperature=72,          # °F (default)
    dew_point=65,
    elevation_gain=2.5,      # % grade (default)
    elevation_loss=2.5,
    meet_elevation=5200,     # feet (default)
)

Outdoor track — 100m with wind

from nrcd import standardize_outdoor_track

std = standardize_outdoor_track(
    "13.52",
    gender="F",
    event_name="100m",
    wind_mps=2.0,
)

Indoor track — 200m on a banked 200m oval

from nrcd import standardize_indoor_track

std = standardize_indoor_track(
    "21.80",
    gender="M",
    event_name="200m",
    lap_length_m=200,
    banked=True,
)

Road — half marathon with weather and grade

from nrcd import standardize_road

std = standardize_road(
    "1:25:30",
    gender="F",
    event_name="Half Marathon",
    temperature=55,
    dew_point=48,
    elevation_gain=1.2,
    elevation_loss=1.2,
)

Pipelines

Sport Function What differs
Cross country standardize_xc Weather, grade, altitude, then Riegel to NIRCA 8k/6k
Road standardize_road Same weather / grade / altitude as XC; distance from event_name; no Riegel target
Outdoor track standardize_outdoor_track Sprint wind, weather, grade, altitude
Indoor track standardize_indoor_track Lap/bank venue factors; no wind

standardize_result remains available when you need a custom sport_name string.

Unit switches (optional kwargs on all pipelines):

Field Default Alternative
temperature, dew_point °F temp_unit="C"
meet_elevation feet venue_elevation_unit="m"
elevation_gain, elevation_loss % grade grade_input="feet" or "m"

More examples

Runnable scripts in examples/:

Script
XC xc_examples.py, compare_improvement.py, standardize_one_result.py
Track track_outdoor_examples.py, track_indoor_examples.py, track_compare_meets.py
Both race_context_example.py, load_dataset_example.py

load_dataset_example.py exits with code 1 if Zenodo CSVs are not in data/ — that is expected without the optional dataset.

pip install nrcd
python examples/xc_examples.py
python examples/track_outdoor_examples.py

Install

Requires Python 3.10+.

pip install nrcd              # after first PyPI release
pip install "nrcd[apis]"      # optional: weather / elevation APIs
pip install "nrcd[data]"      # optional: Zenodo CSV helpers (pandas)

Until the package is on PyPI, install from source:

git clone https://github.com/National-Running-Club-Database/nrcd
cd nrcd
pip install -e .

From source (development):

git clone https://github.com/National-Running-Club-Database/nrcd
cd nrcd
pip install -e ".[dev]"
pip install -e ".[dev,apis]"

API keys (optional — nrcd.enrich only)

Standardization does not need API keys. Use enrichment only when backfilling weather or meet altitude from city/state.

  1. pip install "nrcd[apis]"
  2. OpenWeatherAPI keys → set NRCD_OPENWEATHER_API_KEY
  3. For weather at a race date/time, also TimeZoneDBNRCD_TIMEZONE_API_KEY
  4. Meet altitude uses free USGS EPQS (no key) after OpenWeather geocodes the city
export NRCD_OPENWEATHER_API_KEY="your_key"
export NRCD_TIMEZONE_API_KEY="your_key"   # weather only

Live tests (optional): copy local_api_keys.env.examplelocal_api_keys.env (gitignored), add your OpenWeather key, then pytest -m live_api -v. AQI history starts 2020-11-27; default test date is 2024-10-12.

Full walkthrough: API keys guide. In Python: from nrcd.enrich import API_GUIDE; print(API_GUIDE).

Historical OpenWeather timemachine weather may require a paid OpenWeather plan; geocoding + USGS altitude often work on the free tier.

Do you need the NRCD dataset?

Use case Zenodo CSVs needed?
Standardize your own results No
examples/ scripts No
nrcd.enrich API backfill No
examples/load_dataset_example.py only Yes (optional)

Optional public export: Zenodo dataset (see data/README.md).

API

Full parameter tables: from nrcd import PARAMETERS_DOC or help(nrcd.standardize).

Entry points

Function Use for
standardize_xc Cross country — distance in m/km/mi; Riegel to NIRCA targets
standardize_road Road / marathon — event_name; weather, grade, altitude
standardize_outdoor_track Outdoor track — event_name; wind on sprints
standardize_indoor_track Indoor track — event_name; lap length / banking
standardize_result Low-level — any sport_name (advanced)
standardize_seconds Dispatch from a RaceContext / XCRaceContext row
enrich_race_context Fill missing weather/altitude on a context (pip install "nrcd[apis]")

nrcd.standardize — pipelines & context

Name Description
RaceContext Dataclass for one result (XC or track); time_str or time_sec
XCRaceContext XC-focused RaceContext subclass
StandardizeConfig Paper coefficients (Riegel exponents, heat k, grade bases, …)
PARAMETERS_DOC Full required/optional parameter reference (text)
PARAMETER_SPECS Same metadata as structured ParameterSpec tuples
parameter_specs() Return PARAMETER_SPECS
`required_for("xc" "road"

nrcd.standardize — time, distance, units

Name Description
parse_time "22:15", "1:10:13", or seconds → float seconds
format_time Seconds → clock string
parse_distance "5k", 8, "8000m" + unit → meters
distance_to_meters Numeric distance with distance_unit (m / km / mi)
c_to_f, f_to_c Temperature conversion
feet_to_meters, meters_to_feet Length conversion
temperature_to_fahrenheit Value + temp_unit (F / C) → °F
venue_elevation_to_feet Meet altitude + venue_elevation_unit (ft / m) → ft
grade_percent_from_feet Vertical ft over course → % grade
grade_percent_from_meters Vertical m over course → % grade
resolve_grade_percent Normalize gain/loss with grade_input (percent / feet / m)

nrcd.standardize — factors & sport helpers

Name Description
weather_factor Heat slowdown multiplier from temp + dew point (°F)
heat_index, heat_slowdown_percent Hadley-style heat index components
elevation_factor Maurer grade multiplier from % gain/loss
apply_course_grade_factor Grade step on a race time
warn_one_sided_course_grade Warn when only gain or only loss is set
apply_meet_altitude Peronnet meet-altitude correction
peronnet_f_alt, sea_level_time_seconds Altitude factor and sea-level equivalent
resolve_meet_altitude_inputs Parse elevation + barometric pressure from a record
barometric_pressure_hpa_from_record hPa from row fields
barometric_pressure_torr_from_hpa, parse_barometric_pressure_hpa Pressure unit helpers
riegel_convert, riegel_exponent Distance conversion
xc_target_distance_m NIRCA reference XC distance (8000 M / 6000 F)
apply_factors Multiply time by weather/grade/altitude/track/wind factors
is_cross_country, is_track, is_outdoor_track, is_indoor_track Sport name checks
normalize_sport_name, pipeline_kind Sport string normalization / xc vs track

nrcd.data — Zenodo CSV helpers

Name Description
meet_altitude_column Altitude column name in a meet DataFrame
meet_altitude_ft_from_record Meet altitude (ft) from a merged row + course details
derive_course_details_fields Derived weather/grade fields from course details

nrcd.enrich — optional APIs (pip install "nrcd[apis]")

Name Description
API_GUIDE Full signup guide (text); see also API keys guide
EnrichConfig Throttle intervals, cache TTL, API keys
api_keys_from_env Load keys from environment
fetch_weather Temperature, dew point, humidity, AQI for city/state + date
lookup_altitude_ft, lookup_altitude_detail, lookup_elevation_ft Meet altitude (USGS EPQS, ft)
enrich_race_context, enrich_race_context_result Backfill a RaceContext in place
run_enrich_jobs, EnrichJob, JobResult Batch enrichment with thread pool
EnrichResult, ApiUsage, WeatherData, AltitudeResult Result / usage dataclasses
cache_stats, clear_enrich_cache, reset_throttle_state Cache and rate-limit controls
AQI_HISTORY_AVAILABLE_FROM, AQI_HISTORY_AVAILABLE_UNIX AQI history window constants

Citation

NRCD: An Open Database of Collegiate Running with Unified Performance Standardization
Jonathan A. Karr Jr, Ryan M. Fryer, Ben Darden, Nicholas Pell, Kayla Ambrose, Evan Hall, Ramzi K. Bualuan, and Nitesh V. Chawla.
arXiv preprint (forthcoming).

Dataset (if using Zenodo export): Zenodo dataset

Author

Jonathan Karr ORCID Email

Development

pytest

See Changelog. Package version: src/nrcd/init.py (__version__).

License: MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nrcd-0.1.0.tar.gz (53.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nrcd-0.1.0-py3-none-any.whl (51.3 kB view details)

Uploaded Python 3

File details

Details for the file nrcd-0.1.0.tar.gz.

File metadata

  • Download URL: nrcd-0.1.0.tar.gz
  • Upload date:
  • Size: 53.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for nrcd-0.1.0.tar.gz
Algorithm Hash digest
SHA256 6e464114733b2c31fc485a591956cd1373778455bf2636b123d611009da5d772
MD5 d01beb67c84f02f276d189f3b2f8b0fa
BLAKE2b-256 6f4fbfc8c1cbaec2cc42c6b7ec73c676bc4d50a0ff83fa5d261d2b3726d9c846

See more details on using hashes here.

Provenance

The following attestation bundles were made for nrcd-0.1.0.tar.gz:

Publisher: publish.yml on National-Running-Club-Database/nrcd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file nrcd-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: nrcd-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 51.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for nrcd-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c354eaa7692f981537362cf03440bbfb1bcd7c10e78465c3d174b6dee148f5fc
MD5 bf7803211ea0d97965ad7eb9e7b9e808
BLAKE2b-256 d29588f193eb97549bc49e5d7b4585de680b8d778a06406217ad82989feade42

See more details on using hashes here.

Provenance

The following attestation bundles were made for nrcd-0.1.0-py3-none-any.whl:

Publisher: publish.yml on National-Running-Club-Database/nrcd

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page