U ("Up-regulator") up-regulates X , by sharing an upstream reagent S ("Source") across 2 separate reactions:¶2 S <-> U and S <-> X (both mostly forward)¶1st-order kinetics throughout.
Invoking Le Chatelier's principle, it can be seen that, starting from equilibrium, when [U] goes up, so does [S]; and when [S] goes up, so does [X].
Conversely, when [U] goes down, so does [S]; and when [S] goes down, so does [X].
This experiment is a counterpart of experiment up_regulate_2, with "upstream" rather than "downstream" reactions.
Note: numerical errors in the same reactions (with the same initial conditions) is explored in the experiment "large_time_steps_2"
LAST REVISED: May 26, 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 experiments.get_notebook_info import get_notebook_basename
from src.modules.reactions.reaction_data import ReactionData as chem
from src.modules.reactions.reaction_dynamics import ReactionDynamics
import numpy as np
import plotly.express as px
from src.modules.visualization.graphic_log import GraphicLog
# Initialize the HTML logging
log_file = get_notebook_basename() + ".log.htm" # Use the notebook base filename for the log file
# Set up the use of some specified graphic (Vue) components
GraphicLog.config(filename=log_file,
components=["vue_cytoscape_1"],
extra_js="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.21.2/cytoscape.umd.js")
-> Output will be LOGGED into the file 'up_regulate_3.log.htm'
# Initialize the system
chem_data = chem(names=["U", "X", "S"])
# Reaction 2 S <-> U , with 1st-order kinetics for all species (mostly forward)
chem_data.add_reaction(reactants=[(2, "S")], products="U",
forward_rate=8., reverse_rate=2.)
# Reaction S <-> X , with 1st-order kinetics for all species (mostly forward)
chem_data.add_reaction(reactants="S", products="X",
forward_rate=6., reverse_rate=3.)
chem_data.describe_reactions()
# Send the plot of the reaction network to the HTML log file
graph_data = chem_data.prepare_graph_network()
GraphicLog.export_plot(graph_data, "vue_cytoscape_1")
Number of reactions: 2 (at temp. 25 C) 0: 2 S <-> U (kF = 8 / kR = 2 / Delta_G = -3,436.56 / K = 4) | 1st order in all reactants & products 1: S <-> X (kF = 6 / kR = 3 / Delta_G = -1,718.28 / K = 2) | 1st order in all reactants & products [GRAPHIC ELEMENT SENT TO LOG FILE `up_regulate_3.log.htm`]
dynamics = ReactionDynamics(reaction_data=chem_data)
dynamics.set_conc(conc={"U": 50., "X": 100., "S": 0.})
dynamics.describe_state()
SYSTEM STATE at Time t = 0: 3 species: Species 0 (U). Conc: 50.0 Species 1 (X). Conc: 100.0 Species 2 (S). Conc: 0.0
dynamics = ReactionDynamics(reaction_data=chem_data)
dynamics.set_conc(conc={"U": 50., "X": 100., "S": 0.})
#dynamics.describe_state()
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.01, target_end_time=1.5,
variable_steps=True, explain_variable_steps=False)
#df = dynamics.get_history()
#dynamics.explain_time_advance()
INFO: the tentative time step (0.01) 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.005) [Step started at t=0, and will rewind there]
43 total step(s) taken
dynamics.plot_curves(colors=['green', 'orange', 'blue'])
# Verify that the reaction has reached equilibrium
dynamics.is_in_equilibrium()
2 S <-> U
Final concentrations: [U] = 72.65 ; [S] = 18.19
1. Ratio of reactant/product concentrations, adjusted for reaction orders: 3.99404
Formula used: [U] / [S]
2. Ratio of forward/reverse reaction rates: 4.0
Discrepancy between the two values: 0.1489 %
Reaction IS in equilibrium (within 1% tolerance)
S <-> X
Final concentrations: [X] = 36.52 ; [S] = 18.19
1. Ratio of reactant/product concentrations, adjusted for reaction orders: 2.00759
Formula used: [X] / [S]
2. Ratio of forward/reverse reaction rates: 2.0
Discrepancy between the two values: 0.3793 %
Reaction IS in equilibrium (within 1% tolerance)
True
dynamics.describe_state()
SYSTEM STATE at Time t = 1.604933: 3 species: Species 0 (U). Conc: 72.64754791961869 Species 1 (X). Conc: 36.515929976181866 Species 2 (S). Conc: 18.188974184580783
dynamics.set_chem_conc(species_name="U", conc=100.)
dynamics.describe_state()
SYSTEM STATE at Time t = 1.604933: 3 species: Species 0 (U). Conc: 100.0 Species 1 (X). Conc: 36.515929976181866 Species 2 (S). Conc: 18.188974184580783
dynamics.get_history(tail=3)
| SYSTEM TIME | U | X | S | caption | |
|---|---|---|---|---|---|
| 42 | 1.297039 | 72.238529 | 37.297254 | 18.225687 | |
| 43 | 1.604933 | 72.647548 | 36.515930 | 18.188974 | |
| 44 | 1.604933 | 100.000000 | 36.515930 | 18.188974 | Set concentration of `U` |
dynamics.set_step_factors(upshift=1.2, downshift=0.5, abort=0.4) # Needs to tighten to time advance, to prevent mild instability
dynamics.single_compartment_react(initial_step=0.01, target_end_time=3.0,
variable_steps=True, explain_variable_steps=False)
#df = dynamics.get_history()
#dynamics.explain_time_advance()
19 total step(s) taken
dynamics.plot_curves(colors=['green', 'orange', 'blue'])
# Verify that the reaction has reached equilibrium
dynamics.is_in_equilibrium()
2 S <-> U
Final concentrations: [U] = 92.63 ; [S] = 23.18
1. Ratio of reactant/product concentrations, adjusted for reaction orders: 3.99634
Formula used: [U] / [S]
2. Ratio of forward/reverse reaction rates: 4.0
Discrepancy between the two values: 0.09147 %
Reaction IS in equilibrium (within 1% tolerance)
S <-> X
Final concentrations: [X] = 46.26 ; [S] = 23.18
1. Ratio of reactant/product concentrations, adjusted for reaction orders: 1.99594
Formula used: [X] / [S]
2. Ratio of forward/reverse reaction rates: 2.0
Discrepancy between the two values: 0.2029 %
Reaction IS in equilibrium (within 1% tolerance)
True
dynamics.describe_state()
SYSTEM STATE at Time t = 3.152333: 3 species: Species 0 (U). Conc: 92.63103996217262 Species 1 (X). Conc: 46.26386257327225 Species 2 (S). Conc: 23.178961663145174
dynamics.set_chem_conc(species_name="U", conc=150.)
dynamics.describe_state()
SYSTEM STATE at Time t = 3.152333: 3 species: Species 0 (U). Conc: 150.0 Species 1 (X). Conc: 46.26386257327225 Species 2 (S). Conc: 23.178961663145174
dynamics.get_history(tail=3)
| SYSTEM TIME | U | X | S | caption | |
|---|---|---|---|---|---|
| 62 | 2.886100 | 92.695247 | 46.170745 | 23.143666 | |
| 63 | 3.152333 | 92.631040 | 46.263863 | 23.178962 | |
| 64 | 3.152333 | 150.000000 | 46.263863 | 23.178962 | Set concentration of `U` |
dynamics.single_compartment_react(initial_step=0.01, target_end_time=4.5,
variable_steps=True, explain_variable_steps=False)
#dynamics.get_history()
#dynamics.explain_time_advance()
20 total step(s) taken
dynamics.plot_curves(colors=['green', 'orange', 'blue'])
# Verify that the reaction has reached equilibrium
dynamics.is_in_equilibrium(explain=False)
True
dynamics.describe_state()
SYSTEM STATE at Time t = 4.709733: 3 species: Species 0 (U). Conc: 134.37031316880427 Species 1 (X). Conc: 67.07941550667395 Species 2 (S). Conc: 33.62278239213483
dynamics.set_chem_conc(species_name="U", conc=80.)
dynamics.describe_state()
SYSTEM STATE at Time t = 4.709733: 3 species: Species 0 (U). Conc: 80.0 Species 1 (X). Conc: 67.07941550667395 Species 2 (S). Conc: 33.62278239213483
dynamics.get_history(tail=3)
| SYSTEM TIME | U | X | S | caption | |
|---|---|---|---|---|---|
| 83 | 4.443500 | 134.497997 | 66.882281 | 33.564550 | |
| 84 | 4.709733 | 134.370313 | 67.079416 | 33.622782 | |
| 85 | 4.709733 | 80.000000 | 67.079416 | 33.622782 | Set concentration of `U` |
dynamics.single_compartment_react(initial_step=0.01, target_end_time=6.,
variable_steps=True, explain_variable_steps=False)
19 total step(s) taken
#dynamics.history.get_dataframe()
#dynamics.explain_time_advance()
dynamics.plot_curves(colors=['green', 'orange', 'blue'])
# Verify that the reaction has reached equilibrium
dynamics.is_in_equilibrium(explain=False)
True
IDEAS TO EXPLORE:
Effect of the stoichiometry and the Delta_G on the "amplification" of the signal (from [U] to [X])
Effect of a continuously-varying (maybe oscillating [U]), and its being affected by the reactions' kinetics
Combining this experiment and up_regulate_2 in a "bifan motif"