Bench Schematic & Beam Path
The setup uses a single-laser source split into three arms. Each arm independently encodes one LG superposition mode component on a phase SLM. A q-plate in arm C applies spin-orbit coupling. All three beams recombine at a non-polarizing beamsplitter cube before the observation volume.
Hopfion Field Construction
A photonic Hopfion is realized as a specific superposition of structured modes whose combined electromagnetic field reproduces the Hopf fibration: a map from S³ → S² where every fiber is a circle and any two distinct fibers are linked exactly once.
Target Field
The coefficients α, β, γ set the relative weights. For a canonical Hopfion, α = β = 1/√2 and γ encodes the "linking radius." The q-plate in Arm C converts the radial LG(0,1) mode's polarization, generating the out-of-plane polarization texture needed for the full 3D linkage.
Mode Superposition Table
| Arm | Mode LG(p,ℓ) | Polarization | Phase offset | Weight | Physical role |
|---|---|---|---|---|---|
| A | LG(0, +1) | σ⁺ (R-circ) | φ₀ = 0 | 1/√2 | Primary vortex / +z topology |
| B | LG(0, −1) | σ⁻ (L-circ) | φ₀ = 0 | 1/√2 | Counter-vortex / −z topology |
| C | LG(1, 0) | x-lin → SAM-OAM | φ₀ = π/2 | γ (tunable) | Radial node / linking structure |
The π/2 phase offset on Arm C is set via SLM-C global phase or an additional tiltable glass plate in the beam path. Tuning γ sweeps the Hopfion between a "tight" knot (γ → 0) and a more extended linked-ring topology.
Phase Mask Encoding
Each SLM arm displays a forked grating hologram that diffracts the incident Gaussian beam into the target LG mode in the first diffraction order. A blazed carrier grating separates the desired order from undiffracted light; a spatial filter (iris at a Fourier-plane lens) then selects only the first order.
Live-rendered phase masks (canvas). Color = phase 0–2π. Forked gratings visible in A/B; radial Laguerre structure in C.
# hopfion_slm.py — Phase mask generation for Hopfion SLMs
import numpy as np
import matplotlib.pyplot as plt
from scipy.special import genlaguerre
# ── SLM resolution (pixels) ──────────────────────────────
Nx, Ny = 1024, 768 # adjust to your SLM
x = np.linspace(-1, 1, Nx)
y = np.linspace(-1, 1, Ny)
X, Y = np.meshgrid(x, y)
R = np.sqrt(X**2 + Y**2)
Phi = np.arctan2(Y, X)
def lg_phase_mask(ell, p, carrier_freq=20, w0=0.4, global_phase=0.0):
"""
Forked grating hologram for LG(p, ell) mode.
carrier_freq: spatial frequency of blazed grating (cycles/aperture)
w0 : beam waist fraction of aperture
"""
r = R / w0
# Laguerre polynomial L_p^|ell|(2r²)
Lpl = genlaguerre(p, abs(ell))
amp = (r ** abs(ell)) * np.exp(-r**2) * Lpl(2 * r**2)
amp /= np.max(np.abs(amp) + 1e-9)
# complex field of the LG mode
field = amp * np.exp(1j * ell * Phi) * np.exp(1j * global_phase)
# blazed carrier grating
carrier = np.exp(1j * 2 * np.pi * carrier_freq * X)
# interference hologram phase
ref = np.ones_like(field) # plane-wave reference
hologram = field * carrier + ref
phase_mask = np.angle(hologram) # −π to π
return ((phase_mask + np.pi) / (2 * np.pi) * 255).astype(np.uint8)
# ── Generate and save ────────────────────────────────────
mask_A = lg_phase_mask(ell=+1, p=0, carrier_freq=20, global_phase=0.0)
mask_B = lg_phase_mask(ell=-1, p=0, carrier_freq=20, global_phase=0.0)
mask_C = lg_phase_mask(ell=0, p=1, carrier_freq=20, global_phase=np.pi/2)
for name, mask in zip(['slm_A', 'slm_B', 'slm_C'],
[mask_A, mask_B, mask_C]):
plt.imsave(f'{name}.png', mask, cmap='hsv')
print(f'{name} saved')
# ── Simulation: propagate and check field ────────────────
from LightPipes import *
size, wl = 10e-3, 532e-9 # 10 mm aperture, 532 nm
F = Begin(size, wl, Nx)
F = GaussBeam(F, w0=2e-3)
# Apply LG(0,+1) vortex phase
F = Tilt(F, carrier_freq * 2 * np.pi / size, 0)
F = PhaseMap(F, mask_A / 255 * 2 * np.pi)
F = Lens(F, f=0.15) # 150 mm focusing lens
F = Propagate(F, 0.15) # propagate to focus
intensity = Intensity(F)
plt.imshow(intensity); plt.colorbar(); plt.show()
Off-the-Shelf Component List
Power: 50–100 mW CW
Coherence length: > 1 m (single-mode)
Example: Coherent COMPASS 315M or Oxxius LCX-532
Green chosen for SLM efficiency & camera QE. Single-mode spatial profile essential — multi-mode lasers cannot form clean LG modes.
Resolution: ≥ 1024×768 px
Phase range: 0–2π at 532 nm
Examples: Holoeye PLUTO-2, Meadowlark 1024, Hamamatsu X13138
One per arm. Phase-only is sufficient; amplitude is encoded via grating efficiency. Minimum 8-bit phase depth per pixel.
Retardation: Tunable, λ/2 target
Activation: AC voltage ~2–5 V rms
Example: Arcoptix q-plate kit, or custom LC cell
Converts Arm C's LG(1,0) beam, imparting spin-orbit coupling to produce the cylindrical vector beam component needed for 3D polarization texture.
Size: 25 mm cube
AR coating: 530–560 nm
Example: Thorlabs BS013, Edmund 47-052
Non-polarizing critical — PBSC would corrupt the polarization states of each arm during combination.
Clear aperture: ≥ 12.7 mm
Retardation: λ/2 ± λ/300
Example: Thorlabs WPH05ME-532
Placed in Arms A and B to rotate linear polarization before QWP, enabling σ⁺ and σ⁻ circular states. Mount on a precision rotation stage (±0.1° resolution).
Retardation: λ/4 ± λ/300
Example: Thorlabs WPQ05ME-532
After HWP in Arms A and B, converts to circular polarization. HWP fast axis at 45° → QWP fast axis at 0° gives σ⁺. Mirror for σ⁻.
Diameter: 25.4 mm
Coating: VIS (400–700 nm)
Example: Thorlabs AC254 series
Relay lenses between SLM and combination BS maintain beam size and spatial mode fidelity. Final L1 (f=150 mm) focuses the combined beam into the observation volume.
Pixel size: ≤ 6.5 µm
Frame rate: ≥ 50 fps
Example: Andor Zyla, PCO.edge, Thorlabs CS2100M-USB
Mounted on a motorized z-translation stage for axial scanning. Acquires a stack of 2D intensity slices; software reconstructs the 3D field.
Step size: ≤ 1 µm
Example: Thorlabs Z825B + BSC201 controller
Carries the camera through the observation volume for volumetric reconstruction. Alternatively, scan the object plane with a remote focusing module.
Irises: SM1 threaded, ×4 (spatial filters)
Mounts: Thorlabs KM100, post/rod system
Table: Optical breadboard 60×120 cm, M6 holes
Isolator: Faraday isolator at laser output
Faraday isolator prevents backreflection into the laser cavity — mandatory for single-mode DPSS sources.
Step-by-Step Assembly Protocol
Characterizing the 3D Topological Structure
Directly imaging a Hopfion requires either volumetric intensity maps, polarimetric Stokes parameter reconstruction, or optical scattering from a thin medium. Multiple methods should be combined for complete characterization.
Reconstruction Python Sketch
import numpy as np
import napari
from skimage import measure
import tifffile
# Load z-stack (z, y, x) acquired from camera scan
stack = tifffile.imread('hopfion_zstack.tif') # shape (Nz, Ny, Nx)
stack = stack / stack.max()
# Isosurface at 40% intensity
verts, faces, normals, vals = measure.marching_cubes(
stack, level=0.40, spacing=(5e-6, 2e-6, 2e-6)) # z,y,x pixel sizes
# Visualize in napari
viewer = napari.Viewer()
viewer.add_image(stack, name='Intensity', colormap='magma')
viewer.add_surface((verts, faces), name='Hopfion isosurface')
# Phase vortex detection at each z-slice
def find_vortices(field_slice):
"""Returns (x,y) coordinates of phase singularities."""
phase = np.angle(field_slice)
# winding number via finite-difference around each pixel
dx = np.diff(phase, axis=1, append=phase[:, :1])
dy = np.diff(phase, axis=0, append=phase[:1, :])
dx = (dx + np.pi) % (2*np.pi) - np.pi
dy = (dy + np.pi) % (2*np.pi) - np.pi
winding = dx + np.roll(dy,-1,axis=1) - np.roll(dx,-1,axis=0) - dy
vortex_mask = np.abs(winding) > 0.9
return np.argwhere(vortex_mask)
# Compute Gauss linking number between two vortex loops
# (see Moffatt 1969 or Dennis et al. 2010 for implementation)
# linking_number(loop_A, loop_B) should return ±1 for a valid Hopfion
Animated Hopf Fibration — Reference Visualization
Animated canvas showing the Hopf fibration fiber circles — two representative fibers (blue and orange) that are mutually linked exactly once. This is the topological structure being generated in the optical field.
Blue loop and orange loop are topologically linked (linking number = 1). Every pair of distinct fibers in the Hopfion shares this relationship.