A <-> B with and without an enzyme¶LAST REVISED: June 4, 2023
import set_path # Importing this module will add the project's home directory to sys.path
Added 'D:\Docs\- MY CODE\BioSimulations\life123-Win7' to sys.path
from src.modules.reactions.reaction_data import ChemData
from src.modules.reactions.reaction_dynamics import ReactionDynamics
import numpy as np
import plotly.express as px
# Initialize the system
chem_data = ChemData(names=["A", "B"])
# Reaction A <-> B , with 1st-order kinetics, and a forward rate that is slower than it would be with the enzyme of part 2
chem_data.add_reaction(reactants="A", products="B",
forward_rate=1., delta_G=-3989.73)
chem_data.describe_reactions()
Number of reactions: 1 (at temp. 25 C) 0: A <-> B (kF = 1 / kR = 0.2 / Delta_G = -3,989.73 / K = 5.00001) | 1st order in all reactants & products
dynamics = ReactionDynamics(reaction_data=chem_data)
dynamics.set_conc(conc={"A": 20., "B": 0.},
snapshot=True)
dynamics.describe_state()
SYSTEM STATE at Time t = 0: 2 species: Species 0 (A). Conc: 20.0 Species 1 (B). Conc: 0.0
dynamics.set_diagnostics() # To save diagnostic information about the call to single_compartment_react()
# All of these settings are currently close to the default values... but subject to change; set for repeatability
dynamics.set_thresholds(norm="norm_A", low=0.5, high=0.8, abort=1.44)
dynamics.set_thresholds(norm="norm_B", low=0.08, high=0.5, abort=1.5)
dynamics.set_step_factors(upshift=1.5, downshift=0.5, abort=0.5)
dynamics.set_error_step_factor(0.5)
dynamics.single_compartment_react(initial_step=0.1, reaction_duration=3.0,
variable_steps=True, explain_variable_steps=False)
* INFO: the tentative time step (0.1) leads to a least one norm value > its ABORT threshold:
-> will backtrack, and re-do step with a SMALLER delta time, multiplied by 0.5 (set to 0.05) [Step started at t=0, and will rewind there]
30 total step(s) taken
#dynamics.explain_time_advance()
dynamics.plot_curves(colors=['darkorange', 'green'], show_intervals=True, title_prefix="WITHOUT enzyme")
dynamics.curve_intersection("A", "B", t_start=0, t_end=1.0)
Min abs distance found at data row: 18
(0.7406363068115296, 10.0)
# Verify that the reaction has reached equilibrium
dynamics.is_in_equilibrium(tolerance=3)
0: A <-> B
Final concentrations: [B] = 16.6 ; [A] = 3.398
1. Ratio of reactant/product concentrations, adjusted for reaction orders: 4.88533
Formula used: [B] / [A]
2. Ratio of forward/reverse reaction rates: 5.000005788498923
Discrepancy between the two values: 2.293 %
Reaction IS in equilibrium (within 3% tolerance)
True
This in an approximation that we'll drop in later experiments
# Initialize the system
chem_data = ChemData(names=["A", "B", "E"])
# Reaction A + E <-> B + E , with 1st-order kinetics, and a forward rate that is faster than it was without the enzyme
# Thermodynamically, there's no change from the reaction without the enzyme
chem_data.add_reaction(reactants=["A", "E"], products=["B", "E"],
forward_rate=10., delta_G=-3989.73)
chem_data.describe_reactions() # Notice how the enzyme `E` is noted in the printout below
Number of reactions: 1 (at temp. 25 C) 0: A + E <-> B + E (kF = 10 / kR = 2 / Delta_G = -3,989.73 / K = 5.00001) | Enzyme: E | 1st order in all reactants & products
dynamics = ReactionDynamics(reaction_data=chem_data)
dynamics.set_conc(conc={"A": 20., "B": 0., "E": 30.},
snapshot=True) # Plenty of enzyme `E`
dynamics.describe_state()
SYSTEM STATE at Time t = 0: 3 species: Species 0 (A). Conc: 20.0 Species 1 (B). Conc: 0.0 Species 2 (E). Conc: 30.0
dynamics.set_diagnostics() # To save diagnostic information about the call to single_compartment_react()
# All of these settings are currently close to the default values... but subject to change; set for repeatability
dynamics.set_thresholds(norm="norm_A", low=0.5, high=0.8, abort=1.44)
dynamics.set_thresholds(norm="norm_B", low=0.08, high=0.5, abort=1.5)
dynamics.set_step_factors(upshift=1.2, downshift=0.5, abort=0.4)
dynamics.set_error_step_factor(0.25)
dynamics.single_compartment_react(initial_step=0.1, reaction_duration=0.1,
variable_steps=True, explain_variable_steps=False)
*** CAUTION: negative concentration in chemical `A` in step starting at t=0. It will be AUTOMATICALLY CORRECTED with a reduction in time step size, as follows:
INFO: the tentative time step (0.1) leads to a NEGATIVE concentration of `A` from reaction A + E <-> B + E (rxn # 0):
Baseline value: 20 ; delta conc: -600
-> will backtrack, and re-do step with a SMALLER delta time, multiplied by 0.25 (set to 0.025) [Step started at t=0, and will rewind there]
*** CAUTION: negative concentration in chemical `A` in step starting at t=0. It will be AUTOMATICALLY CORRECTED with a reduction in time step size, as follows:
INFO: the tentative time step (0.025) leads to a NEGATIVE concentration of `A` from reaction A + E <-> B + E (rxn # 0):
Baseline value: 20 ; delta conc: -150
-> will backtrack, and re-do step with a SMALLER delta time, multiplied by 0.25 (set to 0.00625) [Step started at t=0, and will rewind there]
*** CAUTION: negative concentration in chemical `A` in step starting at t=0. It will be AUTOMATICALLY CORRECTED with a reduction in time step size, as follows:
INFO: the tentative time step (0.00625) leads to a NEGATIVE concentration of `A` from reaction A + E <-> B + E (rxn # 0):
Baseline value: 20 ; delta conc: -37.5
-> will backtrack, and re-do step with a SMALLER delta time, multiplied by 0.25 (set to 0.0015625) [Step started at t=0, and will rewind there]
* INFO: the tentative time step (0.0015625) leads to a least one norm value > its ABORT threshold:
-> will backtrack, and re-do step with a SMALLER delta time, multiplied by 0.4 (set to 0.000625) [Step started at t=0, and will rewind there]
* INFO: the tentative time step (0.000625) leads to a least one norm value > its ABORT threshold:
-> will backtrack, and re-do step with a SMALLER delta time, multiplied by 0.4 (set to 0.00025) [Step started at t=0, and will rewind there]
Some steps were backtracked and re-done, to prevent negative concentrations or excessively large concentration changes
42 total step(s) taken
#dynamics.explain_time_advance()
dynamics.plot_curves(colors=['darkorange', 'green', 'violet'], show_intervals=True, title_prefix="WITH enzyme")
dynamics.curve_intersection("A", "B", t_start=0, t_end=0.02)
Min abs distance found at data row: 15
(0.0024615346985334676, 10.0)
# Verify that the reaction has reached equilibrium
dynamics.is_in_equilibrium()
0: A + E <-> B + E
Final concentrations: [B] = 16.67 ; [E] = 30 ; [A] = 3.334 ; [E] = 30
1. Ratio of reactant/product concentrations, adjusted for reaction orders: 4.99958
Formula used: ([B][E]) / ([A][E])
2. Ratio of forward/reverse reaction rates: 5.000005788498923
Discrepancy between the two values: 0.008527 %
Reaction IS in equilibrium (within 1% tolerance)
True
The concentrations of A and B now become equal (cross-over) at t=0.00246 , rather than t=0.740
dynamics.get_history()
| SYSTEM TIME | A | B | E | caption | |
|---|---|---|---|---|---|
| 0 | 0.000000 | 20.000000 | 0.000000 | 30.0 | Initial state |
| 1 | 0.000250 | 18.500000 | 1.500000 | 30.0 | |
| 2 | 0.000500 | 17.135000 | 2.865000 | 30.0 | |
| 3 | 0.000625 | 16.513925 | 3.486075 | 30.0 | |
| 4 | 0.000750 | 15.920798 | 4.079202 | 30.0 | |
| 5 | 0.000875 | 15.354362 | 4.645638 | 30.0 | |
| 6 | 0.001000 | 14.813416 | 5.186584 | 30.0 | |
| 7 | 0.001125 | 14.296812 | 5.703188 | 30.0 | |
| 8 | 0.001250 | 13.803456 | 6.196544 | 30.0 | |
| 9 | 0.001375 | 13.332300 | 6.667700 | 30.0 | |
| 10 | 0.001525 | 12.792356 | 7.207644 | 30.0 | |
| 11 | 0.001675 | 12.281569 | 7.718431 | 30.0 | |
| 12 | 0.001855 | 11.701723 | 8.298277 | 30.0 | |
| 13 | 0.002071 | 11.050997 | 8.949003 | 30.0 | |
| 14 | 0.002330 | 10.330846 | 9.669154 | 30.0 | |
| 15 | 0.002589 | 9.677894 | 10.322106 | 30.0 | |
| 16 | 0.002900 | 8.967465 | 11.032535 | 30.0 | |
| 17 | 0.003274 | 8.210411 | 11.789589 | 30.0 | |
| 18 | 0.003647 | 7.555081 | 12.444919 | 30.0 | |
| 19 | 0.004095 | 6.874353 | 13.125647 | 30.0 | |
| 20 | 0.004543 | 6.303387 | 13.696613 | 30.0 | |
| 21 | 0.004991 | 5.824486 | 14.175514 | 30.0 | |
| 22 | 0.005528 | 5.342468 | 14.657532 | 30.0 | |
| 23 | 0.006066 | 4.953716 | 15.046284 | 30.0 | |
| 24 | 0.006711 | 4.577479 | 15.422521 | 30.0 | |
| 25 | 0.007485 | 4.230824 | 15.769176 | 30.0 | |
| 26 | 0.008413 | 3.930744 | 16.069256 | 30.0 | |
| 27 | 0.009528 | 3.691047 | 16.308953 | 30.0 | |
| 28 | 0.010865 | 3.518817 | 16.481183 | 30.0 | |
| 29 | 0.012470 | 3.411650 | 16.588350 | 30.0 | |
| 30 | 0.014396 | 3.357349 | 16.642651 | 30.0 | |
| 31 | 0.016707 | 3.337366 | 16.662634 | 30.0 | |
| 32 | 0.019480 | 3.333337 | 16.666663 | 30.0 | |
| 33 | 0.022808 | 3.333329 | 16.666671 | 30.0 | |
| 34 | 0.026802 | 3.333331 | 16.666669 | 30.0 | |
| 35 | 0.031594 | 3.333330 | 16.666670 | 30.0 | |
| 36 | 0.037345 | 3.333331 | 16.666669 | 30.0 | |
| 37 | 0.044245 | 3.333329 | 16.666671 | 30.0 | |
| 38 | 0.052526 | 3.333331 | 16.666669 | 30.0 | |
| 39 | 0.062463 | 3.333327 | 16.666673 | 30.0 | |
| 40 | 0.074388 | 3.333341 | 16.666659 | 30.0 | |
| 41 | 0.088697 | 3.333284 | 16.666716 | 30.0 | |
| 42 | 0.105869 | 3.333567 | 16.666433 | 30.0 |