In [1]:
import logging
logging.disable(logging.ERROR)
In [2]:
import leg_joint as lj
import matplotlib.pyplot as plt
%matplotlib inline
from IPython import display
import graph_tool.all as gt
import numpy as np

Pattes de mouches: une modélisation de biophysique utilisant python scientifique

Guillaume Gay

DamCB - Data analysis and modeling for Cell Biology

e-mail: guillaume@damcb.com

github / freenode: glyg

twitter: @damcellbio / @elagachado

On travaille sur la mouche du vinaigre, drosophila Melanogaster, un organisme modèle très utilisée en génétique et en biologie du développement. C’est une petite mouche, qui fait quelques milimètres de long.

La mouche source: wikipedia

On s’intéresse plus précisément au passage du stade pupal au stade adulte. Des groupes de cellules bien déterminés (les disques) dans la pupe vont se transformer en organes chez l’adulte. On regarde le disque de patte, qui donnera … la patte de la mouche.

Drosophila development

On regarde la formation du petit pli entre les segments 4 et 5. Le disque de patte est un épithélium une monocouche de cellules, qui forme une espèce de chaussette.

Vue de très près ça ressemble à ça:

Vue apicale

On observe ici les jonctions apicales, un ensemble de protéines qui forment un maillage entourant le haut des cellules.

Le problème biologique: comment la mouche plie ses pattes?

L’apoptose, ou les cellules kamikases

  • Mort programmée via une cascade biochimique.
  • Nombreuses fonctions:
    • comme la prévention du cancer
    • et la morphogénèse

Un exemple de phénotype quand il y a un défaut d’apoptose

Un pied sans apoptose

Dans le tissu qui donnera la patte

Pour former un pli, ~ 30 apoptoses en anneau autour de l’épithélium

Apical vue of the fold formation on a drosophila leg disk from glyg on Vimeo.

Et lorsqu’on suprime l’apoptose…

Des pattes trop droites

