diff --git a/setup.py b/setup.py index 394f0df..c4be0b4 100644 --- a/setup.py +++ b/setup.py @@ -81,7 +81,7 @@ name="vivarium_models", packages=find_packages(exclude=["tests", "*.tests", "*.tests.*"]), package_data={ - '': ['templates/*']}, + '': ['templates/*', 'templates/medyan_Chandrasekaran_2019_no_tread_2mUNI_alphaA_0.1_MA_0.675/*']}, python_requires=">=3.8", setup_requires=setup_requirements, test_suite="vivarium_models/tests", diff --git a/vivarium_models/composites/moving_anchor.py b/vivarium_models/composites/moving_anchor.py new file mode 100644 index 0000000..998bc6e --- /dev/null +++ b/vivarium_models/composites/moving_anchor.py @@ -0,0 +1,163 @@ +from vivarium.core.composer import Composer +from vivarium.core.engine import Engine +from vivarium.processes.alternator import PeriodicEvent + +from vivarium_cytosim import CytosimProcess +from vivarium_models.data.fibers import single_fiber + +from vivarium.core.process import Step + +import numpy as np +import copy + +READDY_TIMESTEP = 0.0000001 +ALTERNATOR_PERIODS = [2.0, READDY_TIMESTEP] + + +class AnchorMover(Step): + defaults = { + "fiber_id": 0, + "point_index": 0, + "movement_vector": [0, 0, 0], + } + + def __init__(self, config=None): + super().__init__(config) + + def ports_schema(self): + return { + "fibers": { + "*": { + "type_name": { + "_default": "", + "_updater": "set", + "_emit": True, + }, + "points": { + "_default": [], + "_updater": "set", + "_emit": True, + }, + } + } + } + + def next_update(self, timestep, state): + points = state["fibers"][self.parameters["fiber_id"]]["points"] + anchor = points[self.parameters["point_index"]] + anchor_moved = anchor + np.array(self.parameters["movement_vector"]) + points[self.parameters["point_index"]] = anchor_moved + + return { + "fibers": { + self.parameters["fiber_id"]: { + "points": points + } + } + } + +class AnchorMoverCytosim(CytosimProcess): + new_defaults = { + "fiber_id": 0, + "point_index": 0, + "movement_vector": [0, 0, 0], + } + + def __init__(self, config=None): + parameters = copy.deepcopy(self.new_defaults) + parameters.update(config) + super().__init__(parameters) + + def next_update(self, timestep, state): + points = state["fibers"][self.parameters["fiber_id"]]["points"] + anchor = points[self.parameters["point_index"]] + anchor_moved = anchor + np.array(self.parameters["movement_vector"]) + points[self.parameters["point_index"]] = anchor_moved + update = super().next_update(timestep, state) + return update + +class BucklingSqueeze(Composer): + defaults = { + "periodic_event": { + "periods": [1.0] + }, + "cytosim_anchor_mover_squeeze": { + 'model_name': 'buckling_squeeze', + "movement_vector": [5, 0, 0], + "fiber_id": "1", + }, + # "cytosim_squeeze": { + # 'model_name': 'buckling_squeeze' + # }, + # "anchor_mover": { + # "movement_vector": [0, 5, 0], + # "fiber_id": "1", + # } + } + + def __init__(self, config=None): + super().__init__(config) + + def generate_processes(self, config): + periodic_event = PeriodicEvent(config["periodic_event"]) + # cytosim_squeeze = CytosimProcess(config['cytosim_squeeze']) + # anchor_mover = AnchorMover(config["anchor_mover"]) + cytosim_anchor_mover_squeeze = AnchorMoverCytosim(config["cytosim_anchor_mover_squeeze"]) + + return { + "periodic_event": periodic_event, + # 'cytosim_squeeze': cytosim_squeeze, + # "anchor_mover": anchor_mover, + "cytosim_anchor_mover_squeeze": cytosim_anchor_mover_squeeze + } + + def generate_topology(self, config): + return { + "periodic_event": { + "event_trigger": ("alternate_trigger",), + "period_index": ("period_index",), + }, + # "cytosim_squeeze": { + # "fibers": ("fibers",), + # "fibers_box_extent": ("fibers_box_extent",), + # }, + # "anchor_mover": { + # "fibers": ("fibers",), + # } + "cytosim_anchor_mover_squeeze": { + "fibers": ("fibers",), + "fibers_box_extent": ("fibers_box_extent",), + }, + } + + +def test_buckling_squeeze(): + initial_state = single_fiber() + initial_state['choices'] = 'N/A' + cytosim_config = { + 'actin_segmentation': 0.005, + "timestep": 5, + "template_directory": "vivarium_models/templates/"} + buckling_squeeze_config = { + # "cytosim_squeeze": cytosim_config + "cytosim_anchor_mover_squeeze": cytosim_config + } + buckling_squeeze = BucklingSqueeze(buckling_squeeze_config) + composite = buckling_squeeze.generate() + composite["initial_state"] = initial_state + engine = Engine( + processes=composite["processes"], + topology=composite["topology"], + initial_state=composite["initial_state"], + emitter="simularium", + emit_processes=True, + ) + engine.update(100) + + output = engine.emitter.get_data() + # import ipdb; ipdb.set_trace() + + + +if __name__ == "__main__": + test_buckling_squeeze() diff --git a/vivarium_models/data/fibers.py b/vivarium_models/data/fibers.py index 909d895..43a814f 100644 --- a/vivarium_models/data/fibers.py +++ b/vivarium_models/data/fibers.py @@ -1,4 +1,5 @@ import numpy as np +import copy initial_fibers = { "fibers_box_extent": np.array([4000.0, 2000.0, 2000.0]), @@ -226,3 +227,84 @@ def centered_initial_fibers(): fiber_points[point_index] - 0.5 * initial_fibers["fibers_box_extent"] ) return result + +def map_fibers(f, initial_fibers): + result = copy.deepcopy(initial_fibers) + for fiber_id in initial_fibers["fibers"]: + fiber_points = initial_fibers["fibers"][fiber_id]["points"] + for point_index in range(len(fiber_points)): + result["fibers"][fiber_id]["points"][point_index] = ( + f(fiber_points[point_index], initial_fibers["fibers_box_extent"]) + ) + return result + + +def single_fiber(): + fiber = { + "fibers_box_extent": np.array([4000.0, 2000.0, 2000.0]), + "fibers": { + '1': { + "type_name": "Actin-Polymer", + "points": [ + np.array([-0.250, 0.000, 0.000]), + np.array([-0.240, 0.000, 0.000]), + np.array([-0.230, 0.000, 0.000]), + np.array([-0.220, 0.000, 0.000]), + np.array([-0.210, 0.000, 0.000]), + np.array([-0.200, 0.000, 0.000]), + np.array([-0.190, 0.000, 0.000]), + np.array([-0.180, 0.000, 0.000]), + np.array([-0.170, 0.000, 0.000]), + np.array([-0.160, 0.000, 0.000]), + np.array([-0.150, 0.000, 0.000]), + np.array([-0.140, 0.000, 0.000]), + np.array([-0.130, 0.000, 0.000]), + np.array([-0.120, 0.000, 0.000]), + np.array([-0.110, 0.000, 0.000]), + np.array([-0.100, 0.000, 0.000]), + np.array([-0.090, 0.000, 0.000]), + np.array([-0.080, 0.000, 0.000]), + np.array([-0.070, 0.000, 0.000]), + np.array([-0.060, 0.000, 0.000]), + np.array([-0.050, 0.000, 0.000]), + np.array([-0.040, 0.000, 0.000]), + np.array([-0.030, 0.000, 0.000]), + np.array([-0.020, 0.000, 0.000]), + np.array([-0.010, 0.000, 0.000]), + np.array([0.000, 0.000, 0.000]), + np.array([0.010, 0.000, 0.000]), + np.array([0.020, 0.000, 0.000]), + np.array([0.030, 0.000, 0.000]), + np.array([0.040, 0.000, 0.000]), + np.array([0.050, 0.000, 0.000]), + np.array([0.060, 0.000, 0.000]), + np.array([0.070, 0.000, 0.000]), + np.array([0.080, 0.000, 0.000]), + np.array([0.090, 0.000, 0.000]), + np.array([0.100, 0.000, 0.000]), + np.array([0.110, 0.000, 0.000]), + np.array([0.120, 0.000, 0.000]), + np.array([0.130, 0.000, 0.000]), + np.array([0.140, 0.000, 0.000]), + np.array([0.150, 0.000, 0.000]), + np.array([0.160, 0.000, 0.000]), + np.array([0.170, 0.000, 0.000]), + np.array([0.180, 0.000, 0.000]), + np.array([0.190, 0.000, 0.000]), + np.array([0.200, 0.000, 0.000]), + np.array([0.210, 0.000, 0.000]), + np.array([0.220, 0.000, 0.000]), + np.array([0.230, 0.000, 0.000]), + np.array([0.240, 0.000, 0.000]), + np.array([0.250, 0.000, 0.000]), + ]}}} + + scaled = map_fibers( + lambda fiber_points, box_extent: fiber_points * 1000, + fiber) + + return scaled + +if __name__ == '__main__': + fiber = single_fiber() + import ipdb; ipdb.set_trace() diff --git a/vivarium_models/processes/simularium_emitter.py b/vivarium_models/processes/simularium_emitter.py index 6253088..88d6246 100644 --- a/vivarium_models/processes/simularium_emitter.py +++ b/vivarium_models/processes/simularium_emitter.py @@ -309,4 +309,4 @@ def get_data(self) -> dict: simularium_converter = SimulariumEmitter.get_simularium_converter( trajectory, box_dimensions, 0.1 ) - simularium_converter.write_JSON("out/actin_test") + simularium_converter.save("out/actin_test") diff --git a/vivarium_models/templates/buckling_squeeze.cym b/vivarium_models/templates/buckling_squeeze.cym new file mode 100644 index 0000000..2134234 --- /dev/null +++ b/vivarium_models/templates/buckling_squeeze.cym @@ -0,0 +1,98 @@ +% Fiber under compression to measure buckling force +% F. Nedelec, 23.05.2017, 21.02.2018 + + +set simul system +{ + time_step = {{internal_timestep}} + viscosity = {{viscosity}} + kT = {{kT}} +} + +set space cell +{ + shape = sphere +} + +new cell +{ + radius = 2 +} + +set fiber filament +{ + rigidity = 1 + segmentation = {{actin_segmentation}} + display = ( point=6,1; line=10,2; ) + {% if confine %} + confine = {{confine.side}}, {{confine.force}}, {{confine.space}} + {% endif %} +} + +set hand binder +{ + % 10 events per second, 0.05 um binding radius + + binding = 10, 0.05 + + % 0 events per second, infinite unbinding force + + unbinding = 0, inf + bind_also_end = 1 + + display = ( width=3; size=12; color=green ) +} + +set single linker +{ + hand = binder + activity = fixed + stiffness = 1000 +} + + +{% for filament in filaments %} +new filament +{ + mark = {{filament.id}} + shape = {{filament.points|join(', ')}} + placement = off + attach1 = linker, 0, minus_end + attach2 = linker, 0, plus_end +} +{% endfor %} + +% but figure out how to set the location of individual segmentation points on an actin filament (fiber) + +% new linker +% { +% position = -4.5 0 0 +% % attach = fiber1, 0 +% } + +% new linker +% { +% position = +4.5 0 0 +% % attach = fiber1, 10 +% } + +run {{simulation_time}} system +{ + % this could be 1 if you want to just get the last state + nb_frames = 1 +} + +% change some properties +% for example, see "event.cym" + +% continue running + +% retrieve the state: +% positions of everything + + +% you want to grab +% positions (fiber points) (single) etc + +% report single:force force.txt { verbose=0; } +% report fiber:tension tension.txt { verbose=0; plane = 1 0 0, 0; }