Exemplo n.º 1
0
def octahedron_tetrahedra(side_length=15.):
    points = {}
    points[2] = np.array([1, 0, 0]) + 0.1 * np.random.rand(3)
    points[3] = np.array([0, 1, 0]) + 0.1 * np.random.rand(3)
    points[4] = np.array([-1, 0, 0]) + 0.1 * np.random.rand(3)
    points[5] = np.array([0, -1, 0]) + 0.1 * np.random.rand(3)
    points[6] = np.array([0, 0, 1]) + 0.1 * np.random.rand(3)
    points[7] = np.array([0, 0, -1]) + 0.1 * np.random.rand(3)

    tetrahedra = []
    tetrahedra += [[2, 3, 4, 6]]
    tetrahedra += [[2, 4, 5, 6]]
    tetrahedra += [[2, 3, 4, 7]]
    tetrahedra += [[2, 4, 5, 7]]

    return tetrahedra_topomesh(tetrahedra, points)
def octahedron_tetrahedra(side_length=15.):
    points = {}
    points[2] = np.array([1,0,0]) + 0.1*np.random.rand(3)
    points[3] = np.array([0,1,0]) + 0.1*np.random.rand(3)
    points[4] = np.array([-1,0,0]) + 0.1*np.random.rand(3)
    points[5] = np.array([0,-1,0]) + 0.1*np.random.rand(3)
    points[6] = np.array([0,0,1]) + 0.1*np.random.rand(3)
    points[7] = np.array([0,0,-1]) + 0.1*np.random.rand(3)

    tetrahedra = []
    tetrahedra += [[2,3,4,6]]
    tetrahedra += [[2,4,5,6]]
    tetrahedra += [[2,3,4,7]]
    tetrahedra += [[2,4,5,7]]

    return tetrahedra_topomesh(tetrahedra,points)
