Functional Weave
Code in Rust

health.egfr@1.0.1

impl/python.py

2,265 bytes · the Python implementation · view raw

Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.

import math

from .health_egfr_types import CreatinineUnit, Egfr, Sex
from .math_pow import pow  ← from math.pow ^1.0.0 · built alongside by fune
from .math_round_float import round_float  ← from math.round-float ^1.0.0 · built alongside by fune

#: Inker et al. 2021, footnote to table 2: mg/dL x 88.4 = umol/L.
_UMOL_PER_MG_DL = 88.4


def egfr_ckd_epi2021(creatinine: float, unit: CreatinineUnit, age_years: int, sex: Sex) -> Egfr:
    """Estimated GFR by the CKD-EPI 2021 creatinine equation without race
    (Inker et al., NEJM 2021;385:1737-49, table 2):

        eGFR = 142 x min(Scr/k, 1)^a x max(Scr/k, 1)^-1.200 x 0.9938^age x 1.012 [if female]

    with Scr in mg/dL, k 0.7 (female) or 0.9 (male), a -0.241 (female) or
    -0.302 (male). Powers go through math.pow so all three languages produce
    the same double; the whole-number result is rounded from the unrounded
    estimate, never from the one-decimal value (143.4993 is 143, not 144).
    """
    if unit == "umol-per-l":
        low, high = 10, 4000
    elif unit == "mg-per-dl":
        low, high = 0.1, 45
    else:
        raise ValueError("unit must be umol-per-l or mg-per-dl, received %r" % (unit,))
    ok = not isinstance(creatinine, bool) and isinstance(creatinine, (int, float)) and math.isfinite(creatinine)
    if not ok or creatinine < low or creatinine > high:
        raise ValueError("creatinine must be a number from %s to %s %s, received %r" % (low, high, unit, creatinine))
    if isinstance(age_years, bool) or not isinstance(age_years, int) or age_years < 18 or age_years > 120:
        raise ValueError("ageYears must be a whole number from 18 to 120, received %r" % (age_years,))
    if sex != "female" and sex != "male":
        raise ValueError("sex must be female or male, received %r" % (sex,))
    female = sex == "female"
    scr = float(creatinine) / _UMOL_PER_MG_DL if unit == "umol-per-l" else float(creatinine)
    kappa = 0.7 if female else 0.9
    alpha = -0.241 if female else -0.302
    ratio = scr / kappa
    # Below the knot the max() term is 1, above it the min() term is 1.
    creatinine_term = pow(ratio, alpha) if ratio <= 1 else pow(ratio, -1.2)
    estimate = 142 * creatinine_term * pow(0.9938, float(age_years))
    if female:
        estimate = estimate * 1.012
    return Egfr(value=round_float(estimate, 1), reported=int(round_float(estimate, 0)))