Guidance By Followers

Open in Morpheus History

Persistent Identifier

Use this permanent link to cite or share this Morpheus model:


Reference

This model is used in the publication by Boutillon et al., under review.

Model

Get this model via:

XML Preview

<?xml version='1.0' encoding='UTF-8'?>
<MorpheusModel version="4">
    <Description>
        <Details>Simulation of zebrafish polster cell migration. Polster cells (green) are given a Run and Tumble behaviour, to which a guidance by follower is added: Each cell perceives the neighbours migrating towards it and aligns its own movement with that of the neighbour migrating towards it.

Multiple neighbours are taken into account by aligning the polster cells according to the contact-weighted mean of the neighbours' directions.</Details> <Title>Guidance by followers</Title> </Description> <Space> <Lattice class="hexagonal"> <Neighborhood> <Order>1</Order> </Neighborhood> <Size value="500, 1500, 0" symbol="size"/> <BoundaryConditions> <Condition boundary="x" type="periodic"/> <Condition boundary="y" type="periodic"/> </BoundaryConditions> </Lattice> <SpaceSymbol symbol="space"/> <MembraneLattice> <Resolution value="50" symbol="membrane_size"/> <SpaceSymbol symbol="membrane_pos"/> </MembraneLattice> </Space> <Time> <StartTime value="0"/> <StopTime value="100"/> <TimeSymbol symbol="time"/> </Time> <Global> <Constant name="Defines the speed of polster cells (Strength of the Directed Motion plugin)." value="0.5" symbol="RandT_or_Mech_motion_strength_global"/> <Constant name="Defines the mean duration of run phases." value="0.76" tags="RunandTumble" symbol="run_duration_adjustment"/> <Constant name="Defines the speed of axial cells (strength of the Directed Motion plugin)" value="0.5" symbol="directed_motion_strength_global"/> <Constant name="Angle between cell movement and direction to the neighbour, below max_angle, the cell is considered as moving towards the neighbouring cell and will influence its direction." value="pi/6" tags="guidance_by_followers" symbol="max_angle"/> <Constant name="Minimal velocity for a cell to influence its neighbours." value="0.1" tags="guidance_by_followers" symbol="min_push_velocity"/> <VariableVector value="0.0, 0.0, 0.0" symbol="velocity"/> <Variable value="0.0" symbol="MSD"/> <Constant name="Boolean: 0 no laser ablation, 1 laser ablation (see Cell Death in CellTypes>cell)" value="0" tags="laser_ablation" symbol="ablation"/> </Global> <CellTypes> <CellType name="cell" class="biological"> <SurfaceConstraint target="1" strength="1" mode="aspherity"/> <VolumeConstraint target="target_volume" strength="1"/> <Property value="326.0" symbol="target_volume"/> <DirectedMotion strength="directed_motion_strength" name="Directed movement, used for axial cells, set to strength=0 for polster cells." direction="directed_motion_dir"/> <PropertyVector name="Direction of the directed motion (axial cells)." value="0.0, 1.0, 0.0" symbol="directed_motion_dir"/> <Property name="Strength of the directed motion" value="0.0" symbol="directed_motion_strength"/> <DirectedMotion strength="RandT_or_Mech_motion_strength" name="RandT or mechanically induced movement." direction="dir" tags="guidance_by_followers"/> <Property name="Strength or Run and Tumble or mechanically induced motion." value="0" tags="guidance_by_followers" symbol="RandT_or_Mech_motion_strength"/> <PropertyVector value="0.0, 0.0, 0.0" symbol="dir"/> <VectorEquation symbol-ref="dir"> <Expression>if(mech_induced_dir.abs > 0, mech_induced_dir, RaT_dir)</Expression> </VectorEquation> <Mapper time-step="1.0"> <Input value="displacement.abs^2"/> <Output symbol-ref="MSD" mapping="average"/> </Mapper> <PropertyVector value="0.0, 0.0, 0.0" symbol="displacement"/> <PropertyVector value="0.0, 0.0, 0.0" symbol="velocity"/> <MotilityReporter name="Used for computing mechanics, needs time-step 1" time-step="1"> <Displacement symbol-ref="displacement"/> <Velocity symbol-ref="velocity"/> </MotilityReporter> <Property value="0.0" tags="py" symbol="py_angle"/> <Property value="0.0" tags="py" symbol="py_induced_dir_x"/> <Property value="0.0" tags="py" symbol="py_induced_dir_y"/> <PyMapper name="Code for multi-neighbour collisions" time-step="1" tags="py"> <Input symbol-ref="cell_center_x"/> <Input symbol-ref="cell_center_y"/> <Input symbol-ref="neighbor_center_x"/> <Input symbol-ref="neighbor_center_y"/> <Input symbol-ref="neighbor_velocity_x"/> <Input symbol-ref="neighbor_velocity_y"/> <Input symbol-ref="max_angle"/> <Input symbol-ref="min_push_velocity"/> <Script>import numpy as np

