Source code for rtdpy.arbitrary

import typing

import numpy as np
from scipy import special

from rtdpy.rtd import RTD, RTDInputError


[docs]class Arbitrary(RTD): """ Create an arbitrary Residence Time Distribution (RTD) model from a function. Parameters ---------- fun : callable Function called with fun(t), where t is an np.ndarray of time. fun(t) should return the RTD at time t as np.ndarray. dt : scalar Time step for RTD. ``dt>0`` time_end : scalar End time for RTD. ``time_end>0`` Examples -------- >>> import matplotlib.pyplot as plt >>> import numpy as np >>> import rtdpy >>> # >>> # Create Square RTD function >>> def fun(t): ... # Square RTD function between times 10 and 15. ... return 1 / (15 - 10) * np.greater(t, 10) * np.less(t, 15) >>> rtdmodel = rtdpy.Arbitrary(fun, dt=.01, time_end=20) >>> plt.plot(rtdmodel.time, rtdmodel.exitage, label="Square RTD") >>> print(f"Square RTD mean residence time: {rtdmodel.mrt():.1f}") Square RTD mean residence time: 12.5 >>> # >>> # Create a model from experimental data >>> t_data = np.array([0, 1, 2, 3, 4, 5], dtype=float) >>> C_data = np.array([0.5, 0.2, 0.3, 0.15, 0.1, 0.0], dtype=float) >>> def fun_data(t): ... return np.interp(t, t_data, C_data, left=0, right=0) >>> rtdmodel_data = rtdpy.Arbitrary(fun_data, dt=.01, time_end=20) >>> # >>> # Plot arbitrary models >>> plt.plot(rtdmodel_data.time, rtdmodel_data.exitage, label="Data RTD") >>> plt.xlabel('Time') >>> plt.ylabel('Exit Age Function') >>> plt.legend() >>> print(f"Data RTD mean residence time: {rtdmodel_data.mrt():.1f}") Data RTD mean residence time: 1.7 >>> plt.show() """ def __init__(self, fun, dt, time_end): super().__init__(dt, time_end) if not isinstance(fun, typing.Callable): raise RTDInputError("fun is not callable") self._fun = fun self._exitage = self._calc_exitage() def _calc_exitage(self): """Calculte exit age function.""" return self.fun(self.time) @property def fun(self): """Return fun.""" return self._fun def __repr__(self): """Representation of object.""" return ("Arbitrary(fun={}, dt={}, time_end={})".format( self.fun, self.dt, self.time_end))