Spaces:
Runtime error
Runtime error
# %% | |
import numpy as np | |
import sympy as sp | |
from scipy.optimize import root_scalar | |
import ultraplot as uplt | |
from smitfit.symbol import Symbols | |
from smitfit.model import Model | |
import polars as pl | |
# %% | |
s = Symbols("TF1, TF2, TFR, R, T_TF, T_R, kD_MD, kD_MR", positive=True) | |
# %% | |
mb_ribosome = s.TFR + s.R - s.T_R # type: ignore | |
mb_TF = s.TF1 + 2 * s.TF2 + s.TFR - s.T_TF # type: ignore | |
eq_MD = s.TF1**2 - s.kD_MD * s.TF2 # type: ignore | |
eq_MR = (s.TF1 * s.R) - s.kD_MR * s.TFR # type: ignore | |
# | |
knowns = ["T_TF", "T_R", "kD_MD", "kD_MR"] | |
# solve for: TF1 | |
# take Monomer-dimer equillibrium, put it in mass balance TF to eliminate TF2 | |
sub_TF2 = (s.TF2, sp.solve(eq_MD, s.TF2)[0]) | |
# same for monomer dimer, eliminate TF_R | |
sub_mb = (s.R, sp.solve(mb_ribosome, s.R)[0]) | |
sub_TFR = (s.TFR, sp.solve(eq_MR.subs(*sub_mb), s.TFR)[0]) | |
# we know have an expr to find free TF monomer | |
eq_TF1 = mb_TF.subs([sub_TF2, sub_TFR]) | |
eq_TF1 | |
# %% | |
d = { | |
s.TF2: sp.solve(eq_MD, s.TF2)[0], | |
s.TFR: sp.solve(mb_TF, s.TFR)[0], | |
s.R: sp.solve(mb_ribosome, s.R)[0], | |
} | |
m = Model(d) | |
# %% | |
ld = sp.lambdify([s.TF1] + [s[k] for k in knowns], eq_TF1) | |
# %% | |
def solve_system(params: dict) -> dict: | |
args = tuple(params[k] for k in knowns) | |
# root find TF1 | |
sol = root_scalar(ld, bracket=(0, params["T_TF"]), args=args) | |
# calculate the others | |
ans = m(**params, TF1=sol.root) | |
return {"TF1": sol.root, **ans} | |
def make_df(records: list[dict]) -> pl.DataFrame: | |
df = pl.DataFrame(records) | |
cols = [ | |
(pl.col("TF1") + pl.col("TF2") + pl.col("TFR")).alias("total TF"), | |
(pl.col("TFR") + pl.col("R")).alias("total R"), | |
] | |
df = df.with_columns(cols) | |
return df | |
# %% | |
# The concentration of TF exceeds that of ribosomes (∼50 μM and ∼30 μM, respectively)[12,13] | |
# TF binds free ribosomal 50S subunits with a Kd of ∼1 μM | |
# Purified TF forms dimers with a Kd of 1–2 μM (ref. 14). | |
# " Real-time observation of trigger factor function on translating ribosomes", https://doi.org/10.1038/nature05225 | |
# "the cytosol contains 2.6 moles of trigger factor per mole of ribosomes. " | |
# The “trigger factor cycle” includes ribosomes, presecretory proteins, and the plasma membrane | |
# | |
ecoli_params = { | |
"T_TF": 50, | |
"T_R": 30, | |
"kD_MD": 1, | |
"kD_MR": 2, | |
} | |
solve_system(ecoli_params) | |
# %% | |
vmin, vmax = 1e-6, 1000e-6 | |
total_tf_protomer = np.logspace( | |
0, 4, endpoint=True, num=100 | |
) # total TF protomer from 1 uM to 1 | |
input_params = [ecoli_params | {"T_TF": v} for v in total_tf_protomer] | |
input_params | |
# %% | |
output_records = [solve_system(params) for params in input_params] | |
df = make_df(output_records) | |
# %% | |
species = ["TF1", "TF2", "TFR"] | |
cycle = iter(uplt.Cycle("default")) | |
fig, axes = uplt.subplots(nrows=2, aspect=2.5, axwidth="120mm") | |
for s in species: | |
axes[0].plot( | |
total_tf_protomer, | |
df.select(pl.col(s) / pl.col("total TF")), | |
label=s, | |
**next(cycle), | |
) | |
axes[0].format(title="TF") | |
species = ["TFR", "R"] | |
for s in species: | |
axes[1].plot( | |
total_tf_protomer, | |
df.select(pl.col(s) / pl.col("total R")), | |
label=s, | |
**next(cycle), | |
) | |
axes[1].format(title="ribosome") | |
axes.format( | |
ylim=(0, 1), | |
xscale="log", | |
xformatter="sci", | |
ylabel="Fractional population", | |
xlabel="Total protomer TF (uM)", | |
) | |
axes.legend(loc="r", ncols=1) | |
# %% | |
# lets repeat for ribosome titration, fixed 100 nM TF protomer concentration | |
microscopy_params = { | |
"T_TF": 1, # 100 nM | |
"kD_MD": 1, | |
"kD_MR": 1, | |
} | |
# %% | |
total_ribosome = np.linspace(0, 5, endpoint=True) | |
input_params = [microscopy_params | {"T_R": v} for v in total_ribosome] | |
# %% | |
output_records = [solve_system(params) for params in input_params] | |
df = make_df(output_records) | |
# %% | |
species = ["TF1", "TF2", "TFR"] | |
cycle = iter(uplt.Cycle("default")) | |
fig, axes = uplt.subplots(nrows=2, aspect=2.5, axwidth="120mm") | |
for s in species: | |
axes[0].plot( | |
total_ribosome, | |
df.select(pl.col(s) / pl.col("total TF")), | |
label=s, | |
**next(cycle), | |
) | |
axes[0].format(title="TF") | |
species = ["TFR", "R"] | |
for s in species: | |
axes[1].plot( | |
total_ribosome, | |
df.select(pl.col(s) / pl.col("total R")), | |
label=s, | |
**next(cycle), | |
) | |
axes[1].format(title="ribosome") | |
axes.format( | |
ylim=(0, 1), | |
# xscale="log", | |
xformatter="sci", | |
ylabel="Fractional population", | |
xlabel="Total protomer TF (uM)", | |
) | |
axes.legend(loc="r", ncols=1) | |
# %% | |