faser

Playground (browser)

Generate, compare and image with PSFs directly on this website, no installation needed.

The faser simulator is compiled to WebAssembly, so the full vectorial model runs in your browser. Open the Playground to try it.

Everything is computed on your machine; nothing is uploaded. The grid is sized automatically for an accurate result; a fast preview keeps the page responsive while you explore.

The microscope

The playground is built around a 3D model of the setup that follows the parameters live. Every part of it is clickable: click the objective, the coverslip, the sample, the focus, the back pupil, or any element of the illumination arm (laser, polarization optics, phase plate, spatial light modulator) and its parameters unfold in the settings card on the right: an accordion with one section per part (the same sections open when you click them). The card can be hidden with the floating button; on small screens it is a full-screen card behind the Settings button, which opens by itself when you tap a part. Drag to move along the axis, shift + drag to rotate, scroll to zoom. The Microscope / PSF toggle above the scene switches between the microscope with its zoom-in and the PSF on its own, large.

  • Laser: wavelength and the Gaussian beam profile on the pupil.
  • Polarization: elliptical (direction and ellipticity), radial or azimuthal input.
  • Phase plate: the analytic masks (vortex, π disc, incoherent donut + bottle mix) with their offsets.
  • Spatial light modulator: see below.
  • Objective: NA, immersion index, correction collar and focal length.
  • Back pupil & aberrations: Zernike modes. The disc on top of the objective shows the pupil as the simulator sees it: brightness is amplitude, hue is phase (phase plate, SLM and aberrations combined), with the polarization drawn on top.
  • Coverslip: thickness, index and tilt.
  • Sample: index, imaging depth and what sits at the focus (a bead, or a sample to image; see below). Index mismatch shifts the focus; the nominal focus is drawn as a wire sphere.
  • Cranial window: an optional skull opening on the coverslip that clips the focusing cone.
  • Focus & sampling: the observation volume, normalization and the simulation grid.

Optional elements (the phase plate, the SLM, the cranial window and the coverslip) are only drawn when they are part of the setup; their sections start with an "in the beam path" / "in the setup" toggle, and opening a section of an absent element shows a ghost outline of where it would go.

Accuracy without tuning

The simulation grid is sized automatically from the optics, so you do not have to touch Nxy, Nz, Ntheta or Nphi:

  • the lateral voxel is a fifth of λ / (2 NA), the axial one follows the axial band limit;
  • the number of φ nodes lies above the highest azimuthal harmonic present at the corner of the field (plus the vortex charge), so the trapezoid rule is exact and no aliased ghost foci fall inside the volume;
  • the number of θ nodes follows the fastest phase variation of the integrand (lateral and axial plane-wave terms, coverslip / depth aberration, Zernike modes) at eight points per 2π.

While you drag a slider a quarter-size preview is computed immediately; the accurate volume follows a third of a second after the parameters settle (a status chip shows which one you are looking at). If the accurate volume would take more than a few seconds, live updates stay in preview mode and Generate computes it on demand. The "Focus & sampling" inspector shows the resolved grid and the estimated time, and lets you switch to manual values.

The θ quadrature is adaptive by default: when the aperture reaches past the critical angle of the sample (an oil objective imaging into water, say), the axial phase has a square-root singularity at the critical angle and a uniform rule converges poorly. The adaptive rule integrates the sub-critical part over cos θ₃ instead, where that phase is linear; it is identical to the uniform rule whenever there is no critical angle inside the aperture. The same option exists in the Python model (Theta_sampling) and the CLI (--theta_sampling ADAPTIVE); the default there stays UNIFORM to match the numpy reference implementation exactly.

Spatial light modulator

The illumination arm carries an SLM conjugate to the back pupil. Enable it in its inspector and choose a pattern: a vortex (charge m), a π disc (bottle), a half-moon, a blazed grating (steers the focus by λ / (period · sin α)), an axicon (a ring focus), or your own image (gray → phase). The panel is a real device: choose the resolution (32² to 512² pixels), the number of phase levels (continuous, 8-bit, …, binary), the fill factor (the dead space between pixels passes unmodulated light into the focus, the "zeroth order"), the panel size relative to the pupil and its misalignment. The panel in the 3D scene shows the pattern as the device displays it (wrapped, quantized), and the back pupil shows its effect combined with the phase plate and the aberrations.

The SLM multiplies the pupil on top of the phase plate, so it can replace the plate (set the plate to "None" or "pattern on the SLM") or add to it.