Regardons ce qu’il se passe à l’échelle cellulaire (on regarde une coupe des cellules, la région apicale est en haut, la région basale en bas.

L'apoptose dans la cellule vivante

En mourant, une cellule exèrce une traction vers le bas, et on voit aparaître une structure verticale de myosine, une protéine capable d’exercer une force (c’est le même type de protéine qui propulse nos muscles).

On est donc en présence d’un problème de forces et d’interactions mécaniques. C’est là que la modélisation peut intervenir, pour tester cet effet mécanique dans un modèle simplifié.

Le problème biophysique

Les déformations du tissus sont dues à l’activité d’un ensemble de protéines intra et extra cellulaires.

Le modèle de Farhadifar

Ces protéines forment un maillage entre les cellules, que l’on peut modéliser comme un réseau

Architecture du réseau pour une cellule


  • Minimiser localement l’énergie à chaque modification
  • Équilibre des forces

Le modèle est donc basé sur la bibliothèque graph_tool écrite et maintenue par Tiago P. Peixoto, permettant de manipuler des graphes.

Voici un exemple rapide de cette bibliothèque

In [3]:
g = gt.price_network(3000)
pos = gt.sfdp_layout(g)

pos = gt.graph_draw(g, pos=pos, output="graph-draw-sfdp.png")

A graph generatated by graph-tool

Les avantages de graph-tool:

  1. C’est rapide (C++ / meta-programming, openMP)
  2. PropertyMaps interfacées aux ndarray de NumPy.
  3. Bonnes E/S
  4. Mécanisme de filtrage (via des PropertyMaps booléennes appliquées sur le graphe)
  5. Bibliothèque complète d’analyse de graphes.

Le module leg_joint

  • Objet Epithelium:

    • graphe orienté, masques
    • géométrie
    • méthodes de base
  • Fonctions:

    • Division cellulaire, apoptose …
    • Optimisations
    • Représentation graphiques
In [4]:
### Create an epithelium by instanciating the container class

eptm = lj.Epithelium(lj.data.before_apoptosis_xml(),
                     save_dir='.',
                     identifier='slides',
                     copy=True)

### Scale the tissue globaly to approach equilibrium
eptm.isotropic_relax()

A simulated tissue

Un exemple: la division cellulaire

In [5]:
### Select cell a vertex

mother_cell = eptm.graph.vertex(913)
print('The vertex {} is a cell: {}'.format(
      mother_cell, bool(eptm.is_cell_vert[mother_cell])))


### Local mask is used to work only on part of the epithelium
eptm.set_local_mask(None)
eptm.set_local_mask(mother_cell, wider=True)
fig, axes=plt.subplots(1, 2, figsize=(9, 4), sharey=True)
axes = lj.plot_2pannels(eptm,
                        cell_kwargs={'c_text':True},
                        edge_kwargs={'c':'g', 'lw':2, 'alpha':0.4},
                        axes=axes)
The vertex 913 is a cell: True
/home/guillaume/anaconda/envs/python3/lib/python3.4/site-packages/matplotlib-1.4.x-py3.4-linux-x86_64.egg/matplotlib/figure.py:1644: UserWarning: This figure includes Axes that are not compatible with tight_layout, so its results might be incorrect.
  warnings.warn("This figure includes Axes that are not "
In [6]:
septum = lj.cell_division(eptm, mother_cell, verbose=False)

### Gradient descent energy minimization (`fmin_lbfgs_b` is used)
pos0, pos1 = lj.find_energy_min(eptm)
fig, axes=plt.subplots(1, 2, figsize=(9, 4), sharey=True)
axes = lj.plot_2pannels(eptm,
                        cell_kwargs={'c_text':False},
                        edge_kwargs={'c':'g', 'lw':2, 'alpha':0.4},
                        axes=axes)
In [7]:
## Let's define a neat plotting function
def show_apopto_surroundings(eptm, a_cell, axes=None):
    eptm.set_local_mask(None)
    eptm.set_local_mask(a_cell, wider=True)
    is_apoptotic = eptm.ixs.copy()
    is_apoptotic.a[:] = 0.
    is_apoptotic[a_cell] = 1.
    ax_zs, ax_xy = lj.plot_2pannels(eptm, axes=axes,
                                    edge_kwargs={'c':'k', 'lw':0.5, 'alpha':0.5},
                                    cell_kwargs={'cell_colors':is_apoptotic,
                                                 'cmap':'Reds',
                                                 'alpha':0.8})

    eptm.set_local_mask(None)
    return ax_zs, ax_xy

On choisit une cellule apoptotique

In [8]:
fig, axes = plt.subplots(1, 2, figsize=(8, 6))

a_cell = mother_cell
eptm.set_local_mask(None)
eptm.set_local_mask(a_cell, wider=True)

ax_zs, ax_xy = show_apopto_surroundings(eptm, a_cell, axes=axes)

À 10 reprises, on diminue son volume d’équilibre, et on tire dessus avec une force radiale croissante

In [9]:
fig, axes = plt.subplots(1, 2, figsize=(8, 6))

for i in range(10):
    lj.apoptosis_step(eptm, a_cell,
                      vol_reduction=0.7, ## Reduction of equilibrium volume
                      radial_tension=0.1, ## Increase in radial force
                      contractility=1.2, ## Increase in contractility for the apoptotic cell
                      )

ax_zs, ax_xy = show_apopto_surroundings(eptm, a_cell, axes)

Lorsqu’on fait ça 30 fois, voilà ce qu’il se passe:


Fold formation model from glyg on Vimeo.

Différentes conditions

Pas de force $\Leftrightarrow$ pas de pli:

on confirme l’hypothèse de la nécessité d’un rôle actif de l’apoptose dans la morphogénèse

Reste à faire

  1. Tests unitaires & intégration continue

  2. Rendu dynamique 3D avec Blender (en cours)

  3. Gros réusinage du code:

    • description basée sur des évennements
    • optimiser (y’a du boulot…)

Et ensuite

  1. Généraliser la géométrie, surface basale
  2. Plateforme de modélisation de tissus “multi-physique”

Les biologistes du LBCMCP (CNRS/Université de Toulouse)

  • Mélanie Gettings
  • Bruno Monier
  • Sonia Shott
  • Magali Suzanne

L’autre physicien

  • Thomas Mangeat

Merci!