Exemplo n.º 3
0
    def compute_image_adjacency(self):
        """Compute the adjacency relationships between cells in the tissue image.

        By default, the DRACO adjacency complex is set to the cell_vertices tetrahedra (!!NOT A VALID CELL COMPLEX!!)
        !!STRONG RISK OF TOPOLOGICAL ERRORS IF DUALIZING AT THIS STAGE!!

        Updates:
            image_graph (PropertyGraph): adjacency graph connecting adjacent cells by edges
            image_cell_vertex (dict): cell vertices representing 4 co-adjacent cells by the point where they meet
            cell_layer (int): information whether the cell belong to the first layer of cells (L1), the second one (L2) or lower layers (0)
            layer_edge_topomesh (PropertyTopomesh): adjacency graphs restricted to the L1 and L2 layers
            layer_triangle_topomesh (PropertyTopomesh): adjacency triangles between L1 and L2 layers (**TO BE COMPLETED**)
            triangulation_topomesh (PropertyTopomesh): the tetrahedra representing adjacencies between cells 

        Returns:
            None
        """

        self.image_graph = graph_from_image(
            self.segmented_image,
            spatio_temporal_properties=["volume", "barycenter", "L1"],
            ignore_cells_at_stack_margins=False,
            property_as_real=True,
        )
        self.image_labels = np.array(list(self.image_graph.vertices()))
        self.image_cell_volumes = array_dict(
            [self.image_graph.vertex_property("volume")[v] for v in self.image_labels], self.image_labels
        )
        img_center = np.nanmean(self.image_graph.vertex_property("barycenter").values(), axis=0)

        self.positions = array_dict(self.image_graph.vertex_property("barycenter"))
        self.point_topomesh = vertex_topomesh(self.positions)

        img_analysis = SpatialImageAnalysis(self.segmented_image)
        exterior_cells = np.array(list(img_analysis.neighbors(1)))
        self.image_wall_surfaces = img_analysis.wall_areas(real=True)

        self.image_graph.add_vertex(1)
        for c in exterior_cells:
            self.image_graph.add_edge(1, c)

        for v in self.image_cell_vertex.keys():
            self.image_cell_vertex[v] = self.image_cell_vertex[v] * self.resolution
        image_cell_vertex_tetrahedra = np.sort(self.image_cell_vertex.keys())
        image_cell_vertex_tetrahedra = np.delete(
            image_cell_vertex_tetrahedra, np.where(image_cell_vertex_tetrahedra[:, 0] == 1)[0], axis=0
        )
        self.image_cell_vertex_topomesh = tetrahedra_topomesh(image_cell_vertex_tetrahedra, self.positions)
        self.triangulation_topomesh = deepcopy(self.image_cell_vertex_topomesh)

        truncated_image = self.segmented_image[:, :, :]
        truncated_image_graph = graph_from_image(
            truncated_image,
            spatio_temporal_properties=["barycenter", "L1"],
            background=1,
            ignore_cells_at_stack_margins=True,
            property_as_real=True,
        )

        self.cell_layer = array_dict(np.zeros_like(self.positions.keys()), self.positions.keys())
        for c in truncated_image_graph.vertices():
            if c > 1 and truncated_image_graph.vertex_property("L1")[c]:
                self.cell_layer[c] = 1
        for c in self.cell_layer.keys():
            if c > 1 and self.cell_layer[c] == 1:
                for n in truncated_image_graph.neighbors(c):
                    if n > 1 and self.cell_layer[n] != 1:
                        self.cell_layer[n] = 2
        self.point_topomesh.update_wisp_property(
            "layer", 0, self.cell_layer.values(list(self.point_topomesh.wisps(0))), list(self.point_topomesh.wisps(0))
        )

        self.layer_edge_topomesh = {}

        if (self.cell_layer.values() == 1).sum() > 1:
            L1_edges = np.array(
                [
                    [(c, n) for n in self.image_graph.neighbors(c) if n > 1 and self.cell_layer[n] == 1]
                    for c in self.cell_layer.keys()
                    if self.cell_layer[c] == 1
                ]
            )
            L1_edges = np.concatenate([e for e in L1_edges if len(e) > 0])
            L1_edges = L1_edges[L1_edges[:, 1] > L1_edges[:, 0]]
            L1_edge_topomesh = edge_topomesh(L1_edges, self.positions)
            self.layer_edge_topomesh["L1"] = L1_edge_topomesh

        if (self.cell_layer.values() == 2).sum() > 1:
            L2_edges = np.array(
                [
                    [(c, n) for n in self.image_graph.neighbors(c) if n > 1 and self.cell_layer[n] == 2]
                    for c in self.cell_layer.keys()
                    if self.cell_layer[c] == 2
                ]
            )
            L2_edges = np.concatenate([e for e in L2_edges if len(e) > 0])
            L2_edges = L2_edges[L2_edges[:, 1] > L2_edges[:, 0]]
            L2_edge_topomesh = edge_topomesh(L2_edges, self.positions)
            self.layer_edge_topomesh["L2"] = L2_edge_topomesh

        self.layer_triangle_topomesh = {}

        if (self.cell_layer.values() == 1).sum() > 1 and (self.cell_layer.values() == 2).sum() > 1:
            L1_L2_edges = np.array(
                [
                    [(c, n) for n in self.image_graph.neighbors(c) if n > 1 and self.cell_layer[n] in [1, 2]]
                    for c in self.cell_layer.keys()
                    if self.cell_layer[c] in [1, 2]
                ]
            )
            L1_L2_edges = np.concatenate([e for e in L1_L2_edges if len(e) > 0])
            L1_L2_edges = L1_L2_edges[L1_L2_edges[:, 1] > L1_L2_edges[:, 0]]

            L1_L2_additional_edges = np.array(
                [
                    [
                        (c, n)
                        for n in np.unique(
                            np.array(self.image_cell_vertex.keys())[
                                np.where(np.array(self.image_cell_vertex.keys()) == c)[0]
                            ]
                        )
                        if n > 1
                        and n != c
                        and (n not in self.image_graph.neighbors(c))
                        and (self.cell_layer[n] in [1, 2])
                    ]
                    for c in self.cell_layer.keys()
                    if self.cell_layer[c] in [1, 2]
                ]
            )
            L1_L2_additional_edges = np.concatenate([e for e in L1_L2_additional_edges if len(e) > 0])
            L1_L2_additional_edges = L1_L2_additional_edges[L1_L2_additional_edges[:, 1] > L1_L2_additional_edges[:, 0]]

            self.layer_triangle_topomesh["L1_L2"] = triangle_topomesh(
                triangles_from_adjacency_edges(np.concatenate([L1_L2_edges, L1_L2_additional_edges])), self.positions
            )