Skip to content

Constitutive RMA

rma_kinetics.models.ConstitutiveRMA

Simple constitutive expression of released markers of activity.

Attributes:

Name Type Description
rma_prod_rate float

RMA production rate (concentration/time).

rma_rt_rate float

RMA reverse transcytosis rate (1/time).

rma_deg_rate float

RMA degradation rate (1/time).

time_units float

(Time): time units (Default = Time.hours).

conc_units float

(Concentration): concentration units (Default = Concentration.nanomolar).

Source code in src/rma_kinetics/models/constitutive.py
class ConstitutiveRMA(AbstractModel):
    """
    Simple constitutive expression of released markers of activity.

    Attributes:
        rma_prod_rate (float): RMA production rate (concentration/time).
        rma_rt_rate (float): RMA reverse transcytosis rate (1/time).
        rma_deg_rate (float): RMA degradation rate (1/time).
        time_units: (Time): time units (Default = Time.hours).
        conc_units: (Concentration): concentration units (Default = Concentration.nanomolar).
    """

    def __init__(
        self,
        rma_prod_rate: float,
        rma_rt_rate: float,
        rma_deg_rate: float,
        time_units: Time = Time.hours,
        conc_units: Concentration = Concentration.nanomolar
    ):
        super().__init__(
            rma_prod_rate,
            rma_rt_rate,
            rma_deg_rate,
            time_units=time_units,
            conc_units=conc_units
        )

    def _model(self, t: float, y: PyTree[float], args=None) -> PyTree[float]:
        r"""
        ODE model implementation. See the Model Equations section for more details.

        Info: Model Equations
            $$\begin{align}
            \dot{[RMA_{B}]} &= k_{RMA} - k_{RT}[RMA_{B}] \tag{1} \\
            \dot{[RMA_{P}]} &= k_{RT} - \gamma_{RMA}[RMA_{P}] \tag{2}
            \end{align}
            $$

            |Parameters|Description|Units (Example)|
            |----------|-----------|-----|
            |$k_{RMA}$|RMA production rate|Concentration/Time (nM/hr)|
            |$k_{RT}$|RMA reverse transcytosis rate|1/Time (1/hr)|
            |$\gamma_{RMA}$|RMA degradation rate|1/Time (1/hr)|
            |$[RMA_B]$|Brain RMA concentration|Concentration (nM)|
            |$[RMA_P]$|Plasma RMA concentration|Concentration (nM)|

        Arguments:
            t (float): Time point.
            y (PyTree[float]): Brain and plasma RMA concentrations.

        Returns:
            dydt (PyTree[float]): Change in brain and plasma RMA concentrations.
        """
        brain_rma, plasma_rma = y
        plasma_rma_transport_flux = self.rma_rt_rate * brain_rma
        dbrain_rma = self.rma_prod_rate - plasma_rma_transport_flux
        dplasma_rma = plasma_rma_transport_flux - (self.rma_deg_rate * plasma_rma)

        return dbrain_rma, dplasma_rma

    def _terms(self) -> AbstractTerm:
        return ODETerm(self._model)

simulate(t0: float, t1: float, y0: PyTree[float], dt0: float | None = None, sampling_rate: float = 1, stepsize_controller: AbstractStepSizeController = PIDController(rtol=1e-05, atol=1e-05), max_steps: int = 4096, solver: AbstractSolver = Kvaerno3(), adjoint: AbstractAdjoint = RecursiveCheckpointAdjoint(), throw: bool = True, progress_meter: AbstractProgressMeter = NoProgressMeter())

Simulates model within the given time interval.

Wraps diffrax.diffeqsolve with specific defaults for RMA model simulation.

Parameters:

Name Type Description Default
t0 float

Start time of integration.

required
t1 float

Stop time of integration.

required
y0 PyTree[float]

Tuple of initial conditions.

required
dt0 float | None`

Initial step size if using adaptive step sizes, or size of all steps if using constant stepsize.

None
sampling_rate float

Sampling rate for saving solution.

1
stepsize_controller AbstractStepSizeController`

Determines how to change step size during integration.

PIDController(rtol=1e-05, atol=1e-05)
max_steps int

Max number of steps before stopping.

4096
solver AbstractSolver

Differential equation solver.

Kvaerno3()
adjoint AbstractAdjoint

How to differentiate.

RecursiveCheckpointAdjoint()
throw bool

Raise an exception if integration fails.

True

Returns:

Name Type Description
solution Solution

A solution object (parent of diffrax.Solution) with added plotting methods.

