What is the package “ggf” used for?

It is a Python implementation of two Matlab scripts by Lars Boyde, StretcherNStress.m and GGF.m, which are used in the Guck lab to compute optical stress distributions and resulting global geometric factors for spherical and spheroidal objects in the optical stretcher.

What is an optical stretcher?

The optical stretcher consists of a dual beam laser trap, in its original configuration built from two opposing optical fibers [GAM+01]. When increasing the trapping power, compliant objects such as cells are stretched along the axis of the trap. Using video analysis, the measured shape change can be translated into physical properties of the cell.

What is the global geometric factor?

The global geometric factor (GGF) connects (the unknown variable) compliance \(J\) (how easy it is to deform a body consisting of a certain material) and (the measured variable) strain \(\epsilon\) (how much this body is deformed). Thus, the GGF is a measure of stress (force acting on the surface of the body).

\[J = \frac{\epsilon}{\text{GGF}}\]

In an optical stretcher (OS) experiment, the strain \(\epsilon\) of a cell can be measured by analyzing its deformation (e.g. via a contour in the intensity image). Using cell size and the measured change in eccentricity, as well as several parameters of the OS setup itself, ggf can be used to compute the optical stress \(\sigma\) from which the GGF is computed.

How should I migrate my Matlab pipeline to Python?

To reproduce data

You can access the computations performed in StretcherNStress.m via ggf.stress.boyde2009.core.stress().


There was a mistake in the original boundary function (see issue #1). This affects all cases where poisson_ratio is non-zero. If you would like to reproduce exactly the stress profiles of StretcherNStress.m, please use ggf version 0.2.0.

from ggf.stress.boyde2009.core import stress
theta, sigma, coeff = stress(object_index=1.41,
                             semi_minor=2.8466e-6,   # [m]
                             wavelength=780e-9,      # [m]
                             beam_waist=3.08,        # [wavelengths]
                             power_left=.65,         # [W]
                             power_right=.65,        # [W]
                             dist=180e-6,            # [m]

The GGF can be computed from the coefficients coeff via ggf.legendre2ggf().

from ggf import legendre2ggf
GGF = legendre2ggf(coeff, poisson_ratio=.45)

These methods produce the same output as the original Matlab scripts with an accuracy that is below the standard tolerance of numpy.allclose().

For a new project

In general, the method ggf.get_ggf() is recommended. The difference to the above method is:

  • It makes use of precomputed look-up tables (LUTs) which avoids long computation times. The error made by using LUTs maxes at about 1-2%.
  • It comes with user-convenient keyword arguments.
  • The GGF is computed from 120 Legendre coefficients by default, a number that was previously determined automatically and could have potentially been too low.

Please note that due to these points, the resulting GGF might vary from the GGF computed with the original Matlab script.

import ggf
GGF = ggf.get_ggf(model="boyde2009",
                  semi_major=3.2788e-6,             # [m]
                  semi_minor=2.8466e-6,             # [m]
                  effective_fiber_distance=180e-6,  # [m]
                  mode_field_diameter=4.8e-06,      # [m]
                  power_per_fiber=.65,              # [W]
                  wavelength=780e-9,                # [m]