TissueGraph implementation proposal¶
Biological observations¶
The typical object is a multicellular tissue observation (from microscopy). Cell-based segmentation, manual or algorithmic, is required to access the spatial information hidden in the intensity image.
Goal¶
The goal of this data structure is to provide a flexible graph object dedicated to the organisation and exploration of multicellular tissue properties.
It is based on the
networkx
library.Biological semantic should be used when possible.
Properties are stored in dictionaries attached to the corresponding element, i.e. the volume of a cell will be attached to the cell
Structure¶
A primal graph organize the cells (primal graph nodes) and connect them with walls (primal graph edges). A dual graph organize the cell vertices (dual graph nodes) and connect them with cell edges (dual graph edges).
Both graphs are undirected networkx.Graph()
.
Warning
We have to define what to do with the background id!
Element ids¶
Tissue image element ids¶
In the image, the topological element ids are:
cell ids are defined by an integer, e.g.
5
.cell-wall ids are defined by two cells in junction, so a len-2 tuple of integers, e.g.
(5, 6)
for cells5
and6
.cell-edge ids are defined by three cells in junction, so a len-3 tuple of integers, e.g.
(5, 6, 7)
for cells5
,6
and7
.cell-vertex ids are defined by four cells in junction, so a len-4 tuple of integers, e.g.
(5, 6, 7, 8)
for cells5
,6
,7
and8
.
Tissue graph element ids¶
In the tissue graph, the topological element ids are different for edges as they now relate two cell-vertices of the dual graph.
Primal graph¶
cell ids
cid
are the nodes defined by integers, e.g.5
for cell5
.cell-wall ids
wid=(cid_i, cid_j)
are the edges defined by a len-2 tuple of integers, e.g.(5, 6)
for the two cells (nodes) it join.
Dual graph¶
cell-vertex ids
vid=(cid_i, cid_j, cid_k, cid_l)
are the nodes defined by a len-4 tuple of integers, e.g.(5, 6, 7, 8)
for cells5
,6
,7
and8
.cell-edge ids
eid=(vid_1, vid_2)=((cid_i1, cid_j1, cid_k1, cid_l1), (cid_i2, cid_j2, cid_k2, cid_l2))
are the edges defined by two len-4 tuple of integers, e.g.(5, 6, 7, 8)
and(5, 6, 7, 9)
for the two cell-vertices (nodes) it join.
Methods¶
Creation methods¶
The first step is to populate the data structure with the topological data from the segmented tissue. Then we can attach spatial properties to the topological elements.
Add topological elements¶
The following methods allow adding topological elements to the tissue graph:
tg = TissueGraph()
tg.add_cells(cells)
tg.add_cell_walls(walls)
tg.add_cell_vertices(vertices)
tg.add_cell_edges(edges)
Examples¶
tg.add_cells([2, 3, 4]) # add cell ids to the graph
tg.add_cell_walls([(2, 3), (2, 4)]) # add two edges to the graph
Add properties¶
The following methods allow adding named properties (and their unit) to topological elements to the tissue graph:
tg.add_cell_property(name, values, unit)
tg.add_cell_wall_property(name, values, unit)
tg.add_cell_edge_property(name, values, unit)
tg.add_cell_vertex_property(name, values, unit)
The values
should be dictionaries with keys matching the type of element ids they correspond to.
Examples¶
tg.add_cell_property('volume', {2: 25.6, 3: 31.2}, 'µm³') # add a 'volume' property to the cells
tg.add_cell_wall_property('area', {(2, 3): 15.6}, 'µm²') # add an 'area' property to the cell walls
Inspection methods¶
Two options are possible to access properties:
get the property value for a single element id, in that case we will return an integer|float|numpy.array (e.g. the cell’s neighborhood size, volume, inertia axes) or a list of integers|floats|numpy.arrays (e.g. the cell’s neighbors).
get the property values for a list of element ids (all of them or according to a specific list), in that case we will return a dictionary of values for all elements (or those selected).
Important
In both cases, if a property is not defined for an element, None
will be used as default value (default missing value should be editable)
List of ids¶
The following methods return list of ids:
tg.cell_ids()
tg.cell_wall_ids()
tg.cell_edge_ids()
tg.cell_vertex_ids()
List of properties¶
The following methods return dictionary of properties and their units by elements’ type:
tg.list_cell_properties()
tg.list_wall_properties()
tg.list_cell_edge_properties()
tg.list_cell_vertex_properties()
Example for a graph with cell’s volumes:
>>> tg.cell_properties()
{'volume': 'µm³'}
Single element - single property¶
To access the properties of a single element, the following methods:
tg.cell_property(cell_id, name, default=None)
tg.cell_wall_property(wall_id, name, default=None)
This return a single value which type depends on the property type (integer, float, numpy.array).
Important
If the property is unknown to the cell_id
, return a default
value.
Single element - all properties¶
tg.cell_properties(cell_id, ppties=None, default=None)
tg.cell_wall_properties(wall_id, ppties=None, default=None)
This return a dictionary with property names as keys and their associated value, if defined, which type depends on the property type (integer, float, numpy.array).
Warning
If names
is None
, what should we return?
all known property to the element (skip those undefined for the element)
all known property to the graph for the element (with default value)
Single property - several elements¶
tg.cell_property_dict(names, cell_ids=None, default=None)
tg.cell_wall_property_dict(names, wall_ids=None, default=None)
This return a dictionary with element ids as keys and their associated value, if defined, which type depends on the property type (integer, float, numpy.array).
Important
If cell_ids
is None
, returns the dictionary for all cells known to the graph, with a default value for cells without a property value.
Exceptions¶
As node neighbors are quite useful to explore the graph, there are a few dedicated method:
tg.cell_neighbors(cell_id)
tg.cell_vertex_neighbors(cell_vertex_id)
tg.cell_neighbors_dict()
Bulk export to CSV¶
It can be useful to export all (or a selection of) properties known to a CSV file to process or display them in an external app.
tg.cell_csv(names=None, cell_ids=None, default=None)
tg.cell_wall_csv(names=None, wall_ids=None, default=None)
Important
If names
is None
, returns all known property to the graph for this element, with default for element without a property value.
Important
If cell_ids
is None
, returns the dictionary for all cells known to the graph, with a default value for cells without a property value.
Spatial differentiation functions¶
Laplacian¶
Formulae¶
The Laplacian for cell \(i\), on a given property, can be expressed as: \(\text{L}_i = \dfrac{1}{N} . \sum_{x=1}^N (v_i - v_x)\), with \(v_x\) the property values of the \(N\) neighbors of cell \(i\) and \(v_i\) its property value.
Mean absolute deviation¶
Creation¶
Can be created from list of cells, & cell walls
tissue = TissueImage3D(img, background=1, not_a_label=0)
tg = TissueGraph()
tg.add_cells(tissue.cell_ids()) # add the list of cells
tg.cell_ids()[:10] # access the first 10