Structured Light / Topological Optics — Lab Reference

DIY Photonic Hopfion
Setup

Complete optical bench design for generating a 3D electromagnetic Hopfion via superposed Laguerre-Gaussian modes, spatial light modulation, and interferometric beam combination — targeted at a sophisticated home optics bench.

Hopf Fibration ℝ³ Phase SLM DIY Bench

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.

LASER 532 nm CW 50–100 mW BS₀ 50:50 M-A1 SLM ARM-A ℓ=+1, p=0 HWP σ⁺ SLM ARM-B ℓ=−1, p=0 HWP σ⁻ M-C1 SLM ARM-C ℓ=0, p=1 q-plate q=1/2 BS₁ A+C BS₂ +B L1 f=150mm OBS. VOL. CCD scan ARM A — LG(+1,0) σ⁺ ARM B — LG(−1,0) σ⁻ ARM C — LG(0,1) + q-plate ≈ 30 cm

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

E(r) = α · LG0,+1(r) êσ⁺ + β · LG0,−1(r) êσ⁻ + γ · LG1,0(r) êx total field
LGp,ℓ(r,φ,z) = C · (r/w)|ℓ| · exp(−r²/w²) · Lp|ℓ|(2r²/w²) · exp(iℓφ) · exp(ikz) LG mode
Hopf index: H = (1/4π²) ∫ FF = 1 topological charge

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.

SLM-A — LG(0,+1) forked grating
SLM-B — LG(0,−1) forked grating
SLM-C — LG(1,0) radial + carrier
SLM-A+B combined (reference)
# 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()
1
SLM plane-wave alignment
Display a flat phase (gray = 128) on all SLMs. Use a shear-plate interferometer or a reference mirror to verify the wavefront is flat. Tilt/piston the SLM until fringes are vertical and equally spaced. Residual wavefront error < λ/10 RMS is the target.
2
Carrier grating calibration
Display a pure blazed grating (carrier only). Place a lens (f = 150 mm) and CCD at the focal plane. Confirm the first-order spot position matches prediction. Translate an iris to select only the +1 order. Diffraction efficiency should exceed 40%.
3
LG donut verification (Arm A & B)
Apply SLM-A mask. The first-order beam at the CCD should show a hollow donut with a dark center. Interfere with a co-propagating plane wave (flip to a reference arm briefly) and count ℓ = ±1 spiral fringes to confirm topological charge sign.
4
q-plate tuning (Arm C)
The LC q-plate requires a specific applied voltage to satisfy the half-wave retardation condition (Δ = π). Sweep voltage while monitoring output polarization with a Stokes polarimeter or quarter-wave + PBS combination. At the correct voltage, linearly polarized input converts to a cylindrical vector beam (doughnut intensity, radial polarization).
5
Interferometric phase locking
Relative phase drift between arms will wash out the Hopfion topology. Either: (a) use a common-path design where all three arms share the same table vibrations and a reference CCD monitors relative fringe phase for active correction, or (b) use short integration times (< 1 ms) with a fast camera. An electro-optic phase modulator in one arm gives active locking to < λ/50 jitter.
6
Polarization balance check
Before combining, verify each arm's polarization state with a polarimeter. Arm A → σ⁺, Arm B → σ⁻, Arm C → linear x (post q-plate output will have the desired cylindrical polarization). Correct with QWP/HWP rotation if needed.

Off-the-Shelf Component List

SRC-01
CW Laser Source
Wavelength: 532 nm (green DPSS)
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.
SLM-01/02/03
Phase-Only SLMs (×3)
Type: Reflective LCOS, phase-only
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.
QP-01
Liquid Crystal q-plate
Topological charge: q = 1/2
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.
BS-01/02/03
Non-Polarizing Beamsplitters
Type: NPBS cube, R:T = 50:50
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.
HWP-01/02
Zero-Order HWP (×2)
Wavelength: 532 nm
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).
QWP-01/02
Zero-Order QWP (×2)
Wavelength: 532 nm
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 σ⁻.
L-01/02/03
Achromatic Doublets
Focal lengths: f = 75 mm, 150 mm, 200 mm
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.
CAM-01
Scientific CMOS Camera
Sensor: sCMOS, ≥ 5.5 MP
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.
STG-01
Z-Translation Stage (Motorized)
Travel: ≥ 25 mm
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.
OPT-MISC
Miscellaneous Optics
Mirrors: Protected silver λ/10, ×6
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

