shampoo: Digital Holographic Microscopy in Python

shampoo is an open source Python package for digital holographic microscopy with SHAMU, the Submersible Holographic Astrobiology Microscope with Ultraresolution. At present, shampoo does holographic reconstruction, and in the near future, shampoo will support specimen detection and tracking.

Warning

This code is in development and may break without warning.

General Documentation

Installation

Requirements

Note

Users are strongly recommended to manage these dependencies with the excellent Anaconda Python Distribution which provides easy access to all of the above dependencies and more.

shampoo works on Linux, Mac OS X and Windows. It requires Python 3.5 or 2.7 (earlier versions are not supported) as well as the following packages:

pyFFTW

shampoo depends on a package called pyfftw for speedy, multithreaded Fourier transforms, which is easy to install on Mac OS X and linux but may be tricky on Windows machines. We recommend that Windows users install pyfftw by doing the following steps via conda:

conda install -c salilab fftw
pip install pyfftw

Install shampoo

You can install the latest developer version of shampoo by cloning the git repository:

git clone https://github.com/bmorris3/shampoo.git

...then installing the package with:

cd shampoo
python setup.py install

Testing

If you want to check that all the tests are running correctly with your Python configuration, start up python, and type:

import shampoo
shampoo.test()

If there are no errors, you are good to go!

More

shampoo follows Astropy‘s guidelines for affiliated packages–installation and testing for the two are quite similar! Please see Astropy’s installation page for more information.

Getting Started

Simple numerical reconstruction

shampoo comes with a sample hologram of a US Air Force resolution target to reconstruct in the data directory. Let’s reconstruct it with shampoo.

Let’s start in the shampoo repository’s top level directory. First, one must import shampoo, and specify the path to the file to reconstruct and the propagation distance:

from shampoo import Hologram
hologram_path = 'data/USAF_test.tif'
propagation_distance = 0.03685  # m

Now we will import the hologram, which is stored in TIF format, using the from_tif method:

h = Hologram.from_tif(hologram_path)

If your digital holographic microscope has different properties from SHAMU, for example, a different wavelength and pixel size, you will want to set those properties in the Hologram constructor, like this:

h = Hologram.from_tif(hologram_path, wavelength=650e-6, dx=3.5e-6, dy=3.5e-6)

The defaults are set for SHAMU’s configuration, so the defaults will work for this example hologram which was recorded by SHAMU.

Now let’s reconstruct the hologram:

wave = h.reconstruct(propagation_distance)

That’s it! The reconstructed wave is stored within wave, which is a ReconstructedWave object that stores the 2D complex ndarray reconstructed wave, plus has attributes to get the phase and intensity arrays (phase and intensity), and a plotting function plot which we will use to plot the phase and intensity from the reconstructed wave:

import matplotlib.pyplot as plt
fig, ax = wave.plot()
fig.suptitle("USAF Target")
fig.tight_layout()
plt.show()

Here’s the result:

(Source code, png, hires.png, pdf)

_images/getting_started-1.png

Now you’re ready to reconstruct your holograms!

Warning

This release should be considered a “preview”, as shampoo is still under development.

For more tutorials, see the Tutorials documentation.

Return to Top

Tutorials

We’ve put together some basic tutorials to show you how shampoo works.

If you’re looking for details about specific functions’ inputs/outputs, see instead the Reference/API.

If you have any trouble reproducing these examples, you are welcome to submit an issue on our GitHub issue tracker, or to submit a pull request with a fix, if you’re adventurous.

We currently have the following tutorials:

Reconstruction Tutorials

If you’re looking for a quick reference for beginning your first reconstruction, see Getting Started. Below we’ll dive into some more in-depth examples.

Reconstructing multiple z-planes

If you want to reconstruct several z-planes – for example, to find the propagation distance to the USAF test target – you can use the following pattern. First, we will load the raw hologram (only once):

from shampoo import Hologram
import numpy as np

hologram_path = 'data/USAF_test.tif'
h = Hologram.from_tif(hologram_path)

Next we must set the range of propagation distances to reconstruct. We will use linspace to create a linearly-spaced array of five propagation distances:

n_z_slices = 5
propagation_distances = np.linspace(0.03585, 0.03785, n_z_slices)

