# -*- coding: utf-8 -*-
# SPDX-FileCopyrightText: 2022-2023 Tanguy Fardet
# SPDX-License-Identifier: GPL-3.0-or-later
# orgmatt/excreta.py
"""
Functions to compute the amount of excreta (urine or feces) generated by a
human population over a certain amount of time.
"""
from typing import Optional
import numpy as _np
from pint import Quantity
from ._utils import (
_filter_dataframe, auto_format as _auto_format,
return_values as _rval)
from .data import excretions as _excr
from .typing import NumericArrayLike, NumericOrArray
from .units import (
check_dim as _check_dim, day as _day, ureg as _ureg)
__all__ = [
"urine_from_population",
"feces_from_population"
]
[docs]
@_auto_format
@_check_dim(arglist=('duration', 1, '[time]'), result='[length]**3')
def urine_from_population(
pop: NumericOrArray,
duration: Quantity,
ci: int = 0,
q: Optional[NumericArrayLike] = None,
**kwargs
) -> Quantity:
'''
Amount of urine generated by a given population over a certain duration
from the ``excretions.csv`` database.
Parameters
----------
pop : float or array-like object
Number of inhabitants.
duration : float [time]
Time interval over which the nitrogen is excreted.
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 `region="Europe"` to use only
values obtained from studies in European countries.
Returns
-------
urine : float or array of dimension D [length]**3
Volume of excreted urine 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 `pop`; otherwise, if `ci` > 0, one (low, mean, high)
result per `pop` entry, giving the volumes expected for the requested
confidence interval.
The dimension D is either 3, len(q), (len(pop), 3), or
(len(pop), len(q)) depending on `ci` and `q`.
'''
df_Ur = _excr[_excr.excreta == "urine"]
df_Ur = _filter_dataframe(df_Ur, kwargs)
res = _rval(df_Ur, "amount", pop, ci, q)
return _ureg("L/day") * res * duration
[docs]
@_auto_format
@_check_dim(arglist=('duration', 1, '[time]'), result='[mass]')
def feces_from_population(
pop: NumericOrArray,
duration: Quantity,
wet: bool = True,
ci: int = 0,
q: Optional[NumericArrayLike] = None,
**kwargs
) -> Quantity:
'''
Mass of feces generated by a given population over a certain duration from
the ``excretions.csv`` database.
Parameters
----------
pop : float or list-like object
Number of inhabitants.
duration : float [time]
Time interval over which the nitrogen is excreted.
wet : bool (optional, default: True)
Whether to compute the mass of wet feces (default) or dry solids.
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`)..
Returns
-------
feces : float or array of dimension D [mass]
Mass of excreted feces if `ci` is 0. If `q` is provided, returns the
values associated to each percentile in `q` for each entry in `pop`;
otherwise, if `ci` > 0, one (low, mean, high) result per `pop` entry,
giving the masses expected for the requested confidence interval.
The dimension D is either 3, len(q), (len(pop), 3), or
(len(pop), len(q)) depending on `ci` and `q`.
'''
ftype = "feces (wet)" if wet else "feces (dry)"
df_Fec = _excr[_excr.excreta == ftype]
df_Fec = _filter_dataframe(df_Fec, kwargs)
res = _rval(df_Fec, "amount", pop, ci, q)
return _ureg("g/day") * duration * res