Examples

2D Refocusing of an HL60 cell

The data show a live HL60 cell imaged with quadriwave lateral shearing interferometry (SID4Bio, Phasics S.A., France). The diameter of the cell is about 20µm.

_images/refocus_cell.jpg

refocus_cell.py

 1import matplotlib.pylab as plt
 2from skimage.restoration import unwrap_phase
 3import numpy as np
 4
 5import nrefocus
 6
 7from example_helper import load_cell
 8
 9# load initial cell
10cell1 = load_cell("HL60_field.zip")
11
12# refocus to two different positions
13cell2 = nrefocus.refocus(cell1, 15, 1, 1)  # forward
14cell3 = nrefocus.refocus(cell1, -15, 1, 1)  # backward
15
16# amplitude range
17vmina = np.min(np.abs(cell1))
18vmaxa = np.max(np.abs(cell1))
19ampkw = {"cmap": plt.get_cmap("gray"),
20         "vmin": vmina,
21         "vmax": vmaxa}
22
23# phase range
24cell1p = unwrap_phase(np.angle(cell1))
25cell2p = unwrap_phase(np.angle(cell2))
26cell3p = unwrap_phase(np.angle(cell3))
27vminp = np.min(cell1p)
28vmaxp = np.max(cell1p)
29phakw = {"cmap": plt.get_cmap("coolwarm"),
30         "vmin": vminp,
31         "vmax": vmaxp}
32
33# plots
34fig, axes = plt.subplots(2, 3, figsize=(8, 4.5))
35axes = axes.flatten()
36for ax in axes:
37    ax.xaxis.set_major_locator(plt.NullLocator())
38    ax.yaxis.set_major_locator(plt.NullLocator())
39
40# titles
41axes[0].set_title("focused backward")
42axes[1].set_title("original image")
43axes[2].set_title("focused forward")
44
45# data
46mapamp = axes[0].imshow(np.abs(cell3), **ampkw)
47axes[1].imshow(np.abs(cell1), **ampkw)
48axes[2].imshow(np.abs(cell2), **ampkw)
49mappha = axes[3].imshow(cell3p, **phakw)
50axes[4].imshow(cell1p, **phakw)
51axes[5].imshow(cell2p, **phakw)
52
53# colobars
54cbkwargs = {"fraction": 0.045}
55plt.colorbar(mapamp, ax=axes[0], label="amplitude [a.u.]", **cbkwargs)
56plt.colorbar(mapamp, ax=axes[1], label="amplitude [a.u.]", **cbkwargs)
57plt.colorbar(mapamp, ax=axes[2], label="amplitude [a.u.]", **cbkwargs)
58plt.colorbar(mappha, ax=axes[3], label="phase [rad]", **cbkwargs)
59plt.colorbar(mappha, ax=axes[4], label="phase [rad]", **cbkwargs)
60plt.colorbar(mappha, ax=axes[5], label="phase [rad]", **cbkwargs)
61
62plt.suptitle("Refocused cell on CPU with Numpy")
63plt.tight_layout()
64plt.show()

Compare available Metrics for Refocusing

The HL60 cell data used is described in refocus_cell.py.

_images/compare_metrics.png

compare_metrics.py

 1import nrefocus
 2from nrefocus.metrics import METRICS
 3import matplotlib.pyplot as plt
 4
 5from examples.example_helper import load_cell
 6
 7nrefocus.set_ndarray_backend("cupy")
 8
 9dataset = load_cell("HL60_field.zip")
10
11# load initial cell and create rf object
12rf = nrefocus.iface.RefocusCupy(field=dataset,
13                                wavelength=647e-9,
14                                pixel_size=0.139e-6,
15                                kernel="helmholtz")
16
17# autofocus the image for each metric
18my_metrics = list(METRICS.keys())
19
20fig, axes = plt.subplots(1, len(my_metrics), figsize=(12, 5))
21
22for i, mt in enumerate(my_metrics):
23    af_vals = rf.autofocus(metric=mt,
24                           minimizer="legacy",
25                           interval=(-5e-6, 5e-6),
26                           ret_field=True,
27                           ret_grid=True)
28    d, grid, field = af_vals
29    d = d.get()
30    field = field.get()
31    grid_0 = grid[0].get()
32    grid_1 = grid[1].get()
33
34    axes[i].plot(grid_0, grid_1)
35    axes[i].axvline(d, color='k', ls='--')
36    axes[i].set_title(f"Metric {mt}")
37
38fig.suptitle("Comparison of Metrics")
39fig.tight_layout()
40plt.show()

Refocus a stack of 2D fields (3D array input).

This example shows how to refocus a stack shaped (n, y, x). nrefocus interprets the last two axes as spatial axes and broadcasts over any leading “batch” axes.

refocus_stack.py

 1import numpy as np
 2
 3import nrefocus
 4
 5rng = np.random.default_rng(0)
 6
 7# Synthetic complex field stack: (n, y, x)
 8n, ny, nx = 5, 128, 96
 9amp = 1 + 0.1 * rng.normal(size=(n, ny, nx))
10pha = 0.3 * rng.normal(size=(n, ny, nx))
11field = amp * np.exp(1j * pha)
12
13pixel_size = 1e-6
14dist = 2.13 * pixel_size
15
16# CPU (NumPy) refocus of the entire stack in one call
17rf = nrefocus.RefocusNumpy(
18    field=field,
19    wavelength=8.25 * pixel_size,
20    pixel_size=pixel_size,
21    medium_index=1.533,
22    distance=0,
23    kernel="helmholtz",
24    padding=True,
25)
26refocused = rf.propagate(distance=dist)
27print("nrefocus now accepts stacks of 2D arrays (3D input)!\n"
28      "Input shape:", field.shape, "| Output shape-> ", refocused.shape)