merge all inputs into one big data frame df

with two multiindex-columns "MemX"=membrane-position and "Cell"=cell.id

and many rows for all membrane-positions and one cell after the other

df = pandas.concat([cell_center_x, cell_center_y, neighbor_center_x, neighbor_center_y, neighbor_velocity_x, neighbor_velocity_y], axis=1, keys=[‘cell_center_x’, ‘cell_center_y’, ‘neighbor_center_x’, ‘neighbor_center_y’, ‘neighbor_velocity_x’, ‘neighbor_velocity_y’])

relative_position_to_neighbor = if(neighbor_center.abs>0, cell.center - neighbor_center, 0)

df[‘neighbor_center_abs’] = (df[‘neighbor_center_x’]**2+df[‘neighbor_center_y’]**2)**0.5

df[‘relative_position_to_neighbor_x’] = df[‘cell_center_x’]-df[‘neighbor_center_x’] df[‘relative_position_to_neighbor_y’] = df[‘cell_center_y’]-df[‘neighbor_center_y’]

df.loc[df[‘neighbor_center_abs’] == 0, ‘relative_position_to_neighbor_x’] = np.NaN df.loc[df[‘neighbor_center_abs’] == 0, ‘relative_position_to_neighbor_y’] = np.NaN

angle = if(neighbor_center.abs>0, neighbor_velocity.phi - relative_position_to_neighbor.phi, pi)

df[‘angle’] = np.arctan2(df[‘neighbor_velocity_y’],df[‘neighbor_velocity_x’])-np.arctan2(df[‘relative_position_to_neighbor_y’],df[‘relative_position_to_neighbor_x’]) df.loc[df[‘neighbor_center_abs’] == 0, ‘angle’] = np.pi df[‘angle_abs’] = abs((df[‘angle’] + np.pi) % (2 * np.pi) - np.pi)

induced_dir = if(cos(angle)>cos(max_angle) and neighbor_velocity.abs>min_push_velocity, neighbor_velocity, 0)

df[‘induced_dir_x’] = df[‘neighbor_velocity_x’] df[‘induced_dir_y’] = df[‘neighbor_velocity_y’] df[‘induced_dir_abs’] = (df[‘neighbor_velocity_x’]**2+df[‘neighbor_velocity_y’]**2)**0.5 df.loc[(np.cos(df[‘angle’])&lt;np.cos(max_angle)) | (df[‘induced_dir_abs’]&lt;min_push_velocity), ‘induced_dir_x’] = np.NaN df.loc[(np.cos(df[‘angle’])&lt;np.cos(max_angle)) | (df[‘induced_dir_abs’]&lt;min_push_velocity), ‘induced_dir_y’] = np.NaN

to monitor, also return per-cell aggregated intermediate quantities

py_angle = df.groupby(‘Cell’)[‘angle’].mean()

aggregate information per cell and apply summary statistics

contact-length weighted mean of direction vectors

