Spaces:
Runtime error
Runtime error
File size: 4,438 Bytes
ef9fe45 0a4042c ef9fe45 0a4042c ef9fe45 0a4042c ef9fe45 0a4042c ef9fe45 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
from pathlib import Path
import altair as alt
import numpy as np
import pandas as pd
import solara
import sympy as sp
#
P1, P2, PT, k_on, k_off, kD = sp.symbols("P_1 P_2 P_T k_on k_off k_D", positive=True)
sol = sp.solve(
[
-2 * k_on * P1 * P1 + 2 * k_off * P2,
P1 + 2 * P2 - PT,
(k_off / k_on) - kD,
],
[P1, P2, k_on, k_off],
dict=True,
)
solve_for = [P1, P2]
inputs = [PT, kD]
lambdas = {s: sp.lambdify(inputs, sol[0][s]) for s in solve_for}
ld_total = sp.lambdify(inputs, sol[0][P1] + sol[0][P2])
def make_chart(df: pd.DataFrame, dark: bool) -> alt.Chart:
source = df.melt("PT", var_name="species", value_name="y")
# Create a selection that chooses the nearest point & selects based on x-value
nearest = alt.selection_point(
nearest=True, on="pointerover", fields=["PT"], empty=False
)
# The basic line
line = (
alt.Chart(source)
.mark_line(interpolate="basis")
.encode(
x=alt.X("PT:Q", scale=alt.Scale(type="log"), title="Ratio PT/kD"),
y=alt.Y("y:Q", title="Fraction of total"),
color="species:N",
)
.properties(width="container")
)
# Draw points on the line, and highlight based on selection
points = (
line.mark_point()
.encode(opacity=alt.condition(nearest, alt.value(1), alt.value(0)))
.properties(width="container")
)
# Draw a rule at the location of the selection
rule_color = "white" if dark else "black"
rules = (
alt.Chart(source)
.transform_pivot("species", value="y", groupby=["PT"])
.mark_rule(color=rule_color)
.encode(
x="PT:Q",
opacity=alt.condition(nearest, alt.value(0.3), alt.value(0)),
tooltip=[
alt.Tooltip(c, type="quantitative", format=".2f") for c in df.columns
],
)
.add_params(nearest)
.properties(width="container")
)
# Put the five layers into a chart and bind the data
chart = (
alt.layer(line, points, rules)
.properties(height=300)
.configure(autosize="fit-x")
)
return chart
md = """
This app calculates monomer and dimer concentrations given a total amount of protomer PT and the
dissociation constant KD. More info on how and why can be found [HuggingFace](https://huggingface.co/spaces/Jhsmit/binding-kinetics) (right click, open new tab).
"""
@solara.component
def Page():
solara.Style(Path("style.css"))
dark_effective = solara.lab.use_dark_effective()
if dark_effective is True:
alt.themes.enable("dark")
elif dark_effective is False:
alt.themes.enable("default")
PT = solara.use_reactive(10.0)
kD = solara.use_reactive(1.0)
vmin = solara.use_reactive(-1)
vmax = solara.use_reactive(3)
ans = {k: ld(PT.value, kD.value) for k, ld in lambdas.items()}
solara.Title("Dimerization Kinetics")
with solara.Card("Calculate concentrations from kD"):
solara.Markdown(md)
with solara.GridFixed(columns=2):
with solara.Tooltip("Total protomer concentration"):
solara.InputFloat("PT", value=PT)
with solara.Tooltip("Dissociation constant"):
solara.InputFloat("kD", value=kD)
solara.Markdown(f"### Concentration monomer: {ans[P1]:.2f}")
solara.Markdown(f"### Concentration dimer: {ans[P2]:.2f}")
# create a vector of PT values ranging from 0.1 times kD to 1000 times kD
def update():
PT_values = np.logspace(vmin.value, vmax.value, endpoint=True, num=100)
ans = {
k: ld(PT_values, 1) / ld_total(PT_values, 1) for k, ld in lambdas.items()
}
# put the results in a dataframe, together with input PT values
df = pd.DataFrame(dict(PT=PT_values) | {k.name: v for k, v in ans.items()})
return make_chart(df, dark_effective)
chart = solara.use_memo(update, [vmin.value, vmax.value])
with solara.Card("Fraction monomer/dimer vs ratio over kD"):
with solara.Row():
with solara.Tooltip("X axis lower limit (log10)"):
solara.InputFloat("xmin", value=vmin)
with solara.Tooltip("X axis upper limit (log10)"):
solara.InputFloat("xmax", value=vmax)
solara.HTML(tag="div", style="height: 10px")
solara.FigureAltair(chart)
|