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 life123 import ChemData
from life123 import UniformCompartment
import plotly.express as px
import plotly.graph_objects as go
from life123 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_2"],
extra_js="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.21.2/cytoscape.umd.js")
-> Output will be LOGGED into the file 'state_space_1.log.htm'
# Initialize the system
chem_data = ChemData(names=["A", "B"])
# Reaction A <-> 3B , with 1st-order kinetics in both directions
chem_data.add_reaction(reactants="A", products=[(3,"B",1)], forward_rate=5., reverse_rate=2.)
chem_data.describe_reactions()
Number of reactions: 1 (at temp. 25 C) 0: A <-> 3 B (kF = 5 / kR = 2 / delta_G = -2,271.4 / K = 2.5) | 1st order in all reactants & products Set of chemicals involved in the above reactions: {'A', 'B'}
dynamics = UniformCompartment(chem_data=chem_data)
dynamics.set_conc(conc={"A": 10., "B": 50.},
snapshot=True)
dynamics.describe_state()
SYSTEM STATE at Time t = 0: 2 species: Species 0 (A). Conc: 10.0 Species 1 (B). Conc: 50.0 Set of chemicals involved in reactions: {'A', 'B'}
# Send the plot to the HTML log file
chem_data.plot_reaction_network("vue_cytoscape_2")
[GRAPHIC ELEMENT SENT TO LOG FILE `state_space_1.log.htm`]
dynamics.single_compartment_react(initial_step=0.05, n_steps=10, variable_steps=False)
10 total step(s) taken
df = dynamics.get_history()
df
SYSTEM TIME | A | B | caption | |
---|---|---|---|---|
0 | 0.00 | 10.000000 | 50.000000 | Initialized state |
1 | 0.05 | 12.500000 | 42.500000 | |
2 | 0.10 | 13.625000 | 39.125000 | |
3 | 0.15 | 14.131250 | 37.606250 | |
4 | 0.20 | 14.359063 | 36.922812 | |
5 | 0.25 | 14.461578 | 36.615266 | |
6 | 0.30 | 14.507710 | 36.476870 | |
7 | 0.35 | 14.528470 | 36.414591 | |
8 | 0.40 | 14.537811 | 36.386566 | |
9 | 0.45 | 14.542015 | 36.373955 | |
10 | 0.50 | 14.543907 | 36.368280 |
# Verify that the reaction has reached equilibrium
dynamics.is_in_equilibrium()
0: A <-> 3 B Final concentrations: [A] = 14.54 ; [B] = 36.37 1. Ratio of reactant/product concentrations, adjusted for reaction orders: 2.50059 Formula used: [B] / [A] 2. Ratio of forward/reverse reaction rates: 2.5 Discrepancy between the two values: 0.02341 % Reaction IS in equilibrium (within 1% tolerance)
True
dynamics.plot_history(colors=['navy', 'orange'])
fig0 = px.line(data_frame=dynamics.get_history(), x="A", y="B",
title="State space of reaction A <-> 3B : [A] vs. [B]",
color_discrete_sequence = ['#C83778'],
labels={"value":"concentration", "variable":"Chemical"})
fig0.show()
# Now show the individual data points
df['SYSTEM TIME'] = round(df['SYSTEM TIME'], 2) # To avoid clutter from too many digits, in the column
fig1 = px.scatter(data_frame=df, x="A", y="B",
title="Trajectory in State space: [A] vs. [B]",
hover_data=['SYSTEM TIME'])
fig1.update_traces(marker={"size": 6, "color": "#2FAC74"}) # Modify the style of the dots
# Add annotations (showing the System Time value) to SOME of the points, to avoid clutter
for ind in df.index: # for each row in the Pandas dataframe
label = df["SYSTEM TIME"][ind]
if ind == 0:
label = f"t={label}"
label_x = ind*16
label_y = 20 + ind*8 # A greater y value here means further DOWN!!
if (ind <= 3) or (ind%2 == 0):
fig1.add_annotation(x=df["A"][ind], y=df["B"][ind],
text=label,
font=dict(
size=10,
color="grey"
),
showarrow=True, arrowhead=0, ax=label_x, ay=label_y, arrowcolor="#b0b0b0",
bordercolor="#c7c7c7")
fig1.show()
# Combine the two above plots, while using the layout of fig1 (which includes the title and annotations)
all_fig = go.Figure(data=fig0.data + fig1.data, layout = fig1.layout)
all_fig.show()