Then we will loop over the propagation distances, calling reconstruct for each one. We will store the reconstructed wave intensities into a data cube called intensities:

# Allocate some memory for the complex reconstructed waves
intensities = np.zeros((n_z_slices, h.hologram.shape[0], h.hologram.shape[1]),
                       dtype=np.complex128)

# Loop over all propagation distances
for i, distance in enumerate(propagation_distances):

    # Reconstruct at each distance
    wave = h.reconstruct(distance)

    # Save the result to the data cube
    intensities[i, ...] = wave.intensity

Now intensities contains all of the reconstructed wave intensities, so if we want to find the propagation distance at best focus, we could apply a very crude focus metric to the intensity arrays. For example, the standard deviation of the intensities will be maximal at the propagation distance nearest to the USAF target, so let’s plot the standard deviation of the intensities at each propagation distance:

# Measure standard deviation within each intensity image
std_intensities = np.std(intensities, axis=(1, 2))

# Initialize a figure object
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.plot(propagation_distances, std_intensities, 'o-')
ax.axvline(propagation_distances[np.argmax(std_intensities)], ls='--',
           label='Best propagation distance')
ax.set(xlabel='Propagation distance', ylabel='std( Intensity )')
ax.legend()
plt.show()

(Source code, png, hires.png, pdf)

_images/reconstruction-1.png

You can see that the best propagation distance is near the same distance that we used in the first example (that’s why we picked it!).

Return to Top

Reconstructing a cropped hologram

Sometimes you need speed. Sometimes you can afford to reconstruct only the central part the hologram’s your field of view if it will save you some time. Hologram has a built-in option to help you in this situation.

The keyword argument crop_fraction sets the fraction of the original image to crop out. By default it is set to None. If you set crop_fraction=0.5, a 1024x1024 hologram will be cropped to 512x512 before being reconstructed:

# Import package, set hologram path, propagation distance
from shampoo import Hologram
hologram_path = 'data/USAF_test.tif'
propagation_distance = 0.03685  # m

# Construct the hologram object, reconstruct the complex wave
h = Hologram.from_tif(hologram_path, crop_fraction=0.5)
wave = h.reconstruct(propagation_distance)

# Plot the reconstructed phase/intensity
import matplotlib.pyplot as plt
fig, ax = wave.plot()
fig.suptitle("USAF Target")
fig.tight_layout()
plt.show()

Since the implementations of the FFT used by shampoo generally run on order time, the cropped hologram reconstruction should compute about 2.2x faster than the full-sized one.

(Source code, png, hires.png, pdf)

_images/reconstruction-2.png

Return to Top

Reference/API

shampoo Package

Functions
cluster_focus_peaks(xyz[, eps, min_samples]) Use DBSCAN to identify single particles through multiple focus planes.
create_hdf5_archive(hdf5_path, ...[, ...]) Create HDF5 file structure for holograms and phase/intensity reconstructions.
fftshift(x[, additional_shift, axes]) Shift the zero-frequency component to the center of the spectrum, or with some additional offset from the center.
find_focus_plane(roi_cube[, focus_on, plot]) Find focus plane in a cube of reconstructed waves at different propagation distances.
glue_focus(xyz, labels) Launch a glue session with focusing results.
locate_specimens(wave_cube, positions, ...) Identify the (x, y, z) coordinates of a specimen.
open_hdf5_archive(hdf5_path) Load and return a shampoo HDF5 archive.
save_scaled_image(image, filename[, margin, ...]) Save an image to png.
test([package, test_path, args, plugins, ...]) Run the tests using py.test.
unwrap_phase(reconstructed_wave[, seed]) 2D phase unwrap a complex reconstructed wave.
Classes
FFT(shape, float_precision, complex_precision) Convenience wrapper around pyfftw.builders.fft2.
Hologram(hologram[, crop_fraction, ...]) Container for holograms and methods to reconstruct them.
ReconstructedWave(reconstructed_wave) Container for reconstructed waves and their intensity and phase arrays.
Class Inheritance Diagram

Inheritance diagram of shampoo.fftutils.FFT, shampoo.reconstruction.Hologram, shampoo.reconstruction.ReconstructedWave