Zernike layer (adaptive optics). The SLM designer has the same twelve Zernike modes as the "Back pupil & aberrations" card. They are added to the pattern before wrapping and quantization, so the SLM can carry a vortex and a wavefront correction at once, like a real AO hologram. On the aberration card, Display on the SLM moves the system coefficients onto the layer (and clears them), Correct on the SLM puts their negative on the layer while the system aberration stays. Both act in the same pupil plane as the simulator's own Zernike phase, so on an ideal panel the two are indistinguishable (max PSF difference below 10⁻³ for a12 = 0.8); what a real panel adds is exactly its device effects: pixel sampling, phase levels (an 8‑bit, 93 % fill‑factor panel leaves a residual of about 1 % of the peak) and dead‑space leakage. The aberration offsets are not transferred. The layer is baked into the SLM.phase block of the config file; a loaded config shows it as a loaded pattern with an empty layer. The pattern is saved in psf_config.json as an SLM block (n, phase, extent, levels, fill_factor, offsets) that the Python model (PSFConfig.SLM, SLMConfig.from_array) and the native backend read; Mode = LOADED with a loaded_phase_mask array is handled the same way.

The PSF in the scene

A fluorescent bead sits at the focus; its PSF is ray-marched right there, inside the microscope, drawn over the optics so it stays visible. With the camera arm switched on (gear menu), a dichroic above the back pupil folds the emission to a camera whose image plane shows what is recorded. The PSF view (bottom-left pill) shows the volume large, with the XY and XZ cross-sections and the display options (maximum intensity projection or emission-absorption compositing, colormap, linear or logarithmic scaling). The derived quantities (angles, effective NA, focus shift, voxel sizes, grid) are the last section of the settings card.

What is at the focus

The Sample card decides what the microscope images:

  • A fluorescent bead (default): its image is the PSF shown in the zoom-in.
  • A sample, imaged through the PSF: a synthetic ground truth (random beads, filaments, cells with a nucleus, a point lattice, a Siemens star) or your own image (a PNG / JPG whose brightness is fluorescence, painted into a thin slab at the focal plane). The ground truth is drawn faintly at the focus of the microscope with its image over it: the sample convolved with the current PSF (3-D FFT convolution in the browser, on the PSF's voxel grid), optionally with Poisson shot noise for a chosen number of photons in the brightest voxel. Only the settings that matter for the chosen sample are shown; the field of view is given in voxels of the PSF grid. In the PSF view a toggle switches between the image and the PSF.

Scenes

The scene picker sits at the top of the settings card. It lists the built-in presets with a description each, and the scenes you saved in this browser. As soon as you change something the picker reads "edited" and a Save button appears: it stores the whole setup (parameters, SLM design, sample settings, grid mode) under a name in local storage, so it survives reloads; entries can be reloaded or deleted from the menu. The controls floating over the renderer hold the Microscope / PSF toggle, the view options behind the gear (the camera image plane, off by default; permanent labels; the highlight of the selected part), Live and Generate, the Export menu (TIFF volume, PNG / JPEG slices, config JSON), load and reset. A small badge at the bottom-right of the renderer shows progress while a volume is computed, and problems if any; it is hidden otherwise.

Round trip with the desktop tools

The Export menu gives you the volume as a 32-bit multi-page TIFF (opens in Fiji/ImageJ and napari with the correct pixel size), the XY and XZ slices as a PNG or JPEG picture, and the parameters as psf_config.json. That JSON is exactly what the CLI and the napari plugin read and write (including the resolved grid, the SLM pattern and the θ sampling), so you can continue on the desktop with a bigger grid or field:

faser --config psf_config.json --nxy 256 --l_obs_xy 4

The scalar Debye model (same pupil, no polarization or Fresnel terms) is available from Python for comparisons:

from faser import _core
scalar = _core.generate_psf_json(config.model_dump_json(), scalar=True)

Cost

The PSF cost scales with Ntheta × (Nphi + Nz) × Nxy²; one core does roughly 300–400 million of these units per second in the browser. Typical automatic grids:

Configurationgrid (Nxy² × Nz, Nθ, Nφ)time (single core)
Water objective, 1.0 NA, 4 × 4 µm72² × 47, 64, 56~0.1 s
STED vortex, 1.4 NA oil76² × 51, 72, 56~0.1 s
1.4 NA oil into water, 20 µm deep, 4 × 6 µm116² × 128, 300, 80~2 s
1.4 NA oil, 12 × 16 µm field256² × 128, 344, 184~15 s

Above a few seconds the accurate volume waits for Generate. The imaging simulation adds an FFT over the sample field plus the PSF extent; a 96 × 96 × 48 field with the default PSF takes well under a second.

On this page