Source code for orgmatt.metabolism.intake_fraction

# -*- coding: utf-8 -*-
# SPDX-FileCopyrightText: 2022-2023 Tanguy Fardet
# SPDX-License-Identifier: GPL-3.0-or-later
# orgmatt/metabolism/intake_fraction.py

import numpy as np

from .._utils.age import _array_numeric_age
from .._utils.tools import is_arraylike
from ..typing import NumericOrArray
from ..units import Quantity, ureg


[docs] def intake_fraction_age( age: NumericOrArray | str, adult_consumption: Quantity, sex: str | None = None, ) -> NumericOrArray: ''' Fraction of the adult intake consumed at a given age. Parameters ---------- age : float, int, str or array Age of the individual(s) in years. If a string is provided, it must be a group name, an integer or a range, e.g. ("4" or "16-20"). adult_consumption : Quantity Average adult intake (mass of nitrogen, phosphorus, or potassium). sex : str, optional (default: average value) Sex of the indivual(s). ''' numeric_age = _array_numeric_age(age) if isinstance(sex, str) and sex != "mixed": sex = [sex] else: sex = ["male", "female"] res = None if adult_consumption.is_compatible_with("gN"): res = _nitrogen_intake_fraction_age(numeric_age, adult_consumption, sex) elif adult_consumption.is_compatible_with("gP"): res = _phosphorus_intake_fraction_age( numeric_age, adult_consumption, sex ) elif adult_consumption.is_compatible_with("gK"): res = _potassium_intake_fraction_age( numeric_age, adult_consumption, sex ) else: raise ValueError( f"Unsupported `adult_consumption`: {adult_consumption}." ) if is_arraylike(age): return res return res[0]
def _nitrogen_intake_fraction_age( age: np.ndarray, adult_consumption: Quantity, sex: list[str] ) -> NumericOrArray: min_child_frac = (2.4 * ureg("gN") / adult_consumption.to("gN")).m age_half = 2 age_peak = 55 age_diff_sex = 5 frac = np.zeros(len(age)) for s in sex: age_plateau = 14 if s == "female" else 18 frac_plateau = 0.83 if s == "female" else 1.1 frac_peak = 0.9 if s == "female" else 1.15 frac_100 = 0.725 if s == "female" else 0.95 keep = age <= age_half frac[keep] += ( min_child_frac + age[keep] * (0.5 - min_child_frac) / age_half ) keep = (age_half < age) & (age <= age_diff_sex) frac[keep] += 0.5 + (age[keep] - age_half) * 0.15 / ( age_diff_sex - age_half ) keep = (age_diff_sex < age) & (age <= age_plateau) frac[keep] += 0.65 + (age[keep] - age_diff_sex) * ( frac_plateau - 0.65 ) / (age_plateau - age_diff_sex) keep = (age_plateau < age) & (age < age_peak) frac[keep] += frac_plateau + (age[keep] - age_plateau) * ( frac_peak - frac_plateau ) / (age_peak - age_plateau) keep = age >= age_peak frac[keep] += frac_peak + (age[keep] - age_peak) * ( frac_100 - frac_peak ) / (100 - age_peak) return frac / len(sex) def _phosphorus_intake_fraction_age( age: np.ndarray, adult_consumption: Quantity, sex: list[str] ) -> NumericOrArray: min_child_frac = (375 * ureg("mgP") / adult_consumption.to("mgP")).m age_65pc = 2 age_peak = 55 age_diff_sex = 5 frac = np.zeros(len(age)) for s in sex: age_plateau = 13 if s == "female" else 16 frac_plateau = 0.88 if s == "female" else 1.1 frac_peak = 0.89 if s == "female" else 1.12 frac_100 = 0.71 if s == "female" else 0.925 keep = age <= age_65pc frac[keep] += ( min_child_frac + age[keep] * (0.65 - min_child_frac) / age_65pc ) keep = (age_65pc < age) & (age <= age_diff_sex) frac[keep] += 0.65 + (age[keep] - age_65pc) * 0.12 / ( age_diff_sex - age_65pc ) keep = (age_diff_sex < age) & (age <= age_plateau) frac[keep] += 0.77 + (age[keep] - age_diff_sex) * ( frac_plateau - 0.77 ) / (age_plateau - age_diff_sex) keep = (age_plateau < age) & (age < age_peak) frac[keep] += frac_plateau + (age[keep] - age_plateau) * ( frac_peak - frac_plateau ) / (age_peak - age_plateau) keep = age >= age_peak frac[keep] += frac_peak + (age[keep] - age_peak) * ( frac_100 - frac_peak ) / (100 - age_peak) return frac / len(sex) def _potassium_intake_fraction_age( age: np.ndarray, adult_consumption: Quantity, sex: list[str] ) -> NumericOrArray: min_child_frac = (800 * ureg("mgK") / adult_consumption.to("mgK")).m age_57pc = 2 age_peak = 55 age_diff_sex = 5 frac = np.zeros(len(age)) for s in sex: age_plateau = 13 if s == "female" else 10 frac_plateau = 0.8 if s == "female" else 0.875 frac_peak = 0.94 if s == "female" else 1.15 frac_100 = 0.825 if s == "female" else 1 keep = age <= age_57pc frac[keep] += ( min_child_frac + age[keep] * (0.57 - min_child_frac) / age_57pc ) keep = (age_57pc < age) & (age <= age_diff_sex) frac[keep] += 0.57 + (age[keep] - age_57pc) * 0.11 / ( age_diff_sex - age_57pc ) keep = (age_diff_sex < age) & (age <= age_plateau) frac[keep] += 0.68 + (age[keep] - age_diff_sex) * ( frac_plateau - 0.68 ) / (age_plateau - age_diff_sex) keep = (age_plateau < age) & (age < age_peak) frac[keep] += frac_plateau + (age[keep] - age_plateau) * ( frac_peak - frac_plateau ) / (age_peak - age_plateau) keep = age >= age_peak frac[keep] += frac_peak + (age[keep] - age_peak) * ( frac_100 - frac_peak ) / (100 - age_peak) return frac / len(sex)