01
Laser & Isolation
Mount laser on two-axis kinematic base. Insert Faraday isolator (OD ≥ 30 dB) immediately after laser aperture. Expand beam ×3 with a spatial filter pinhole (15 µm, f=10 mm + f=30 mm lenses) to clean spatial mode and set beam diameter to ~6 mm. Verify TEM₀₀ with beam profiler.
02
3-Way Split
At BS₀, split into three arms. Use half-wave plate before BS₀ to control splitting ratio. Route Arm A upward with a mirror, Arm B straight, Arm C downward with a mirror. Adjust mirror angles so all three arms are co-parallel with the optical table plane. Check heights with a ruler — all beam centers should be at the same height ± 0.5 mm.
03
SLM Alignment (each arm)
Mount SLM at ~10° angle of incidence to avoid retroreflection. Display flat phase map (gray=128). Place a 50:50 BS after the SLM and a reference mirror in one port to build a Michelson. Adjust SLM tip/tilt until interference fringes are straight. Remove reference arm when flat-phase condition confirmed. Repeat for all three SLMs independently.
04
Mode Generation & Spatial Filtering
Load each SLM with its forked grating hologram. Place a lens (f=150 mm) after each SLM and an iris at its focal plane to select only the +1 diffraction order. Translate the iris while monitoring a downstream CCD — the donut (LG modes) or ring (LG(1,0)) should be isolated. Confirm mode order by interference with a plane wave.
05
Polarization State Setting
Arm A: insert HWP (fast axis 22.5°) then QWP (fast axis 0°) → σ⁺ circular. Arm B: insert HWP (fast axis −22.5°) then QWP (fast axis 0°) → σ⁻ circular. Arm C: apply q-plate at optimal voltage, confirm cylindrical vector beam output with rotating linear polarizer + CCD (should produce 4-lobe pattern). Verify each with a Stokes polarimeter before combining.
06
Beam Combination
Combine Arms A and C at BS₁ (50:50 NPBS). Then combine the (A+C) output with Arm B at BS₂. Use relay lenses before each BS to ensure all three beam profiles are size-matched (same w₀ at the combining planes) and co-focal. Check far-field interference fringes at BS₂ output to confirm co-alignment. Adjust tip/tilt of final relay mirrors to remove residual angle.
07
Phase Locking
Insert a camera at an intermediate plane and monitor the fringe pattern between any two arms. For passive stability: mount everything on a rigid breadboard on vibration-damping pads, use short arm lengths (< 40 cm), and shield from airflow. For active locking: feedback an EO modulator in Arm C using a dithering signal on the SLM global phase and a lock-in amplifier on a reference fringe. Aim for < λ/20 phase noise over 10-minute exposures.
08
Observation Volume & Volumetric Scan
Focus the combined beam with L1 (f=150 mm). Mount camera on z-stage; step through the observation volume in 5 µm increments over ±2 mm. At each z-plane, record intensity image. Use Python/MATLAB to reconstruct the 3D intensity stack. For polarization-resolved imaging, insert a rotating QWP + fixed linear polarizer before the camera and record Stokes parameters at each z-plane.

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.

📷
z-Scan Intensity Stack
Step camera in z; reconstruct I(x,y,z). Isosurface at ~50% max intensity reveals the donut topology. Cheap and direct — standard lab capability. Requires mechanical repeatability < 1 µm per step.
🔵
Stokes Tomography
Measure S₀, S₁, S₂, S₃ at each z-plane via rotating QWP + linear polarizer. Reconstruct full polarization texture. The Hopf index can be computed from curl of the Stokes field: H = ∫ F∧F. Gold-standard method for confirming topology.
💡
Fluorescent Medium Scattering
Fill a cuvette with dilute fluorescent dye (rhodamine B at 10⁻⁵ M) or polystyrene microsphere suspension. Image scattered light side-on with a macro lens. Reveals 3D beam intensity structure in one shot. Best for quick qualitative confirmation before quantitative scan.
🌊
Phase Singularity Mapping
Interfere the observation volume output with a reference plane wave (from a fourth BS tap at the laser). At each z, interference fringes reveal phase vortex positions (dislocations). Tracking vortex lines in 3D confirms the linked-loop topology characteristic of the Hopfion.
🖥️
3D Rendering (Python)
Load z-stack into Python (numpy + matplotlib or napari). Compute isosurfaces with marching cubes (scikit-image). Render 3D volume with mayavi or plotly. Overlay Stokes vectors as arrow glyphs on the isosurface. Export to interactive HTML for sharing.
🔗
Linking Number Calculation
From the phase singularity vortex line data, compute the Gauss linking integral numerically between any two extracted loops. A result of ±1 confirms the Hopfion topology. This is the definitive topological verification step.

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.