%load_ext autoreload
%autoreload 2
%run nb_init.py
import IPython.core.display as disp
2014-03-19 10:50:04,694 -leg_joint -INFO -successfully imported leg_joint
[TOC]
The architecture of the epithelium model consists in a graph containing
two types of vertices:
and two types of edges:
The junction edges, structuring the apical surface of the
epithelium
neighbouring junction vertices.
disp.SVG(filename='../doc/imgs/one_cell.svg')
The position of the vertices is given in two 3D coordinate systems, cartesian $(x, y, z)$ and cylindrical $(\rho, \theta, z)$.
Initialy, the vertices are distributed over a cylinder centered around the $z$ axis. The volume of a cell is computed as the sum of the area of each triangle formed by a junction edge and two cell-to-junction edges times the height of the cell center. Of course this is an approximation:
$$
V_\alpha = \sum_{i,j} A_{\alpha ij} h_\alpha c_{\alpha i} c_{\alpha j} c_{ij}
$$
with $c_{uv} = 1$ if vertices $u$ and $v$ are connected and 0 otherwise.
and $A_{\alpha ij} = || \mathbf{r}_{\alpha i} \times \mathbf{ r}_{\alpha j} || / 2 $
Three interactions are considered at the epithelium:
The line tension between two junction vertices, with associated energy $E^t_{ij} = \Lambda \ell_{ij}$, where $\ell_{ij}$ is the length of the junction edge between vertices $i$ and $j$.
The contraction of a cell, with associated energy $E^c_\alpha = \Gamma L_\alpha^2$, where $L_\alpha$ is the perimeter of the cell $\alpha$.
The volume elasticity $E^v_\alpha = K_v (V_\alpha - V_0)^2$, where $V_\alpha$ is the volume of the cell $\alpha$.
The total energy is given by:
$$ E = \sum_\alpha (E^v_\alpha + E^c_\alpha) + \sum_{i \leftrightarrow j} E^t_{ij} $$disp.SVG(filename='../doc/imgs/coordinate_system.svg')
leg_joint
module¶We show below a view of an epithelium. The static view is stored as a graphXML file parsed by graph_tool, and passed to instenciate an Epithelium
container class. We won't focus on the implementation details for now.
eptm = lj.Epithelium(graphXMLfile='../saved_graphs/xml/before_apoptosis.xml')
print(eptm)
2014-03-19 10:50:16,572 -leg_joint.epithelium -INFO -Instanciating epithelium 0 2014-03-19 10:50:18,991 -leg_joint.epithelium -INFO -Initial cells 2014-03-19 10:50:18,992 -leg_joint.epithelium -INFO -Initial junctions 2014-03-19 10:50:49,557 -leg_joint.epithelium -INFO -Update geometry
<Epithelium with 1729 cells and 5059 junction edges at 0x98534a6c> Identifier : 0_2014-03-19T09_50_16 Directory : /home/guillaume/Python/leg_joint/saved_graphs/0_2014-03-19T09_50_16
All the variables associated with the apical junction network are stored as graph_tool PropertyMaps
.
eptm.graph.list_properties()
radial_tensions (vertex) (type: double) volume_grad_apical (vertex) (type: double) volume_grad_radial (vertex) (type: double) contractile_grad (vertex) (type: double) rhos (vertex) (type: double) grad_ix (vertex) (type: double) is_cell_vert (vertex) (type: bool) perimeters (vertex) (type: double) grad_zed (vertex) (type: double) grad_wy (vertex) (type: double) ixs (vertex) (type: double) ages (vertex) (type: int32_t) wys (vertex) (type: double) contractilities (vertex) (type: double) thetas (vertex) (type: double) grad_radial (vertex) (type: double) sigmas (vertex) (type: double) grad_sigma (vertex) (type: double) volume_grad_cell (vertex) (type: vector<double>) volume_grad (vertex) (type: double) areas (vertex) (type: double) vol_elasticities (vertex) (type: double) elastic_grad (vertex) (type: double) zeds (vertex) (type: double) prefered_vol (vertex) (type: double) is_active_vert (vertex) (type: bool) vols (vertex) (type: double) is_alive (vertex) (type: bool) is_local_vert (vertex) (type: bool) u_drhos (edge) (type: double) drhos (edge) (type: double) is_junction_edge (edge) (type: bool) is_ctoj_edge (edge) (type: bool) u_dsigmas (edge) (type: double) dzeds (edge) (type: double) is_local_edge (edge) (type: bool) is_active_edge (edge) (type: bool) dthetas (edge) (type: double) u_dzeds (edge) (type: double) is_new_edge (edge) (type: bool) u_dwys (edge) (type: double) at_boundary (edge) (type: bool) dwys (edge) (type: double) dsigmas (edge) (type: double) edge_lengths (edge) (type: double) u_dixs (edge) (type: double) dixs (edge) (type: double) line_tensions (edge) (type: double)
There are various ways to look at an epithelium. The default one is just called draw
, and produces a 3D and a 2D view. Color code corresponds to the depth of the edge.
lj.draw(eptm, output3d='../doc/imgs/tissue_3d.png',
output2d='../doc/imgs/tissue_2d.png')
disp.Image(filename='../doc/imgs/tissue_3d.png')
disp.Image(filename='../doc/imgs/tissue_2d.png')
eptm.graph.properties.keys()
dict_keys([('v', 'radial_tensions'), ('v', 'is_alive'), ('v', 'thetas'), ('v', 'wys'), ('e', 'line_tensions'), ('e', 'u_dixs'), ('e', 'dwys'), ('v', 'grad_ix'), ('v', 'elastic_grad'), ('v', 'zeds'), ('e', 'is_new_edge'), ('e', 'at_boundary'), ('e', 'is_local_edge'), ('v', 'grad_radial'), ('v', 'volume_grad'), ('e', 'is_active_edge'), ('e', 'u_drhos'), ('e', 'u_dzeds'), ('v', 'is_active_vert'), ('v', 'perimeters'), ('e', 'is_junction_edge'), ('v', 'prefered_vol'), ('v', 'is_cell_vert'), ('v', 'grad_sigma'), ('v', 'contractile_grad'), ('v', 'volume_grad_cell'), ('v', 'volume_grad_radial'), ('v', 'ixs'), ('e', 'edge_lengths'), ('v', 'sigmas'), ('e', 'u_dwys'), ('e', 'is_ctoj_edge'), ('v', 'areas'), ('v', 'grad_zed'), ('e', 'dzeds'), ('v', 'vol_elasticities'), ('v', 'grad_wy'), ('v', 'volume_grad_apical'), ('e', 'drhos'), ('v', 'contractilities'), ('e', 'dsigmas'), ('e', 'dixs'), ('v', 'ages'), ('e', 'dthetas'), ('e', 'u_dsigmas'), ('v', 'vols'), ('v', 'is_local_vert'), ('v', 'rhos')])
For the epithelium above, we can look at the number of neighbors for each cells, and the dependency of the cells' areas on this number. This is what we compute in the cell bellow.
eptm.graph.set_vertex_filter(None)
## The number of side is equal to the number of junction vertices
## thus to the number of out neighbors of each cell
num_sides = eptm.graph.degree_property_map('out')
## Filter living cells
live_cells = eptm.is_alive.copy()
live_cells.a *= eptm.is_cell_vert.a
eptm.graph.set_vertex_filter(live_cells)
## Computing nomrmalized area
normed_areas = eptm.cells.areas.fa / eptm.cells.areas.fa.mean()
## Getting the numbr of sides only for living cells
num_sides = np.asarray(num_sides.fa)
u_num_sides = np.unique(num_sides)
## Plotting it all
avg_areas = np.zeros(u_num_sides.size)
stm_areas = np.zeros(u_num_sides.size)
bins, n_cells = np.histogram(num_sides, bins=11, range=(0, 11))
for n, n_sides in enumerate(u_num_sides):
avg_areas[n] = normed_areas[num_sides == n_sides].mean()
stm_areas[n] = normed_areas[num_sides == n_sides].std() / np.sqrt(n_cells[np.int(n_sides)])
fig, (ax1, ax2) = plt.subplots(2, 1, sharex=True, figsize=(6, 6))
ax1.plot(num_sides, normed_areas, 'o', alpha=0.05)
ax1.errorbar(u_num_sides, avg_areas, yerr=stm_areas, lw=2, elinewidth=2)
ax1.set_xlim(0, 12)
ax2.hist(num_sides, bins=11, range=(0.5, 11.5),
normed=True, color='g', alpha=0.7)
ax2.set_xlim(0, 12)
eptm.graph.set_vertex_filter(None)
ax2.set_xlabel('Number of cell neighbors')
ax2.set_ylabel('Frequency')
ax1.set_ylabel('Normalized cell area')
plt.draw()
fig.savefig('../doc/imgs/tissue_geometry.svg')