Source code in src/rma_kinetics/models/abstract.py
def simulate(
        self,
        t0: float,
        t1: float,
        y0: PyTree[float],
        dt0: float | None = None,
        sampling_rate: float = 1,
        stepsize_controller: AbstractStepSizeController = PIDController(rtol=1e-5, atol=1e-5),
        max_steps: int = 4096,
        solver: AbstractSolver = Kvaerno3(),
        adjoint: AbstractAdjoint = RecursiveCheckpointAdjoint(),
        throw: bool = True,
        progress_meter: AbstractProgressMeter = NoProgressMeter()
):
    """
    Simulates model within the given time interval.

    Wraps `diffrax.diffeqsolve` with specific defaults for RMA model simulation.

    Arguments:
        t0 (float): Start time of integration.
        t1 (float): Stop time of integration.
        y0 (PyTree[float]): Tuple of initial conditions.
        dt0 (float | None`): Initial step size if using adaptive
            step sizes, or size of all steps if using constant stepsize.
        sampling_rate (float): Sampling rate for saving solution.
        stepsize_controller (AbstractStepSizeController`): Determines
            how to change step size during integration.
        max_steps (int): Max number of steps before stopping.
        solver (AbstractSolver): Differential equation solver.
        adjoint (AbstractAdjoint): How to differentiate.
        throw (bool): Raise an exception if integration fails.

    Returns:
        solution (Solution): A solution object (parent of diffrax.Solution) with added plotting methods.
    """
    saveat = SaveAt(ts=jnp.linspace(t0, t1, int(t1*sampling_rate)))
    diffsol = diffeqsolve(
        self._terms(),
        solver,
        t0,
        t1,
        dt0,
        y0,
        saveat=saveat,
        stepsize_controller=stepsize_controller,
        max_steps=max_steps,
        adjoint=adjoint,
        throw=throw,
        progress_meter=progress_meter
    )

    return Solution(diffsol, self.time_units, self.conc_units)

_model(t: float, y: PyTree[float], args=None) -> PyTree[float]

ODE model implementation. See the Model Equations section for more details.

Model Equations
\[\begin{align} \dot{[RMA_{B}]} &= k_{RMA} - k_{RT}[RMA_{B}] \tag{1} \\ \dot{[RMA_{P}]} &= k_{RT} - \gamma_{RMA}[RMA_{P}] \tag{2} \end{align} \]
Parameters Description Units (Example)
\(k_{RMA}\) RMA production rate Concentration/Time (nM/hr)
\(k_{RT}\) RMA reverse transcytosis rate 1/Time (1/hr)
\(\gamma_{RMA}\) RMA degradation rate 1/Time (1/hr)
\([RMA_B]\) Brain RMA concentration Concentration (nM)
\([RMA_P]\) Plasma RMA concentration Concentration (nM)

Parameters:

Name Type Description Default
t float

Time point.

required
y PyTree[float]

Brain and plasma RMA concentrations.

required

Returns:

Name Type Description
dydt PyTree[float]

Change in brain and plasma RMA concentrations.

Source code in src/rma_kinetics/models/constitutive.py
def _model(self, t: float, y: PyTree[float], args=None) -> PyTree[float]:
    r"""
    ODE model implementation. See the Model Equations section for more details.

    Info: Model Equations
        $$\begin{align}
        \dot{[RMA_{B}]} &= k_{RMA} - k_{RT}[RMA_{B}] \tag{1} \\
        \dot{[RMA_{P}]} &= k_{RT} - \gamma_{RMA}[RMA_{P}] \tag{2}
        \end{align}
        $$

        |Parameters|Description|Units (Example)|
        |----------|-----------|-----|
        |$k_{RMA}$|RMA production rate|Concentration/Time (nM/hr)|
        |$k_{RT}$|RMA reverse transcytosis rate|1/Time (1/hr)|
        |$\gamma_{RMA}$|RMA degradation rate|1/Time (1/hr)|
        |$[RMA_B]$|Brain RMA concentration|Concentration (nM)|
        |$[RMA_P]$|Plasma RMA concentration|Concentration (nM)|

    Arguments:
        t (float): Time point.
        y (PyTree[float]): Brain and plasma RMA concentrations.

    Returns:
        dydt (PyTree[float]): Change in brain and plasma RMA concentrations.
    """
    brain_rma, plasma_rma = y
    plasma_rma_transport_flux = self.rma_rt_rate * brain_rma
    dbrain_rma = self.rma_prod_rate - plasma_rma_transport_flux
    dplasma_rma = plasma_rma_transport_flux - (self.rma_deg_rate * plasma_rma)

    return dbrain_rma, dplasma_rma

Example

from rma_kinetics.models import ConstitutiveRMA
import matplotlib.pyplot as plt

model = ConstitutiveRMA(5e-3, 0.6, 7e-3)
solution = model.simulate(t0=0, t1=72, y0=(0,0))
solution.plot_plasma_rma()
plt.gcf()

# we can also get plasma and brain RMA solutions directly
plasma_rma = solution.plasma_rma
brain_rma = solution.brain_rm