Source code for tyssue.topology.monolayer_topology

import logging
import numpy as np

from ..geometry.bulk_geometry import MonolayerGeometry
from ..core.sheet import Sheet
from ..geometry.sheet_geometry import SheetGeometry
from .bulk_topology import get_division_vertices
from .bulk_topology import cell_division as bulk_division
from .sheet_topology import type1_transition as sheet_t1
from .sheet_topology import get_division_edges as sheet_division_edges


logger = logging.getLogger(name=__name__)


[docs]def cell_division(monolayer, mother, orientation="vertical", psi=0): """ Divides the cell mother in the monolayer. Parameters ---------- * monolayer: a :class:`Monolayer` instance * mother: int, the index of the cell to devide * orientation: str, {"vertical" | "horizontal"} if "horizontal", performs a division in the equatorial plane of the cell. If "vertical" (the default), performs a division along the basal-apical axis of the cell * psi: float, default 0 extra rotation angle of the division plane around the basal-apical plane Returns ------- * daughter: int, the index of the daughter cell """ ab_axis = MonolayerGeometry.basal_apical_axis(monolayer, mother) plane_normal = np.asarray(ab_axis) if orientation == "horizontal": vertices = get_division_vertices( monolayer, mother=mother, plane_normal=plane_normal ) elif orientation == "vertical": apical_sheet = monolayer.get_sub_sheet("apical") m_apical_face = monolayer.edge_df[ (monolayer.edge_df["cell"] == mother) & (monolayer.edge_df["segment"] == "apical") ]["face"].iloc[0] apical_edges = sheet_division_edges(apical_sheet, m_apical_face, SheetGeometry) basal_edges = [] for ae in apical_edges[::-1]: basal_edges.append(find_basal_edge(monolayer, ae)) division_edges = list(apical_edges) + basal_edges vertices = get_division_vertices(monolayer, division_edges=division_edges) else: raise ValueError( """orientation argument not understood, should be either "horizontal" or "vertical", not {}""".format( orientation ) ) daughter = bulk_division(monolayer, mother, MonolayerGeometry, vertices) # Correct segment assignations for the septum septum = monolayer.face_df.index[-2:] septum_edges = monolayer.edge_df.index[-2 * len(vertices) :] if orientation == "vertical": monolayer.face_df.loc[septum, "segment"] = "lateral" monolayer.edge_df.loc[septum_edges, "segment"] = "lateral" _assign_vert_segment(monolayer, vertices) elif orientation == "horizontal": monolayer.face_df.loc[septum[0], "segment"] = "apical" monolayer.face_df.loc[septum[1], "segment"] = "basal" monolayer.edge_df.loc[septum_edges[: len(vertices)], "segment"] = "apical" monolayer.edge_df.loc[septum_edges[len(vertices) :], "segment"] = "basal" monolayer.vert_df.loc[vertices, "segment"] = "apical" return daughter
def _assign_vert_segment(monolayer, vertices): for v in vertices: segs = set(monolayer.edge_df[monolayer.edge_df["srce"] == v]["segment"]) if "apical" in segs: monolayer.vert_df.loc[v, "segment"] = "apical" elif "basal" in segs: monolayer.vert_df.loc[v, "segment"] = "basal" else: monolayer.vert_df.loc[v, "segment"] = "lateral"
[docs]def find_basal_edge(monolayer, apical_edge): """Returns the basal edge parallel to the apical edge passed in argument. Parameters ---------- monolayer: a :class:`Monolayer` instance """ srce, trgt, cell = monolayer.edge_df.loc[apical_edge, ["srce", "trgt", "cell"]] cell_edges = monolayer.edge_df[monolayer.edge_df["cell"] == cell] srce_segment = monolayer.vert_df.loc[cell_edges["srce"].values, "segment"] srce_segment.index = cell_edges.index trgt_segment = monolayer.vert_df.loc[cell_edges["trgt"].values, "segment"] trgt_segment.index = cell_edges.index b_trgt, = cell_edges[ (srce_segment == "apical") & (trgt_segment == "basal") & (cell_edges["srce"] == srce) ]["trgt"] b_srce, = cell_edges[ (srce_segment == "basal") & (trgt_segment == "apical") & (cell_edges["trgt"] == trgt) ]["srce"] b_edge, = cell_edges[ (cell_edges["srce"] == b_srce) & (cell_edges["trgt"] == b_trgt) ].index return b_edge
[docs]def type1_transition(monolayer, apical_edge, epsilon=0.1): """Performs a type 1 transition on the apical and basal meshes """ v0_a, v1_a, fb_a, cb_a = monolayer.edge_df.loc[ apical_edge, ["srce", "trgt", "face", "cell"] ] basal_edge = find_basal_edge(monolayer, apical_edge) v0_b, v1_b, fb_b, cb_b = monolayer.edge_df.loc[ basal_edge, ["srce", "trgt", "face", "cell"] ] if monolayer.face_df.loc[fb_a, "num_sides"] < 4: logger.warning( """Face %s has 3 sides, type 1 transition is not allowed""", fb_a, ) return