Enzymatic System: Michaelis Menten Model

This notebook shows two reductions for an enzymatic reaction system with AutoReduce: first a conservation-law reduction, then a quasi-steady-state approximation (QSSA). The goal is to keep the substrate and product dynamics while eliminating intermediate enzyme-complex states.

Model

The reaction structure is

\[E + S \rightleftharpoons_{k_2}^{k_1} C \rightarrow^{k_3} E + P.\]

Conservation law:

With total enzyme \(E_T\), the conservation law is

\[E + C = E_T.\]

After substituting \(E = E_T - C\), the system is

\[\begin{split}\begin{aligned} \dot{S} &= -k_1(E_T-C)S + k_2C, \\ \dot{C} &= k_1(E_T-C)S - (k_2+k_3)C, \\ \dot{P} &= k_3C. \end{aligned}\end{split}\]

We will now show how AutoReduce can be used to solve for the reduced model by applying conservation laws automatically. That is, we will use AutoReduce to find the model above starting from the enzymatic system CRN. This “trivial” example is designed to demonstrate the most fundamental features of AutoReduce. For more interesting examples, see the other example notebooks.

Import libraries and define symbols

[ ]:
import numpy as np
from sympy import simplify, symbols

from autoreduce import System, solve_conservation_laws, solve_timescale_separation

# define all symbols using sympy.symbols (see note below on supported model imports)
S, E, C, P, k1, k2, k3, E_T = symbols("S,E,C,P,k1,k2,k3,E_T")

Create a system in AutoReduce

Here, we use the Sympy symbols to define the system. AutoReduce also accepts pre-defined models in standard control theory or system biology formats: python-control, sbml, and pyDMD.

[ ]:
# define variables and parameters
x = [S, E, C, P]
params = [k1, k2, k3, E_T]
param_values = [1.0, 0.5, 0.25, 10.0]
x_init = [10.0, 0.0, 0.0, 0.0]

# define output of choice / interest using the C matrix
# here, C is the matrix of the output equation: y = Cx.
# alternatively, y = g(x,u), a nonlinear function is also supported.

f = [
    -k1 * E * S + k2 * C,
    (k2 + k3) * C - k1 * E * S,
    k1 * E * S - (k2 + k3) * C,
    k3 * C,
]

system = System(
    x,
    f,
    params=params,
    params_values=param_values,
    x_init=x_init,
    C=np.array([[0, 0, 0, 1]]),
)

View the system

[ ]:
system.pretty_print()

Solve conservation laws

To solve (apply) conservation laws to a model, you can use the solve_conservation_laws function directly on the System. This will automatically find conserved sets and reduce the system accordingly.

In this example, we expect that AutoReduce will find the conservation law \(E + C = E_T\) and reduce the system to the form shown above. The search depth is set to 2 because this conservation law is detected by summing two ODE terms, \(\dot{E}+\dot{C}=0\).

[ ]:
conserved_system = solve_conservation_laws(
    system,
    conservation_search_depth=2,
    total_quantities={"E_T": param_values[-1]},
    states_to_eliminate=[E],
)

Check the reduced system after applying the conservation law

Print the conserved system states:

[ ]:
print(conserved_system.x)

Print the conserved system equations:

[ ]:
from sympy import pprint
for i in range(len(conserved_system.f)):
    pprint(conserved_system.f[i])

Quasi-steady-state approximation

For the standard Michaelis-Menten reduction, the enzyme complex \(C\) is treated as the fast state (at quasi-steady-state). AutoReduce can solve the reduced dynamics automatically using the solve_timescale_separation function.

[ ]:
reduced_system, collapsed_system = solve_timescale_separation(
    conserved_system,
    slow_states=[S, P],
    fast_states=[C],
)

Reduced dynamics

The reduced system has states reduced_system.x, which are \([S, P]\). The symbolic dynamics are reduced_system.f, shown above.

The collapsed system records the eliminated fast state and its algebraic condition. You can explore the collapsed system by printing collapsed_system.x and collapsed_system.f.

[ ]:
collapsed_system.x, collapsed_system.f

[ ]:
# end