Classic TFM (liver fibroblasts)

This example evaluates three hepatic stellate cells in 1.2mg/ml collagen with relaxed and deformed stacks. The relaxed stacks were recorded with cytochalasin D treatment of the cells. This example can also be evaluated with the graphical user interface.

../../_images/liver_fibroblasts.png
15 import saenopy

Downloading the example data files

The folder structure is as follows. There are three cells recorded at different positions in the gel (Pos004, Pos007, Pos008) and three channels (ch00, ch01, ch02). The stack has 376 z positions (z000-z375). All positions are recorded once in the active state (“Deformed”) and once after relaxation with Cyto D as the reference state (“Relaxed”).

1_ClassicSingleCellTFM
├── Deformed
│   └── Mark_and_Find_001
│       ├── Pos004_S001_z000_ch00.tif
│       ├── Pos004_S001_z000_ch01.tif
│       ├── Pos004_S001_z000_ch02.tif
│       ├── Pos004_S001_z001_ch02.tif
│       ├── ...
│       ├── Pos007_S001_z001_ch00.tif
│       ├── ...
│       ├── Pos008_S001_z001_ch02.tif
│       └── ...
└── Relaxed
    └── Mark_and_Find_001
        ├── Pos004_S001_z000_ch00.tif
        ├── Pos004_S001_z000_ch01.tif
        ├── Pos004_S001_z000_ch02.tif
        ├── Pos004_S001_z001_ch02.tif
        ├── ...
        ├── Pos007_S001_z001_ch00.tif
        ├── ...
        ├── Pos008_S001_z001_ch02.tif
        └── ...
53 # download the data
54 saenopy.load_example("ClassicSingleCellTFM")

Loading the Stacks

Saenopy is very flexible in loading stacks from any filename structure. Here we replace the number in the position “Pos004” with an asterisk “Pos*” to batch process all positions. We replace the number of the channels “ch00” with a channel placeholder “ch{c:00}” to indicate that this refers to the channels and which channel to use as the first channel where the deformations should be detected. We replace the number of the z slice “z000” with a z placeholder “z{z}” to indicate that this number refers to the z slice. We do the same for the deformed state and for the reference stack.

67 # load the relaxed and the contracted stack
68 # {z} is the placeholder for the z stack
69 # {c} is the placeholder for the channels
70 # {t} is the placeholder for the time points
71 results = saenopy.get_stacks(
72     '1_ClassicSingleCellTFM/Deformed/Mark_and_Find_001/Pos*_S001_z{z}_ch{c:00}.tif',
73     reference_stack='1_ClassicSingleCellTFM/Relaxed/Mark_and_Find_001/Pos*_S001_z{z}_ch{c:00}.tif',
74     output_path='1_ClassicSingleCellTFM/example_output',
75     voxel_size=[0.7211, 0.7211, 0.988])

Detecting the Deformations

Saenopy uses 3D Particle Image Velocimetry (PIV) with the following parameters to calculate matrix deformations between a deformed and relaxed state for three example cells.

Piv Parameter

Value

element_size

14

window_size

35

signal_to_noise

1.3

drift_correction

True

 97 # define the parameters for the piv deformation detection
 98 piv_parameters = {'element_size': 14.0, 'window_size': 35.0, 'signal_to_noise': 1.3, 'drift_correction': True}
 99
100 # iterate over all the results objects
101 for result in results:
102     # set the parameters
103     result.piv_parameters = piv_parameters
104     # get count
105     count = len(result.stacks)
106     if result.stack_reference is None:
107         count -= 1
108     # iterate over all stack pairs
109     for i in range(count):
110         # get two consecutive stacks
111         if result.stack_reference is None:
112             stack1, stack2 = result.stacks[i], result.stacks[i + 1]
113         # or reference stack and one from the list
114         else:
115             stack1, stack2 = result.stack_reference, result.stacks[i]
116         # and calculate the displacement between them
117         result.mesh_piv[i] = saenopy.get_displacements_from_stacks(stack1, stack2,
118                                                                    piv_parameters["window_size"],
119                                                                    piv_parameters["element_size"],
120                                                                    piv_parameters["signal_to_noise"],
121                                                                    piv_parameters["drift_correction"])
122     # save the displacements
123     result.save()

Generating the Finite Element Mesh

Interpolate the found deformations onto a new mesh which will be used for the regularisation. We use identical element size of deformation detection mesh here and keep the overall mesh size the same.

Mesh Parameter

Value

element_size

14

mesh_size

‘piv’

reference_stack

‘first’

142 # define the parameters to generate the solver mesh and interpolate the piv mesh onto it
143 mesh_parameters = {'reference_stack': 'first', 'element_size': 14.0, 'mesh_size': 'piv'}
144
145
146 # iterate over all the results objects
147 for result in results:
148     # correct for the reference state
149     displacement_list = saenopy.subtract_reference_state(result.mesh_piv, mesh_parameters["reference_stack"])
150     # set the parameters
151     result.mesh_parameters = mesh_parameters
152     # iterate over all stack pairs
153     for i in range(len(result.mesh_piv)):
154         # and create the interpolated solver mesh
155         result.solvers[i] = saenopy.interpolate_mesh(result.mesh_piv[i], displacement_list[i], mesh_parameters)
156     # save the meshes
157     result.save()

Calculating the Forces

Define the material model and run the regularisation to fit the measured deformations and get the forces.

Material Parameter

Value

k

6062

d_0

0.0025

lambda_s

0.0804

d_s

0.034

Regularisation Parameter

Value

alpha

10**10

step_size

0.33

max_iterations

400

rel_conv_crit

0.009

189 # define the parameters to generate the solver mesh and interpolate the piv mesh onto it
190 material_parameters = {'k': 6062.0, 'd_0': 0.0025, 'lambda_s': 0.0804, 'd_s':  0.03}
191 solve_parameters = {'alpha': 10**10, 'step_size': 0.33, 'max_iterations': 400, 'rel_conv_crit': 0.009}
192
193 # iterate over all the results objects
194 for result in results:
195     result.material_parameters = material_parameters
196     result.solve_parameters = solve_parameters
197     for M in result.solvers:
198         # set the material model
199         M.set_material_model(saenopy.materials.SemiAffineFiberMaterial(
200             material_parameters["k"],
201             material_parameters["d_0"],
202             material_parameters["lambda_s"],
203             material_parameters["d_s"],
204         ))
205         # find the regularized force solution
206         M.solve_regularized(alpha=solve_parameters["alpha"], step_size=solve_parameters["step_size"],
207                             max_iterations=solve_parameters["max_iterations"],
208                             rel_conv_crit=solve_parameters["rel_conv_crit"], verbose=True)
209     # save the forces
210     result.save()

Display Results

../../_images/liver_fibroblast_workflow.png

The reconstructed force field (right) generates a reconstructed deformation field (middle) that recapitulates the measured matrix deformation field (left). The overall cell contractility is calculated as all forcecomponents pointing to the force epicenter.

Gallery generated by Sphinx-Gallery