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)))