Pick a preset on the left (e.g. thick-lens focus), then change beam and component values — everything recomputes instantly. The plot shows the 1/e² envelope along z; on the right you get the output waist, pulse numbers and each component's aperture margin. The amber/red notes at the bottom are not decoration: ModeForge tells you honestly when something clips or an approximation reaches its limit.
Source: Gaussian (w0, z0, M²), elliptical/astigmatic (separate x/y) or a moment beam (D4σ + M²). The mode helper converts HG/LG orders into an envelope M² ("Apply as beam M²"). Pulse: energy or average power + rate plus FWHM duration and shape — peak power, fluence and intensity at the exit plane appear on the right. Components: add via the + buttons, click to select and edit, reorder with ←/→. Position z adjusts the preceding free space. The computation is paraxial ABCD matrix optics — exact within that approximation, no aberrations.
Two-lens grid search: define lens candidates (f, aperture) and position grids, set a target (radius at plane z or a target waist), choose constraints such as minimum separation and aperture margin. The result list shows the mismatch and optionally the sensitivity to position/focal/M² errors — "Send to beamline" installs a solution directly.
Load Zemax sequential files via LOAD FILE, drag & drop or paste (UTF-16 exports are detected), set λ for the refractive index, parse. Object/image planes of real exports are trimmed automatically. Simple singlets become a thick lens; more complex prescriptions (cemented doublets, multi-element) become a surface stack in the beamline — glass-glass interfaces included. Why is my import blocked? Unknown glasses (load and adopt an AGF catalog first), aspheres/mirrors/tilts (CONI, XDAT, GLAS MIRROR …), unknown lens units, or indices outside the Sellmeier validity range. That is deliberate: an honest no beats a wrong lens.
Propagates the scalar field through the actual beamline and reads it out at a freely chosen probe plane. Grid N and dx set resolution and extent — AUTO dx is the right starting point. Field source: Gaussian or true HG/LG modes (m,n or p,l) — the waist is read as the measured second-moment waist; set the beam M² to match for a consistent cross-check (a note reminds you). Surface phase: "Ideal" = paraxial phase mask; "Real sag (TEA)" imprints the exact spherical surface phase — sag-driven spherical aberration becomes visible. Reading results: the cross-check compares the field against the paraxial envelope. Blue = deviation expected from diffraction (hard aperture). Amber "SAMPLING LIMIT" = the grid cannot resolve the result (e.g. a focus smaller than one grid cell) — the deviation is then a grid artifact, not physics. The warning states the N you would need.
Paste caustic measurements as CSV: one row per point z_mm, width, pick the width basis (1/e² radius, FWHM/D4σ diameter, rms). The least-squares fit returns w0, z0, M² and residuals; "Use as beam" makes the fit your project source.
Load a file: in the Analyzer tab (pill: IMG), drop or pick a .tif/.tiff/.png file (up to 128 MB, decoded images capped at 4096 × 4096 px). Multi-page TIFF and multi-channel PNG add page/channel pickers; set the physical pixel pitch (µm/px, x and y) to see physical widths alongside pixel widths.
Background: today's choices are None or a manual offset in counts; either way the analyzer estimates a noise scale sigma_B — from your background reference rectangles if you gave any, otherwise from a thin rim frame around the ROI. Negative values after correction are never clipped — a systematic negative bias is exactly what the warnings below are watching for.
ROI: Full frame, a rectangle dragged on the image (drag inside to move, drag an edge or corner to resize), typed pixel coordinates (x0, y0, width, height), or the dashed suggested ROI with "Apply suggestion". Whichever is set when you click "Run analysis" becomes the confirmed ROI — the fixed domain every release gate and both moment stages read for that run.
Reading the preview: a compact spot is framed at about 3× the D4sigma diameter; switch the view to full frame to see the blue ROI rectangle on the whole sensor. The solid green overlay is the released D4sigma ellipse; the dashed orange overlay is the fit-width ellipse — never the ROI. A 4sigma ellipse encloses about 86 percent of a Gaussian's power, so the display stretch still shows fainter tails outside it.
Three numbers, on purpose: the headline tile is D4σ (ellipse) — a diameter measured inside an aperture fitted to the beam; it is the analyzer's most trustworthy released number. Next to it, fit width 4sigma is the width the Gaussian model itself predicts — sharper on clean beams, but a model number, not a measurement. The Moments/Profiles panel additionally shows the raw ROI moments — worth looking at, never released as the headline value.
Suppressed? When D4σ (ellipse) cannot be trusted, the tile shows a reason instead of guessing: fit_not_converged (the model fit did not settle), nonpositive_amplitude (the fit found no real peak), residual_high (the fit does not match the data well enough, relative to the noise), aperture_clipped (the check aperture would reach outside your ROI), alpha_inconsistent (the shape is not consistent enough with a clean Gaussian core — wings, a second lobe, a flat top), multi_peak (more than one significant peak was found). None of these is a bug report — the analyzer is deliberately refusing to hand you a number it does not trust.
Warnings worth reading: negative power flags a background correction that leaves too little (or unusually much) negative signal for a clean zero-mean background; ROI sensitive means the released width moves more than expected when the ROI is nudged; residual high and multi peak explain why a release was suppressed; pedestal hint warns of a flat residual offset biasing the width upward; width scatter reports how much the released width itself moves under this image's own noise and warns above 5 percent; absorbed power flags a faint wide wing beyond the aperture that would otherwise vanish into the background fit — though a weak enough wing at very low signal-to-noise can still slip past it; clipping suspect flags a plateau of pixels sitting below the file format's saturation limit, a possible sign of sensor clipping; hot-pixel, saturation and float-special warnings describe the raw file itself, before any of the analysis above runs. Every number here comes from the documented ModeForge analyzer method (see docs/theory in the repository).
The Caustic tab runs a campaign of camera frames at several z positions. Each plane becomes a second-moment observation, repeats are aggregated, and a fit gives w0, z0 and M² per axis. The result can be adopted as a measured source in the beamline.
z-12.5mm, z+3.0mm, z=3 or z_012p5; p represents the decimal point. The unit is mm unless cm, um or µm is specified. Without a marker, only a number with an explicit unit is read, such as -3.0mm or 250um.beam_z-12.5mm_rep01.tif and beam_z-12.5mm_rep02.tif.“Export bundle” and “Import bundle” save and load observations, groups, fit, ensemble and the campaign table in a reproducible archive without pixel data. Two exports of the same state are byte-identical. After import, rows are marked as not loaded; pick the source files again before observing. Reopening a file replaces its earlier rows; pixels stay in the browser.
See also docs/guide/caustic.md and docs/theory/caustic.md.
When the beam is measured behind an optic that is removed again, this card calculates back to the source in front of that optic.
“Setup” offers “Directly measured” or “Measurement train (back-calculate to source)”. Directly measured uses the caustic at the camera as the source. Measurement train calculates back through the specified measurement optic and requires assumptions.
The coupling gate checks the cross moments of all planes jointly with an exact sign-flip test, and needs at least six planes and six repeats per plane. A compatible result does not prove decoupling; adoption still needs the explicit declaration of the uncoupled model. For delivered products that include jitter, it answers “undetermined” because that path is not calibrated yet.
"Export JSON" saves the whole project as a versioned, diffable file; "Import JSON" (also via file/drag & drop) loads it back. Ideal for version control, sharing and reproducibility.