py_induced_dir_x = df.groupby(‘Cell’)[‘induced_dir_x’].mean() py_induced_dir_y = df.groupby(‘Cell’)[‘induced_dir_y’].mean() </Script> <Output symbol-ref="py_induced_dir_x"/> <Output symbol-ref="py_induced_dir_y"/> <Output symbol-ref="py_angle"/> </PyMapper> <MembraneProperty value="0.0" tags="py" symbol="cell_center_x"> <Diffusion rate="0"/> </MembraneProperty> <MembraneProperty value="0.0" tags="py" symbol="cell_center_y"> <Diffusion rate="0"/> </MembraneProperty> <Mapper name="cell_center_x" time-step="1.0" tags="py"> <Input value="cell.center.x"/> <Output symbol-ref="cell_center_x"/> </Mapper> <Mapper name="cell_center_y" time-step="1.0" tags="py"> <Input value="cell.center.y"/> <Output symbol-ref="cell_center_y"/> </Mapper> <MembraneProperty value="0.0" tags="py" symbol="neighbor_center_x"> <Diffusion rate="0"/> </MembraneProperty> <MembraneProperty value="0.0" tags="py" symbol="neighbor_center_y"> <Diffusion rate="0"/> </MembraneProperty> <NeighborhoodReporter name="neighbor_center_x" time-step="1.0" tags="py"> <Input value="cell.center.x" scaling="length"/> <Output symbol-ref="neighbor_center_x" mapping="discrete"/> </NeighborhoodReporter> <NeighborhoodReporter name="neighbor_center_y" time-step="1.0" tags="py"> <Input value="cell.center.y" scaling="length"/> <Output symbol-ref="neighbor_center_y" mapping="discrete"/> </NeighborhoodReporter> <MembraneProperty value="0.0" tags="py" symbol="neighbor_velocity_x"> <Diffusion rate="0"/> </MembraneProperty> <MembraneProperty value="0.0" tags="py" symbol="neighbor_velocity_y"> <Diffusion rate="0"/> </MembraneProperty> <NeighborhoodReporter name="neighbor_velocity_x" time-step="1.0" tags="py"> <Input value="velocity.x" scaling="length"/> <Output symbol-ref="neighbor_velocity_x" mapping="discrete"/> </NeighborhoodReporter> <NeighborhoodReporter name="neighbor_velocity_y" time-step="1.0" tags="py"> <Input value="velocity.y" scaling="length"/> <Output symbol-ref="neighbor_velocity_y" mapping="discrete"/> </NeighborhoodReporter> <PropertyVector name="Mechanically induced direction (computed in the PyMapper)." value="0.0, 0.0, 0.0" notation="x,y,z" tags="py" symbol="mech_induced_dir"/> <VectorEquation symbol-ref="mech_induced_dir" name="build vector" notation="x,y,z" tags="py"> <Expression>py_induced_dir_x, py_induced_dir_y, 0.0</Expression> </VectorEquation> <Property name="last tumble event" value="0" tags="RunandTumble" symbol="tumble.last"/> <Property name="run duration" value="0.0" tags="RunandTumble" symbol="tumble.run_duration"/> <Event trigger="when true" name="Run and Tumble" time-step="5" tags="RunandTumble"> <Condition>(time >= tumble.last + tumble.run_duration)</Condition> <Rule symbol-ref="tumble.last"> <Expression>time</Expression> </Rule> <Rule symbol-ref="tumble.run_duration" name="new update time"> <Expression>run_duration_adjustment * rand_gamma(0.5, 5)</Expression> </Rule> <Intermediate value="rand_uni(0, 2 * pi)" symbol="angle"/> <VectorRule symbol-ref="RaT_dir" notation="φ,θ,r"> <Expression>angle, 0 , 1</Expression> </VectorRule> </Event> <PropertyVector value="0.0, 0.0, 0.0" tags="RunandTumble" symbol="RaT_dir"/> <Property name="Defines cell’s colour." value="2" symbol="color"/> <Event name="After 20 time steps, set the properties of polster cells."> <Condition>time == 20 and cell.center.y > 360 </Condition> <Rule symbol-ref="color"> <Expression>3</Expression> </Rule> <Rule symbol-ref="directed_motion_strength"> <Expression>0</Expression> </Rule> <Rule symbol-ref="RandT_or_Mech_motion_strength"> <Expression>RandT_or_Mech_motion_strength_global</Expression> </Rule> </Event> <Event name="After 20 time steps, set the properties of axial cells."> <Condition>time == 20 and cell.center.y &lt;= 360</Condition> <Rule symbol-ref="directed_motion_strength"> <Expression>directed_motion_strength_global</Expression> </Rule> <Rule symbol-ref="RandT_or_Mech_motion_strength"> <Expression>0</Expression> </Rule> </Event> <CellDeath name="Laser ablation" tags="laser_ablation"> <Condition>time == 30 and cell.center.y > 550 and cell.center.y &lt; 600 and ablation == 1</Condition> </CellDeath> </CellType> <CellType name="confinement" class="biological"> <FreezeMotion> <Condition>1</Condition> </FreezeMotion> <Property value="1" symbol="color"/> </CellType> </CellTypes> <CPM> <Interaction> <Contact value="20.0" type1="cell" type2="confinement"/> </Interaction> <ShapeSurface scaling="norm"> <Neighborhood> <Order>3</Order> </Neighborhood> </ShapeSurface> <MonteCarloSampler stepper="edgelist"> <MCSDuration value="0.1"/> <MetropolisKinetics temperature="1"/> <Neighborhood> <Order>1</Order> </Neighborhood> </MonteCarloSampler> </CPM> <CellPopulations> <Population name="polster and axial cells" size="1" type="cell"> <InitRectangle mode="regular" random-offset="5" number-of-cells="400"> <Dimensions origin="160,15.0, 0.0" size="180.0, 650.0, 1.0"/> </InitRectangle> </Population> <Population name="Lateral confinement" size="1" type="confinement"> <InitCellObjects mode="order"> <Arrangement repetitions="1, 1, 1" displacements="1, 1, 1"> <Box origin="0.0, 0.0, 0.0" size="150.0, 1500.00.866, 0.0"/> </Arrangement> </InitCellObjects> <InitCellObjects mode="distance"> <Arrangement repetitions="1, 1, 1" displacements="1, 1, 1"> <Box origin="size.x-150, 0.0, 0.0" size="150.0, 1500.00.866, 0.0"/> </Arrangement> </InitCellObjects> </Population> </CellPopulations> <Analysis> <DependencyGraph reduced="false" format="png" include-tags="#untagged,RunandTumble,guidance_by_followers,laser_ablation,py"/> <Logger name="Trajectories, one CSV file per cell, single plot for all cells." time-step="20"> <Input> <Symbol symbol-ref="cell.center.x"/> <Symbol symbol-ref="cell.center.y"/> </Input> <Output> <TextOutput file-separation="cell"/> </Output> <Plots> <Plot> <Style line-width="2.0" style="lines"/> <Terminal terminal="png"/> <X-axis> <Symbol symbol-ref="cell.center.x"/> </X-axis> <Y-axis> <Symbol symbol-ref="cell.center.y"/> </Y-axis> <Color-bar maximum="6" palette="hot" minimum="0"> <Symbol symbol-ref="cell.id"/> </Color-bar> </Plot> </Plots> </Logger> <Logger name="MSD for whole population" time-step="100"> <Input/> <Output> <TextOutput/> </Output> <Plots> <Plot> <Style style="lines"/> <Terminal terminal="png"/> <X-axis> <Symbol symbol-ref="time"/> </X-axis> <Y-axis> <Symbol symbol-ref="MSD"/> </Y-axis> </Plot> </Plots> </Logger> <Gnuplotter time-step="1"> <Plot title=" "> <Cells value="color" min="1" max="3"> <ColorMap> <Color value="1" color="gray90"/> <Color value="2" color="yellow"/> <Color value="3" color="green"/> </ColorMap> </Cells> </Plot> <Terminal name="png"/> </Gnuplotter> </Analysis> </MorpheusModel>

Model Graph
Model Graph

Downloads

Files associated with this model:

Previous
Next