Source code for tyssue.behaviors.monolayer.delamination_events

import logging

from ...topology.bulk_topology import HI_transition, IH_transition
from ...utils.decorators import cell_lookup
from ..sheet.basic_events import contraction as sheet_contraction
from ..sheet.delamination_events import _neighbor_contractile_increase
from .actions import ab_pull_edge, contract, shrink

logger = logging.getLogger(__name__)


default_constriction_spec = {
    "cell_id": -1,
    "cell": -1,
    "contract_rate": 2.0,
    "critical_area": 1e-2,
    "shrink_rate": 0.4,
    "critical_volume": 0.1,
    "radial_tension": 1.0,
    "contract_neighbors": True,
    "critical_area_neighbors": 10,
    "contract_span": 2,
    "basal_contract_rate": 1.001,
    "current_traction": 0,
    "max_traction": 30,
    "contraction_column": "contractility",
    "with_rearrangement": False,
    "critical_area_reduction": 5,
}


[docs]@cell_lookup def constriction(monolayer, manager, **kwargs): """Constriction behavior Parameters ---------- monolayer : a :cass:`Monolayer` object manager : a :class:`EventManager` object """ constriction_spec = default_constriction_spec constriction_spec.update(**kwargs) cell = constriction_spec["cell"] contract_rate = constriction_spec["contract_rate"] # Find the apical face id of the cell list_face_in_cell = monolayer.get_orbits("cell", "face") faces_in_cell = monolayer.face_df.loc[list_face_in_cell[cell].unique()] if "apical" in faces_in_cell["segment"].values: apical_face_id = faces_in_cell[faces_in_cell["segment"] == "apical"].index[0] else: apical_face_id = None if apical_face_id is None and constriction_spec["with_rearrangement"]: _constrict_apical(faces_in_cell, monolayer, constriction_spec) else: apical_face_area = monolayer.face_df.loc[apical_face_id, "area"] if apical_face_area > constriction_spec["critical_area"]: contract( monolayer, apical_face_id, contract_rate, True, constriction_spec["contraction_column"], ) if (constriction_spec["contract_neighbors"]) & ( apical_face_area < constriction_spec["critical_area_neighbors"] ): sheet = monolayer.get_sub_sheet("apical") neighbors = sheet.get_neighborhood( apical_face_id, constriction_spec["contract_span"] ).dropna() neighbors["id"] = sheet.face_df.loc[neighbors.face, "id"].values # remove cell which are not mesodermal ectodermal_cell = sheet.face_df.loc[neighbors.face][ ~sheet.face_df.loc[neighbors.face, "is_mesoderm"] ].id.values neighbors = neighbors.drop( neighbors[neighbors.id.isin(ectodermal_cell)].index ) manager.extend( [ ( sheet_contraction, _neighbor_contractile_increase(neighbor, constriction_spec), ) for _, neighbor in neighbors.iterrows() ] ) if not constriction_spec["with_rearrangement"]: # we're done return # If apical face has already been removed # Need to eliminate lateral face until obtain cell with 4 faces # If apical face area are under threshold if apical_face_area < constriction_spec["critical_area_reduction"]: # Reduce neighbours for the apical face (until 3) if monolayer.face_df.loc[apical_face_id, "num_sides"] > 3: # "Remove" the shortest edge e_min = monolayer.edge_df[monolayer.edge_df["face"] == apical_face_id][ "length" ].idxmin() prev_nums = { "edge": monolayer.Ne, "face": monolayer.Nf, "vert": monolayer.Nv, } monolayer.settings["threshold_length"] = 1e-3 IH_transition(monolayer, e_min) monolayer.face_df.loc[prev_nums["face"] :, "contractility"] = 0 elif monolayer.face_df.loc[apical_face_id, "num_sides"] == 3: prev_nums = { "edge": monolayer.Ne, "face": monolayer.Nf, "vert": monolayer.Nv, } HI_transition(monolayer, apical_face_id) manager.append(constriction, **constriction_spec)
def _constrict_apical(faces_in_cell, monolayer, constriction_spec): cell = constriction_spec["cell"] current_traction = constriction_spec["current_traction"] if len(faces_in_cell) > 4: # Remove lateral face with 3 sides three_lateral = faces_in_cell[ (faces_in_cell.segment == "lateral") & (faces_in_cell.num_sides == 3) ].index if len(three_lateral): face_to_eliminate = three_lateral[0] prev_Nf = monolayer.Nf HI_transition(monolayer, face_to_eliminate) monolayer.face_df.loc[prev_Nf:, "contractility"] = 0 elif len(faces_in_cell) == 4: if monolayer.cell_df.loc[cell, "vol"] > constriction_spec["critical_volume"]: shrink(monolayer, cell, constriction_spec["shrink_rate"]) if current_traction < constriction_spec["max_traction"]: list_vert_in_cell = monolayer.get_orbits("cell", "srce") vert_in_cell = monolayer.vert_df.loc[list_vert_in_cell[4].unique()] apical_vert = vert_in_cell[vert_in_cell["segment"] == "apical"].index[0] list_vert_connected_to_apical = monolayer.edge_df[ monolayer.edge_df["srce"] == apical_vert ]["trgt"].unique() opposite_vert = -1 for v in list_vert_connected_to_apical: if v not in (vert_in_cell.index): opposite_vert = v if opposite_vert > -1: edges_to_pull = monolayer.edge_df[ ( (monolayer.edge_df.trgt == apical_vert) & (monolayer.edge_df.srce == opposite_vert) ) | ( (monolayer.edge_df.srce == apical_vert) & (monolayer.edge_df.trgt == opposite_vert) ) ].index ab_pull_edge( monolayer, edges_to_pull, constriction_spec["radial_tension"], True ) current_traction += 1 constriction_spec.update({"current_traction": current_traction})