using MEDYAN
using MEDYANVis
using CairoMakie
using Random
using SmallZarrGroups
using StaticArrays
using LinearAlgebra
Random.seed!(1234);3. Actin Treadmilling
3. Actin Treadmilling
Using reactions and rates from
This example doesn’t have any of the actin binding proteins, or filament severing or annealing.
Setup
Open a julia REPL or jupyter notebook using the medyan-tutorial environment you created in tutorial 1.
Load MEDYAN with MeshCat for visualization
Defining the System
The first step is constructing a MEDYAN.SysDef object, then mutating it to add species, filament types, reactions, and callbacks.
s = MEDYAN.SysDef()MEDYAN.SysDef with:
Add diffusing species with their diffusion coefficients. All units are based on nm, s, pN.
DGActin = 5E6 # nm²/s
def_diffusing_species!(s, :GA; coeff=DGActin) # G-Actin with no bound nucleotide
def_diffusing_species!(s, :GAD; coeff=DGActin) # G-Actin in the ADP form
def_diffusing_species!(s, :GADPi; coeff=DGActin) # G-Actin in the ADP Pi form
def_diffusing_species!(s, :GAT; coeff=DGActin) # G-Actin in the ATP formMEDYAN.SysDef with:
Diffusing species:
:GA: 5.0e6 nm²·s⁻¹ (5.0 µm²·s⁻¹)
:GAD: 5.0e6 nm²·s⁻¹ (5.0 µm²·s⁻¹)
:GADPi: 5.0e6 nm²·s⁻¹ (5.0 µm²·s⁻¹)
:GAT: 5.0e6 nm²·s⁻¹ (5.0 µm²·s⁻¹)
Add the actin filament type with its monomer states and mechanical parameters.
def_fila_type!(s;
name=:actin,
mono_states=[
# Monomer states
:FAD, # F-Actin in the ADP form
:FADPi, # F-Actin in the ADP Pi form
:FAT, # F-Actin in the ATP form
:BarbedD, # Barbed end in the ADP form
:BarbedDPi, # Barbed end in the ADP Pi form
:BarbedT, # Barbed end in the ATP form
:PointedD, # Pointed end in the ADP form
:PointedDPi, # Pointed end in the ADP Pi form
:PointedT, # Pointed end in the ATP form
],
param=MEDYAN.ACTIN_FIL_PARAMS
)MEDYAN.SysDef with:
Diffusing species:
:GA: 5.0e6 nm²·s⁻¹ (5.0 µm²·s⁻¹)
:GAD: 5.0e6 nm²·s⁻¹ (5.0 µm²·s⁻¹)
:GADPi: 5.0e6 nm²·s⁻¹ (5.0 µm²·s⁻¹)
:GAT: 5.0e6 nm²·s⁻¹ (5.0 µm²·s⁻¹)
Filaments:
:actin:
monomer states: [:FAD, :FADPi, :FAT, :BarbedD, :BarbedDPi, :BarbedT, :PointedD, :PointedDPi, :PointedT]
Add reactions between diffusing species. These represent G-Actin interacting with ATP ADP and Pi.
# Assume ATP, Pi, and ADP concentrations are fixed
ATP = 10000.0 * MEDYAN.μM⁻¹_per_nm³
Pi = 2000.0 * MEDYAN.μM⁻¹_per_nm³
ADP = 2000.0 * MEDYAN.μM⁻¹_per_nm³
KfGATPoint = 1.3/MEDYAN.μM⁻¹_per_nm³
KrGATPoint = 0.8
KfGADPoint = 0.16/MEDYAN.μM⁻¹_per_nm³
KrGADPoint = 0.3
KfGATBarb = 10.0/MEDYAN.μM⁻¹_per_nm³
KrGATBarb = 1.0
KfGADBarb = 2.5/MEDYAN.μM⁻¹_per_nm³
KrGADBarb = 4.25
KfPiRelease = 0.0026
KrPiRelease = 5.20E-6/MEDYAN.μM⁻¹_per_nm³
# 100
def_reaction!(s, "diffusing.GADPi --> diffusing.GAD";
base_rate=0.0312,
)
def_reaction!(s, "diffusing.GAD --> diffusing.GADPi";
base_rate=KrPiRelease*Pi,
)
# 104
def_reaction!(s, "diffusing.GA --> diffusing.GAT";
base_rate=1.7/MEDYAN.μM⁻¹_per_nm³*ATP,
)
def_reaction!(s, "diffusing.GAT --> diffusing.GA";
base_rate=0.011,
)
# 109
def_reaction!(s, "diffusing.GA --> diffusing.GAD";
base_rate=0.9/MEDYAN.μM⁻¹_per_nm³*ADP,
)
def_reaction!(s, "diffusing.GAD --> diffusing.GA";
base_rate=0.071,
)MEDYAN.SysDef with:
Diffusing species:
:GA: 5.0e6 nm²·s⁻¹ (5.0 µm²·s⁻¹)
:GAD: 5.0e6 nm²·s⁻¹ (5.0 µm²·s⁻¹)
:GADPi: 5.0e6 nm²·s⁻¹ (5.0 µm²·s⁻¹)
:GAT: 5.0e6 nm²·s⁻¹ (5.0 µm²·s⁻¹)
Filaments:
:actin:
monomer states: [:FAD, :FADPi, :FAT, :BarbedD, :BarbedDPi, :BarbedT, :PointedD, :PointedDPi, :PointedT]
Chem voxel reactions:
:reaction1: diffusing.GADPi --> diffusing.GAD @ 0.0312 s⁻¹
:reaction2: diffusing.GAD --> diffusing.GADPi @ 0.0104 s⁻¹
:reaction3: diffusing.GA --> diffusing.GAT @ 17000.0 s⁻¹
:reaction4: diffusing.GAT --> diffusing.GA @ 0.011 s⁻¹
:reaction5: diffusing.GA --> diffusing.GAD @ 1799.9999999999998 s⁻¹
:reaction6: diffusing.GAD --> diffusing.GA @ 0.071 s⁻¹
Next add filament reactions.
The barbed end is the plus end and the pointed end is the minus end.
monomerspacing=2.7 # nm
nucleotide_states = ("T", "DPi", "D")
# Barbed end polymerization and depolymerization
barbed_rates = [
("T", KfGATBarb, KrGATBarb),
("DPi", KfGATBarb, KrGATBarb),
("D", KfGADBarb, KrGADBarb),
]
for (new_nuc, forward_rate, reverse_rate) in barbed_rates
for base_nuc in nucleotide_states
def_fila_tip_reaction!(s;
fila_type = :actin,
name = Symbol("f", "GA", new_nuc, "_to_Barbed", base_nuc),
is_minus_end = false,
match = [Symbol("Barbed", base_nuc)],
new = [Symbol("FA", base_nuc), Symbol("Barbed", new_nuc)],
spacing = monomerspacing,
net_stoich = [Symbol("GA", new_nuc) => -1],
base_rate = forward_rate,
invvolumepower = 1,
reactants_extra = "diffusing.GA"*new_nuc,
)
def_fila_tip_reaction!(s;
fila_type = :actin,
name = Symbol("r", "GA", new_nuc, "_to_Barbed", base_nuc),
is_minus_end = false,
match = [Symbol("FA", base_nuc), Symbol("Barbed", new_nuc)],
new = [Symbol("Barbed", base_nuc)],
spacing = 0.0,
net_stoich = [Symbol("GA", new_nuc) => 1],
base_rate = reverse_rate,
)
end
end
# Pointed end polymerization and depolymerization
pointed_rates = [
("T", KfGATPoint, KrGATPoint),
("DPi", KfGATPoint, KrGATPoint),
("D", KfGADPoint, KrGADPoint),
]
for (new_nuc, forward_rate, reverse_rate) in pointed_rates
for base_nuc in nucleotide_states
def_fila_tip_reaction!(s;
fila_type = :actin,
name = Symbol("f", "GA", new_nuc, "_to_Pointed", base_nuc),
is_minus_end = true,
match = [Symbol("Pointed", base_nuc)],
new = [Symbol("Pointed", new_nuc), Symbol("FA", base_nuc)],
spacing = monomerspacing,
net_stoich = [Symbol("GA", new_nuc) => -1],
base_rate = forward_rate,
invvolumepower = 1,
reactants_extra = "diffusing.GA"*new_nuc,
)
def_fila_tip_reaction!(s;
fila_type = :actin,
name = Symbol("r", "GA", new_nuc, "_to_Pointed", base_nuc),
is_minus_end = true,
match = [Symbol("Pointed", new_nuc), Symbol("FA", base_nuc)],
new = [Symbol("Pointed", base_nuc)],
spacing = 0.0,
net_stoich = [Symbol("GA", new_nuc) => 1],
base_rate = reverse_rate,
)
end
end
# Filament ATP hydrolysis and Pi Dissociation
for monomer_state in ("FA", "Barbed", "Pointed")
def_fila_reaction!(s;
fila_type = :actin,
name = Symbol(monomer_state, "T_to_", monomer_state, "DPi"),
match = [Symbol(monomer_state, "T")],
new = [Symbol(monomer_state, "DPi")],
base_rate = 0.3,
)
def_fila_reaction!(s;
fila_type = :actin,
name = Symbol(monomer_state, "DPi_to_", monomer_state, "D"),
match = [Symbol(monomer_state, "DPi")],
new = [Symbol(monomer_state, "D")],
base_rate = KfPiRelease,
)
def_fila_reaction!(s;
fila_type = :actin,
name = Symbol(monomer_state, "D_to_", monomer_state, "DPi"),
match = [Symbol(monomer_state, "D")],
new = [Symbol(monomer_state, "DPi")],
base_rate = KrPiRelease*Pi,
)
end
sMEDYAN.SysDef with:
Diffusing species:
:GA: 5.0e6 nm²·s⁻¹ (5.0 µm²·s⁻¹)
:GAD: 5.0e6 nm²·s⁻¹ (5.0 µm²·s⁻¹)
:GADPi: 5.0e6 nm²·s⁻¹ (5.0 µm²·s⁻¹)
:GAT: 5.0e6 nm²·s⁻¹ (5.0 µm²·s⁻¹)
Filaments:
:actin:
monomer states: [:FAD, :FADPi, :FAT, :BarbedD, :BarbedDPi, :BarbedT, :PointedD, :PointedDPi, :PointedT]
Filament reactions:
:actin:
FAT_to_FADPi: [(:FAT)] --> [:FADPi] @ 0.3 s⁻¹
FADPi_to_FAD: [(:FADPi)] --> [:FAD] @ 0.0026 s⁻¹
FAD_to_FADPi: [(:FAD)] --> [:FADPi] @ 0.0104 s⁻¹
BarbedT_to_BarbedDPi: [(:BarbedT)] --> [:BarbedDPi] @ 0.3 s⁻¹
BarbedDPi_to_BarbedD: [(:BarbedDPi)] --> [:BarbedD] @ 0.0026 s⁻¹
BarbedD_to_BarbedDPi: [(:BarbedD)] --> [:BarbedDPi] @ 0.0104 s⁻¹
PointedT_to_PointedDPi: [(:PointedT)] --> [:PointedDPi] @ 0.3 s⁻¹
PointedDPi_to_PointedD: [(:PointedDPi)] --> [:PointedD] @ 0.0026 s⁻¹
PointedD_to_PointedDPi: [(:PointedD)] --> [:PointedDPi] @ 0.0104 s⁻¹
Filament end reactions:
:actin:
fGAT_to_BarbedT: [:BarbedT, (+)] + diffusing.GAT --> [:FAT, :BarbedT, +] spacing=2.7nm @ 1.6605390671738468e7 nm³·s⁻¹ (10.0 µM⁻¹·s⁻¹)
rGAT_to_BarbedT: [:FAT, :BarbedT, (+)] --> [:BarbedT, +] + diffusing.GAT @ 1.0 s⁻¹
fGAT_to_BarbedDPi: [:BarbedDPi, (+)] + diffusing.GAT --> [:FADPi, :BarbedT, +] spacing=2.7nm @ 1.6605390671738468e7 nm³·s⁻¹ (10.0 µM⁻¹·s⁻¹)
rGAT_to_BarbedDPi: [:FADPi, :BarbedT, (+)] --> [:BarbedDPi, +] + diffusing.GAT @ 1.0 s⁻¹
fGAT_to_BarbedD: [:BarbedD, (+)] + diffusing.GAT --> [:FAD, :BarbedT, +] spacing=2.7nm @ 1.6605390671738468e7 nm³·s⁻¹ (10.0 µM⁻¹·s⁻¹)
rGAT_to_BarbedD: [:FAD, :BarbedT, (+)] --> [:BarbedD, +] + diffusing.GAT @ 1.0 s⁻¹
fGADPi_to_BarbedT: [:BarbedT, (+)] + diffusing.GADPi --> [:FAT, :BarbedDPi, +] spacing=2.7nm @ 1.6605390671738468e7 nm³·s⁻¹ (10.0 µM⁻¹·s⁻¹)
rGADPi_to_BarbedT: [:FAT, :BarbedDPi, (+)] --> [:BarbedT, +] + diffusing.GADPi @ 1.0 s⁻¹
fGADPi_to_BarbedDPi: [:BarbedDPi, (+)] + diffusing.GADPi --> [:FADPi, :BarbedDPi, +] spacing=2.7nm @ 1.6605390671738468e7 nm³·s⁻¹ (10.0 µM⁻¹·s⁻¹)
rGADPi_to_BarbedDPi: [:FADPi, :BarbedDPi, (+)] --> [:BarbedDPi, +] + diffusing.GADPi @ 1.0 s⁻¹
fGADPi_to_BarbedD: [:BarbedD, (+)] + diffusing.GADPi --> [:FAD, :BarbedDPi, +] spacing=2.7nm @ 1.6605390671738468e7 nm³·s⁻¹ (10.0 µM⁻¹·s⁻¹)
rGADPi_to_BarbedD: [:FAD, :BarbedDPi, (+)] --> [:BarbedD, +] + diffusing.GADPi @ 1.0 s⁻¹
fGAD_to_BarbedT: [:BarbedT, (+)] + diffusing.GAD --> [:FAT, :BarbedD, +] spacing=2.7nm @ 4.151347667934617e6 nm³·s⁻¹ (2.5 µM⁻¹·s⁻¹)
rGAD_to_BarbedT: [:FAT, :BarbedD, (+)] --> [:BarbedT, +] + diffusing.GAD @ 4.25 s⁻¹
fGAD_to_BarbedDPi: [:BarbedDPi, (+)] + diffusing.GAD --> [:FADPi, :BarbedD, +] spacing=2.7nm @ 4.151347667934617e6 nm³·s⁻¹ (2.5 µM⁻¹·s⁻¹)
rGAD_to_BarbedDPi: [:FADPi, :BarbedD, (+)] --> [:BarbedDPi, +] + diffusing.GAD @ 4.25 s⁻¹
fGAD_to_BarbedD: [:BarbedD, (+)] + diffusing.GAD --> [:FAD, :BarbedD, +] spacing=2.7nm @ 4.151347667934617e6 nm³·s⁻¹ (2.5 µM⁻¹·s⁻¹)
rGAD_to_BarbedD: [:FAD, :BarbedD, (+)] --> [:BarbedD, +] + diffusing.GAD @ 4.25 s⁻¹
fGAT_to_PointedT: diffusing.GAT + [(-), :PointedT] --> [-, :PointedT, :FAT] spacing=2.7nm @ 2.158700787326001e6 nm³·s⁻¹ (1.3 µM⁻¹·s⁻¹)
rGAT_to_PointedT: [(-), :PointedT, :FAT] --> diffusing.GAT + [-, :PointedT] @ 0.8 s⁻¹
fGAT_to_PointedDPi: diffusing.GAT + [(-), :PointedDPi] --> [-, :PointedT, :FADPi] spacing=2.7nm @ 2.158700787326001e6 nm³·s⁻¹ (1.3 µM⁻¹·s⁻¹)
rGAT_to_PointedDPi: [(-), :PointedT, :FADPi] --> diffusing.GAT + [-, :PointedDPi] @ 0.8 s⁻¹
fGAT_to_PointedD: diffusing.GAT + [(-), :PointedD] --> [-, :PointedT, :FAD] spacing=2.7nm @ 2.158700787326001e6 nm³·s⁻¹ (1.3 µM⁻¹·s⁻¹)
rGAT_to_PointedD: [(-), :PointedT, :FAD] --> diffusing.GAT + [-, :PointedD] @ 0.8 s⁻¹
fGADPi_to_PointedT: diffusing.GADPi + [(-), :PointedT] --> [-, :PointedDPi, :FAT] spacing=2.7nm @ 2.158700787326001e6 nm³·s⁻¹ (1.3 µM⁻¹·s⁻¹)
rGADPi_to_PointedT: [(-), :PointedDPi, :FAT] --> diffusing.GADPi + [-, :PointedT] @ 0.8 s⁻¹
fGADPi_to_PointedDPi: diffusing.GADPi + [(-), :PointedDPi] --> [-, :PointedDPi, :FADPi] spacing=2.7nm @ 2.158700787326001e6 nm³·s⁻¹ (1.3 µM⁻¹·s⁻¹)
rGADPi_to_PointedDPi: [(-), :PointedDPi, :FADPi] --> diffusing.GADPi + [-, :PointedDPi] @ 0.8 s⁻¹
fGADPi_to_PointedD: diffusing.GADPi + [(-), :PointedD] --> [-, :PointedDPi, :FAD] spacing=2.7nm @ 2.158700787326001e6 nm³·s⁻¹ (1.3 µM⁻¹·s⁻¹)
rGADPi_to_PointedD: [(-), :PointedDPi, :FAD] --> diffusing.GADPi + [-, :PointedD] @ 0.8 s⁻¹
fGAD_to_PointedT: diffusing.GAD + [(-), :PointedT] --> [-, :PointedD, :FAT] spacing=2.7nm @ 265686.2507478155 nm³·s⁻¹ (0.16 µM⁻¹·s⁻¹)
rGAD_to_PointedT: [(-), :PointedD, :FAT] --> diffusing.GAD + [-, :PointedT] @ 0.3 s⁻¹
fGAD_to_PointedDPi: diffusing.GAD + [(-), :PointedDPi] --> [-, :PointedD, :FADPi] spacing=2.7nm @ 265686.2507478155 nm³·s⁻¹ (0.16 µM⁻¹·s⁻¹)
rGAD_to_PointedDPi: [(-), :PointedD, :FADPi] --> diffusing.GAD + [-, :PointedDPi] @ 0.3 s⁻¹
fGAD_to_PointedD: diffusing.GAD + [(-), :PointedD] --> [-, :PointedD, :FAD] spacing=2.7nm @ 265686.2507478155 nm³·s⁻¹ (0.16 µM⁻¹·s⁻¹)
rGAD_to_PointedD: [(-), :PointedD, :FAD] --> diffusing.GAD + [-, :PointedD] @ 0.3 s⁻¹
Chem voxel reactions:
:reaction1: diffusing.GADPi --> diffusing.GAD @ 0.0312 s⁻¹
:reaction2: diffusing.GAD --> diffusing.GADPi @ 0.0104 s⁻¹
:reaction3: diffusing.GA --> diffusing.GAT @ 17000.0 s⁻¹
:reaction4: diffusing.GAT --> diffusing.GA @ 0.011 s⁻¹
:reaction5: diffusing.GA --> diffusing.GAD @ 1799.9999999999998 s⁻¹
:reaction6: diffusing.GAD --> diffusing.GA @ 0.071 s⁻¹
Creating a grid
Create a 1 by 1 by 3 grid of 500 nm side length voxels.
L = 3
grid = CubicGrid((1,1,L),500.0)CubicGrid([1, 1, 3], 500.0)
Creating a Context
The Context is the object the handles the state of a running simulation.
Create a Context using s and grid
c = MEDYAN.Context(s, grid)MEDYAN.Context at time 0.0s in MEDYAN.CubicGrid([1, 1, 3], 500.0)
Add Mechanical Boundary
set_mechboundary!(c, MEDYAN.boundary_box(grid; stiffness=100.0))MEDYAN.Boundary(SVector{4, Float64}[[-10.0, 0.0, 0.0, 2500.0], [10.0, 0.0, 0.0, 2500.0], [0.0, -10.0, 0.0, 2500.0], [0.0, 10.0, 0.0, 2500.0], [0.0, 0.0, -10.0, 7500.0], [0.0, 0.0, 10.0, 7500.0]], UInt32[0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001, 0x00000001], UInt32[0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000], SVector{8, Float64}[], UInt32[], UInt32[])
Add agents to the context
The context starts empty.
Distribute 700 of GAT randomly to the chem voxels by mutating the context.
adddiffusingcount_rand!(c, s.diffusing.GAT, 700)Add a single short filament by mutating the context.
mono_states = [s.state.actin.PointedD, s.state.actin.FADPi, s.state.actin.FAT, s.state.actin.BarbedT]
node_positions = [
SA[0.0,0.0,0.0],
SA[0.0,0.0,monomerspacing*length(mono_states)]
]
make_fila!(c; type=:actin, mono_states, node_positions, node_mids=[1,])MEDYAN.Tag{FilaTipIdx}(0x00000002, 0x00000001)
Run chemistry
Run chemistry for 1.0s and visualize the results.
vis = Visualizer()
setvisible!(vis["/Grid"], false)
setvisible!(vis["/Axes"], false)
setvisible!(vis["/Background"], false)If you open the visualizer in a browser and run the following you should get an animated version of below.
for i in 1:100
run_chemistry!(c, 0.01)
minimize_energy!(c)
draw_context!(vis, c, s)
end