Source code for orgmatt.agrifood.human_consumption

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

from collections import defaultdict
from typing import Optional, Union

from pint import Quantity

from .._utils import _filter_dataframe, return_values, auto_format
from ..data import nutrients_intake
from ..typing import NumericArrayLike, NumericOrArray
from ..units import check_dim, day, g, gN, ureg


[docs] @check_dim(arglist=('nitrogen_mass', 0, '[mass]*[nitrogen]'), result='[mass]') def nitrogen_to_protein( nitrogen_mass: Quantity, food_type: Optional[str] = None ) -> Quantity: ''' Calculate the amount of nitrogen associated to a mass of protein based on the conversion factors from [Mariotti2008]_. Parameters ---------- protein_mass : float [mass]*[nitrogen] Mass of protein to convert to nitrogen content. food_type : str, optional (default: average conversion factor) Type of food considered, among: 'dairy', 'meat' (including fish and eggs), 'cereal' (except corn), 'corn', 'soy', 'legume' (except soy), and 'vegetable' (including mushrooms). If not specified or invalid, a default conversion factor of 5.6 g of protein per gram of nitrogen is used. References ---------- .. [Mariotti2008] Mariotti, Tomé, and Mirand. "Converting Nitrogen into Protein—Beyond 6.25 and Jones’ Factors." Critical Reviews in Food Science and Nutrition 48-2 (2008): 177‑84. :doi:`10.1080/10408390701279749`. ''' food_type = "other" if food_type is None else food_type convertor: dict[str, float] = defaultdict(lambda: 5.6) convertor.update({ "dairy": 5.85, "meat": 5.6, "cereal": 5.4, "corn": 5.6, "soybean": 5.5, "legume": 5.4, "vegetable": 4.4 }) return nitrogen_mass.to(gN).m * convertor[food_type.lower()] * g
[docs] @check_dim(arglist=('protein_mass', 0, '[mass]'), result='[mass]*[nitrogen]') def protein_to_nitrogen( protein_mass: Quantity, food_type: Optional[str] = None ) -> Quantity: ''' Calculate the amount of nitrogen associated to a mass of protein based on Jones' factors (simply 6.25 for now). Parameters ---------- protein_mass : float [mass] Mass of protein to convert to nitrogen content. food_type : str, optional (default: average conversion factor) Type of food considered, among: 'dairy', 'meat' (including fish and eggs), 'cereal' (except corn), 'corn', 'soy', 'legume' (except soy), and 'vegetable' (including mushrooms). Currently unused, a 6.25 conversion factor is used for all food types. ''' return protein_mass.to("gram").m / 6.25 * gN
[docs] @auto_format @check_dim(arglist=('duration', 1, '[time]'), result='[mass]*[X]') def nutrient_intake( pop: NumericOrArray, duration: Quantity, nutrient: str, ci: int = 0, q: Optional[NumericArrayLike] = None, **kwargs ) -> Quantity: ''' Compute the amount of nutrient ingested by a given population over a certain duration using the ``food.csv`` database. Parameters ---------- pop : float or list-like object Number of inhabitants. duration : float [time] Time interval over which the nitrogen is excreted. nutrient : str Nutrient of interest among ('N', 'K', 'P', 'Mg', 'Ca'). ci : int (optional, default: 0) Confidence interval (CI). If non-zero, the function will also return the low and high expected values corresponding to that CI. q : array-like of floats (optional: default: None) Percentiles to compute (supersedes `ci`). **kwargs : arguments to use a subset of the database Additional arguments can be use to restrict the results to a subset of the full database. E.g. one can add `excreta="feces"` to return only nitrogen contained in feces, or `region="Europe"` to use only values obtained from studies in European countries. Returns ------- nutrient_mass : float or array of dimension D [mass] Mean mass of excreted nitrogen if `q` is None or `ci` is 0. If `q` is provided, returns the values associated to each percentile in `q` for each entry in `amount`; otherwise one (low, mean, high) result per entry in `amount`, giving the masses expected for the requested confidence interval. The dimension D is either 3, len(q), (len(amount), 3), or (len(amount), len(q)) depending on `ci` and `q`. Notes ----- * Nitrogen results are computed from protein data via :func:`~orgmatt.agrifood.protein_to_nitrogen` using the default value. * By default, only values for adults are returned, use `group` or `age` to select a specific subpopulation. ''' # special case for N that is computed from protein data cmpd = "protein" if nutrient == "N" else nutrient df = nutrients_intake[nutrients_intake.compound == cmpd] df = _filter_dataframe(df, kwargs) nintake = return_values(df, "intake", pop, ci, q) if cmpd == "protein": # special case for N, we convert from N to protein return protein_to_nitrogen(duration*nintake*g/day) return ureg(f'mg{nutrient}/day') * duration * nintake