Skip to content
13 changes: 12 additions & 1 deletion simularium_readdy_models/actin/actin_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,7 @@ def _get_main_monomers_for_fiber(
pointed_actin_number,
particles={},
longitudinal_bonds=True,
barbed_binding_site=False,
):
"""
get the main actins for a fiber (i.e. no branches or arps).
Expand Down Expand Up @@ -549,8 +550,14 @@ def _get_main_monomers_for_fiber(
# remove "mid" from second actin
ActinGenerator._remove_mid_from_actin(particle_ids[1], particles)
actin_arp_ids = None
if barbed_binding_site and len(particle_ids) > 1:
particles = ActinGenerator._set_particle_type_name(
"actin#barbed_ATP_" ,
particle_ids[len(particle_ids) - 2],
particles,
)
particles = ActinGenerator._set_particle_type_name(
"actin#barbed_ATP_",
"actin#barbed_ATP_" if not barbed_binding_site else "binding_site#" ,
particle_ids[len(particle_ids) - 1],
particles,
)
Expand All @@ -565,6 +572,7 @@ def _get_monomers_for_fiber(
pointed_actin_number,
particles={},
longitudinal_bonds=True,
barbed_binding_site=False,
):
"""
get the main actins for a fiber as well as any bound arps and daughter fibers.
Expand All @@ -581,6 +589,7 @@ def _get_monomers_for_fiber(
pointed_actin_number,
particles,
longitudinal_bonds,
barbed_binding_site,
)
daughter_particle_ids = []
all_actin_arp_ids = []
Expand Down Expand Up @@ -800,6 +809,7 @@ def get_monomers(
use_uuids=True,
start_normal=None,
longitudinal_bonds=True,
barbed_binding_site=False,
):
"""
get all the monomer data for the (branched) fibers in fibers_data.
Expand Down Expand Up @@ -836,6 +846,7 @@ def get_monomers(
np.zeros(3),
1,
longitudinal_bonds=longitudinal_bonds,
barbed_binding_site=barbed_binding_site,
)
result["topologies"][ActinGenerator._get_next_monomer_id()] = {
"type_name": "Actin-Polymer",
Expand Down
107 changes: 91 additions & 16 deletions simularium_readdy_models/actin/actin_simulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,13 @@
import numpy as np
import readdy

from ..common import ReaddyUtil
from ..common import (
ReaddyUtil,
add_membrane_particle_types,
add_membrane_constraints,
init_membrane,
all_membrane_particle_types
)
from .actin_structure import ActinStructure
from .actin_util import ActinUtil

Expand Down Expand Up @@ -110,7 +116,14 @@ def add_particle_types(self):
self.actin_util.add_actin_types(self.system, actin_diffCoeff)
self.actin_util.add_arp23_types(self.system, arp23_diffCoeff)
self.actin_util.add_cap_types(self.system, cap_diffCoeff)
self.system.add_species("obstacle", 0.0)
self.system.topologies.add_type("Obstacle")
self.system.add_topology_species("obstacle", self._parameter("obstacle_diff_coeff"))
if self._parameter("add_membrane"):
add_membrane_particle_types(
self.system, self._parameter("membrane_particle_radius"), temperature, viscosity
)
if self._parameter("barbed_binding_site"):
self.actin_util.add_binding_site_types(self.system, actin_diffCoeff)

def add_constraints(self):
"""
Expand All @@ -120,6 +133,7 @@ def add_constraints(self):
util = ReaddyUtil()
longitudinal_bonds = bool(self._parameter("longitudinal_bonds"))
only_linear_actin = bool(self._parameter("only_linear_actin_constraints"))
actin_constraints = bool(self._parameter("actin_constraints"))
# force constants
actin_angle_force_constant = float(self._parameter("angles_force_constant"))
actin_dihedral_force_constant = float(
Expand All @@ -132,16 +146,17 @@ def add_constraints(self):
longitudinal_bonds,
float(self._parameter("bonds_force_multiplier")),
)
self.actin_util.add_filament_twist_angles(
actin_angle_force_constant, self.system, util, longitudinal_bonds
)
self.actin_util.add_filament_twist_dihedrals(
actin_dihedral_force_constant,
self.system,
util,
longitudinal_bonds,
only_linear_actin,
)
if actin_constraints:
self.actin_util.add_filament_twist_angles(
actin_angle_force_constant, self.system, util, longitudinal_bonds
)
self.actin_util.add_filament_twist_dihedrals(
actin_dihedral_force_constant,
self.system,
util,
longitudinal_bonds,
only_linear_actin,
)
if not only_linear_actin:
# branch junction
self.actin_util.add_branch_bonds(self.system, util)
Expand Down Expand Up @@ -170,8 +185,41 @@ def add_constraints(self):
actin_actin_repulsion_potentials=True,
longitudinal_bonds=longitudinal_bonds,
)
self.actin_util.add_repulsions_with_actin(
["obstacle"],
self._parameter("obstacle_radius"),
ActinUtil.DEFAULT_FORCE_CONSTANT,
self.system,
util
)
# box potentials
self.actin_util.add_monomer_box_potentials(self.system)
self.actin_util.add_obstacle_box_potential(self.system)
self.actin_util.add_extra_box(self.system)
# membrane
if self._parameter("add_membrane"):
add_membrane_constraints(
self.system,
np.array([
float(self._parameter("membrane_center_x")),
float(self._parameter("membrane_center_y")),
float(self._parameter("membrane_center_z")),
]),
np.array([
float(self._parameter("membrane_size_x")),
float(self._parameter("membrane_size_y")),
float(self._parameter("membrane_size_z")),
]),
self._parameter("membrane_particle_radius"),
self._parameter("box_size")
)
self.actin_util.add_repulsions_with_actin(
all_membrane_particle_types(),
self._parameter("membrane_particle_radius"),
ActinUtil.DEFAULT_FORCE_CONSTANT,
self.system,
util
)

def add_reactions(self):
"""
Expand All @@ -198,6 +246,8 @@ def add_reactions(self):
self.actin_util.add_cap_unbind_reaction(self.system)
if self.do_pointed_end_translation():
self.actin_util.add_translate_reaction(self.system)
if self._parameter("position_obstacle_stride") > 0:
self.actin_util.add_position_obstacle_reaction(self.system)

def do_pointed_end_translation(self):
result = self._parameter("displace_pointed_end_tangent") or self._parameter(
Expand Down Expand Up @@ -330,19 +380,44 @@ def add_obstacles(self):
"""
Add obstacle particles.
"""
if not self._parameter("add_obstacles"):
return
n = 0
while f"obstacle{n}_position_x" in self.parameters:
self.simulation.add_particle(
type="obstacle",
position=[
self.simulation.add_topology(
"Obstacle",
["obstacle"],
np.array([[
float(self._parameter(f"obstacle{n}_position_x")),
float(self._parameter(f"obstacle{n}_position_y")),
float(self._parameter(f"obstacle{n}_position_z")),
],
]])
)
n += 1
if n > 0:
print(f"Added {n} obstacle(s).")

def add_membrane(self):
"""
Add membrane types and particles.
"""
if not self._parameter("add_membrane"):
return
init_membrane(
self.simulation,
np.array([
float(self._parameter("membrane_center_x")),
float(self._parameter("membrane_center_y")),
float(self._parameter("membrane_center_z")),
]),
np.array([
float(self._parameter("membrane_size_x")),
float(self._parameter("membrane_size_y")),
float(self._parameter("membrane_size_z")),
]),
self._parameter("membrane_particle_radius"),
self._parameter("box_size")
)

def add_crystal_structure_monomers(self):
"""
Expand Down
Loading
Loading