enzyme_1_a¶E + S <-> ES (reversible), and ES -> E + P (irreversible).
The results are identical, because the algorithm (including the choice of adaptive variable time steps) is the same. The only difference here is that we aren't making use of the native support for enzymatic reactions.
Two other reactions being assumed negligible, and not included, are :
the enzyme Adenosine deaminase with the substrate 2,6-Diamino-9-β-D-deoxyribofuranosyl-9-H-purine,
and the initial concentration values choosen below, all satisfy the customary Michaelis-Menten assumptions that [E] << [S] and that the reaction rate constants satisfy k1_reverse >> k2_forward
For this reaction: k1_forward = 18, k1_reverse = 100, k2_forward = 49
Source of kinetic parameters: page 16 of "Analysis of Enzyme Reaction Kinetics, Vol. 1", by F. Xavier Malcata, Wiley, 2023
LAST_REVISED = "Sep. 2, 2025"
LIFE123_VERSION = "1.0.0rc6" # Library version this experiment is based on
#import set_path # Using MyBinder? Uncomment this before running the next cell!
#import sys
#sys.path.append("C:/some_path/my_env_or_install") # CHANGE to the folder containing your venv or libraries installation!
# NOTE: If any of the imports below can't find a module, uncomment the lines above, or try: import set_path
import ipynbname
import pandas as pd
from life123 import check_version, ChemData, UniformCompartment, GraphicLog, PlotlyHelper
check_version(LIFE123_VERSION) # To check compatibility
OK
# Initialize the HTML logging (for the graphics)
log_file = ipynbname.name() + ".log.htm" # Use the notebook base filename for the log file
# IN CASE OF PROBLEMS, set manually to any desired name
# Set up the use of some specified graphic (Vue) components
GraphicLog.config(filename=log_file,
components=["vue_cytoscape_2"],
extra_js="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.21.2/cytoscape.umd.js")
-> Output will be LOGGED into the file 'enzyme_1_a_technical.log.htm'
enzyme_1_a, but WITHOUT making use of native support for enzymatic reactions¶chem_data = ChemData(names=["P", "ES"], plot_colors=["green", "red"])
# Our Enzyme
chem_data.add_chemical(name="Adenosine deaminase", label="E", plot_color="violet")
# Our Substrate
chem_data.add_chemical(name="2,6-Diamino-9-β-D-deoxyribofuranosyl-9-H-purine", label="S", plot_color="darkturquoise")
chem_data.all_chemicals()
| name | label | plot_color | |
|---|---|---|---|
| 0 | P | P | green |
| 1 | ES | ES | red |
| 2 | Adenosine deaminase | E | violet |
| 3 | 2,6-Diamino-9-β-D-deoxyribofuranosyl-9-H-purine | S | darkturquoise |
# Here we use the "slower" preset for the variable steps, a very conservative option prioritizing accuracy over speed
uc = UniformCompartment(chem_data=chem_data, preset="slower")
enzyme_1_a ...¶# Reaction E + S <-> ES , with 1st-order kinetics,
uc.add_reaction(reactants=["E", "S"], products="ES",
kF=18., kR=100.)
# Reaction ES <-> E + P , with 1st-order kinetics, ignoring the reverse reaction
uc.add_reaction(reactants="ES", products=["E", "P"],
kF=49., kR=0)
uc.describe_reactions()
Number of reactions: 2
0: E + S <-> ES (Elementary Synthesis reaction) (kF = 18 / kR = 100 / delta_G = 4,250.9 / K = 0.18 / Temp = 25 C)
1: ES <-> E + P (Elementary Decomposition reaction) (kF = 49 / kR = 0 / Temp = 25 C)
Chemicals involved in the above reactions: {"P" (green), "ES" (red), "E" (violet), "S" (darkturquoise)}
# Send a plot of the network of reactions to the HTML log file
# NOTE: 2 reactions, instead of the 1 reaction of experiment `enzyme_1_a` will now show up
uc.plot_reaction_network("vue_cytoscape_2")
[GRAPHIC ELEMENT SENT TO LOG FILE `enzyme_1_a_technical.log.htm`]
S0 = 20.
E0 = 1.
uc.set_conc(conc={"S": S0, "E": E0}) # SMALL ampount of enzyme `E`, relative to substrate `S`
uc.describe_state()
SYSTEM STATE at Time t = 0: 4 species: Species 0 (P). Conc: 0.0 Species 1 (ES). Conc: 0.0 Species 2 (E). Conc: 1.0 Species 3 (S). Conc: 20.0 Chemicals involved in reactions: ['S', 'ES', 'P', 'E']
# Perform the reactions
uc.single_compartment_react(duration=1.5, initial_step=0.05)
827 total variable step(s) taken in 1.711 sec
Number of step re-do's because of negative concentrations: 2
Number of step re-do's because of elective soft aborts: 1
Norm usage: {'norm_A': 706, 'norm_B': 710, 'norm_C': 706, 'norm_D': 706}
System Time is now: 1.5039
uc.plot_history(show_intervals=True,
title_prefix="Small amout of E relative to S(0)")
plot_pandas() NOTICE: Excessive number of vertical lines (828) - only showing 1 every 6 lines
# Highlight a detail about the initial buildup of ES
uc.plot_history(title_prefix="DETAIL at early times",
range_x=[0, 0.5], range_y=[0, 2.])
ES (red) quickly builds up at the very beginning, from time 0 to roughly 0.01 ... and that, in the longer term, the enzyme returns to its unbound state E¶
P?¶One could take the numerical derivative (gradient) of the time values of [P] - but no need to! Reaction rates are computed in the course of the simulation, and stored in a rate-history dataframe
rates = uc.get_rate_history() # We'll be interested in rxn1_rate (the reaction that leads to `P`)
rates
| SYSTEM TIME | rxn0_rate | rxn1_rate | step | |
|---|---|---|---|---|
| 0 | 0.000000 | 360.000000 | 0.000000 | 0 |
| 1 | 0.000500 | 274.543200 | 8.820000 | 1 |
| 2 | 0.000750 | 243.269275 | 12.075109 | 2 |
| 3 | 0.000763 | 241.911753 | 12.216716 | 3 |
| 4 | 0.000769 | 241.237493 | 12.287060 | 4 |
| ... | ... | ... | ... | ... |
| 822 | 1.468805 | 0.253941 | 0.285397 | 822 |
| 823 | 1.475832 | 0.244291 | 0.274566 | 823 |
| 824 | 1.482859 | 0.235005 | 0.264142 | 824 |
| 825 | 1.489886 | 0.226068 | 0.254109 | 825 |
| 826 | 1.496913 | 0.217468 | 0.244454 | 826 |
827 rows × 4 columns
# Let's take a look at how the reaction rate varies with time
PlotlyHelper.plot_pandas(df=rates,
title="Reaction rate, dP/dt, over time",
x_var="SYSTEM TIME", fields="rxn1_rate",
x_label="time", y_label="dP/dt")
# A closer peek at its maximum value
PlotlyHelper.plot_pandas(df=rates,
title="Reaction rate, dP/dt, over time (DETAIL at early times)",
x_var="SYSTEM TIME", fields="rxn1_rate",
range_x=[0,0.05], range_y=[33., 34.5])
As we saw earlier, the time it took for ES to build up was about 0.01
Ignoring the brief initial transient phase, the reaction rate starts at about 34.1
ALL THE RESULTS ARE IDENTICAL TO WHAT WE HAD IN EXPERIMENT enzyme_1_a
(For additional analysis, see that experiment)