# he11lib API Reference `he11lib` reconstructs the Laguerre-Gauss (LG) modal content ("mode purity") of a free-space-propagating gyrotron RF beam from a set of thermal (flux) images taken at different distances from the output window. See `examples/full_pipeline_example.py` for a runnable end-to-end demonstration, and `docs/superpowers/specs/2026-07-02-gyrotron-mode-purity-design.md` for the full design rationale. Every class/function below is exported from the top-level `he11lib` package (e.g. `from he11lib import BeamReconstructor`), except where noted. ## Quick start ```python from he11lib import BeamReconstructor, MeasurementPlane # planes: a list of >=3 MeasurementPlane objects built from your own # flux arrays (see MeasurementPlane below). reconstructor = BeamReconstructor(w0=5e-3, z0=0.5, wavelength=1.76e-3) result = reconstructor.reconstruct(planes) for mode, (power_fraction, phase_rad) in result.purity.items(): print(mode, power_fraction, phase_rad) ``` ## `data` — `MeasurementPlane`, `ReconstructionResult` ### `MeasurementPlane(flux, z, pixel_scale=None, viewing_angle_deg=None, label=None)` One measurement: a 2D flux array plus its acquisition metadata. - `flux` — 2D `np.ndarray` of flux values. Dead-pixel correction, background subtraction, and saturation clipping are assumed already handled upstream. - `z` — nominal distance from the output window, in meters. Must be `> 0`. - `pixel_scale` — known meters/pixel, or `None` if unknown (then jointly fit by `ModalFitter`/`BeamReconstructor`). - `viewing_angle_deg` — known camera viewing angle relative to the beam axis, in degrees, or `None` if unknown (also jointly fit). - `label` — optional human-readable identifier. ### `validate_planes(planes)` Raises `ValueError` if there are fewer than 3 planes, planes have mismatched flux shapes, or `z` values are not all distinct. Called internally by `ModalFitter.fit`/`fit_auto`, `PhaseRetriever.retrieve`, and `BeamReconstructor.reconstruct` — you generally don't need to call it yourself. Not exported from the top-level package; import via `from he11lib.data import validate_planes` if needed. ### `ReconstructionResult` Output of a full reconstruction (returned by `ModalFitter.fit`/`fit_auto` and `BeamReconstructor.reconstruct`): - `purity: dict[(p, l), (power_fraction, phase_rad)]` - `reconstructed_field: np.ndarray` — reconstructed complex field. - `centers: list[(x, y)]` — fitted beam transverse center per plane, meters. - `pointing_angle_deg: float` — fitted shared beam pointing angle (tilt). - `geometry: dict[str, float]` — geometry parameters used or fitted (keys `pixel_scale_{i}`, `viewing_angle_deg_{i}` per plane index `i`). - `residuals: list[np.ndarray]` — per-plane (measured − modeled) flux maps. Empty when `used_phase_retrieval` is `True`. - `coefficient_uncertainty: dict[(p, l), float]` — 1-sigma uncertainty on each mode's fitted power fraction. `NaN` per mode when `used_phase_retrieval` is `True`. - `used_phase_retrieval: bool` — whether the phase-retrieval fallback (not the modal fit) produced this result. ## `modes` — `LGBasis` `LGBasis(w0, z0, wavelength)` — the LG mode basis referenced to a known waist radius `w0` (m), waist location `z0` (m), and radiation `wavelength` (m). - `beam_radius(z)` — `w(z)`. - `inverse_radius_of_curvature(z)` — `1/R(z)` (well-defined, `0`, at the waist). - `gouy_phase(z, p, l)` — Gouy phase of mode `(p, l)` at `z`. - `field(x, y, z, p, l)` — complex `LG_{p,l}` field sampled on the `(x, y)` grid at distance `z`. - `field_superposition(x, y, z, coefficients)` — complex field for `coefficients: dict[(p, l), complex]`. - `project(complex_field, x, y, dx, z, modes)` — projects `complex_field` onto each `(p, l)` in `modes`, returning `dict[(p, l), complex]` coefficients (Riemann-sum inner product; `dx` is the grid spacing). ## `geometry` — `GeometryCalibration` `GeometryCalibration(plane)` wraps a single `MeasurementPlane` and resolves its pixel-to-physical-coordinate mapping. - `pixel_scale_known` / `viewing_angle_known` — `bool` properties. - `physical_coordinates(pixel_scale=None, viewing_angle_deg=None)` — returns `(x, y)` physical coordinate grids matching the plane's flux shape. Values known on the `MeasurementPlane` take precedence over the `override` arguments; raises `ValueError` if a value is neither known nor overridden. ## `noise` — `NoiseEstimator` `NoiseEstimator()` — automatic per-image noise estimation (no user-supplied noise parameter needed). - `estimate_std(image)` — fast Laplacian-based (Immerkær 1996) noise standard-deviation estimate. - `weights(image)` — per-pixel weights (`1/sigma**2`) for noise-weighted least squares. ## `deconvolution` — `DiffusionDeconvolver` `DiffusionDeconvolver(thermal_diffusivity, dwell_time)` — optional correction for lateral thermal-diffusion blur in the absorbing target (`thermal_diffusivity` in m²/s, `dwell_time` in s). Disabled unless you pass a `deconvolver` to `BeamReconstructor`. - `blur_sigma_m()` — Gaussian blur standard deviation, in meters. - `blur(image, pixel_scale)` — forward blur (for synthetic testing). - `deconvolve(image, pixel_scale, noise_to_signal_ratio=1e-3)` — regularized (Wiener) removal of the blur. Note: the blur/deconvolution kernel is isotropic in pixel space. If a plane has a nonzero `viewing_angle_deg`, its `x` and `y` pixel axes have different physical scales (see `SyntheticBeamGenerator` below), so deconvolution is only exact for `viewing_angle_deg == 0`; at oblique angles it is an approximation. ## `synthetic` — `SyntheticBeamGenerator` `SyntheticBeamGenerator(basis, image_shape, pixel_scale)` — forward model used to validate the pipeline against known ground truth, and to evaluate experimental design (e.g. "would these distances separate my modes?"). `pixel_scale` is the physical pixel size, in meters, along the non-tilted `y` axis; the `x` axis is compressed by `1/cos(viewing_angle_deg)` to model an oblique camera view. - `generate(coefficients, z_list, *, center=(0, 0), pointing_angle_deg=0.0, viewing_angle_deg=0.0, noise_std=0.0, seed=None)` — returns one `MeasurementPlane` per `z` in `z_list`. The beam's transverse center drifts linearly with `z` according to `pointing_angle_deg`, starting from `center` at `z0`. ## `fitting` — `ModalFitter`, `generate_mode_shells` ### `generate_mode_shells(max_order)` Groups candidate `LG_{p,l}` modes into shells of increasing order `2p + |l|`, up to and including `max_order`. Returns `list[list[(p, l)]]`, one list of modes per order. ### `ModalFitter(basis, noise_estimator=None)` Core reconstruction path: a joint nonlinear least-squares fit of complex LG coefficients, beam center/pointing, and (if unknown) geometry. - `fit(planes, modes, initial_coefficients=None, initial_center=(0.0, 0.0), initial_tilt_deg=(0.0, 0.0), initial_pixel_scale=None, initial_viewing_angle_deg=0.0) -> ReconstructionResult` — fits exactly the given candidate `modes`. - `fit_auto(planes, max_order=4, bic_improvement_threshold=10.0) -> ReconstructionResult` — starts from `LG_00` and grows the candidate mode set shell-by-shell (via `generate_mode_shells`), stopping once BIC no longer improves by more than `bic_improvement_threshold`, capped at `max_order`. Emits a `UserWarning` (does not raise) if the cap is reached while the fit is still improving. ## `phase_retrieval` — `PhaseRetriever`, `propagate_angular_spectrum` Fallback reconstruction path for when the modal fit's residual stays high, or when the mode content isn't well described by a small finite mode set. ### `propagate_angular_spectrum(field, dx, dz, wavelength)` Free-space-propagates a complex `field` (pixel spacing `dx`) by distance `dz` via the (paraxial) angular-spectrum method — the same propagation model implicitly assumed by `LGBasis`'s closed-form paraxial modes. ### `PhaseRetriever(wavelength)` - `retrieve(planes, pixel_scale=None, viewing_angle_deg=None, max_iterations=200) -> PhaseRetrievalResult` — multi-plane Gerchberg-Saxton phase retrieval: propagates a trial complex field back and forth between planes, enforcing the measured amplitude (`sqrt(flux)`) at each plane, without assuming a finite mode basis. ### `PhaseRetrievalResult` `field, x, y, z, center, residual` — the recovered complex field (at the smallest-`z` plane) on its `(x, y)` grid, the estimated beam center (intensity centroid), and the final RMS amplitude-mismatch residual. Project `field` onto `LGBasis` (via `LGBasis.project`) to get a purity table, as `BeamReconstructor` does internally for its fallback path. ## `reconstruct` — `BeamReconstructor` `BeamReconstructor(w0, z0, wavelength, max_order=4, noise_estimator=None, deconvolver=None, force_phase_retrieval=False, phase_retrieval_residual_threshold=None)` High-level orchestrator wiring together the full pipeline: optional diffusion deblurring → `ModalFitter.fit_auto` → optional `PhaseRetriever` fallback. - `reconstruct(planes) -> ReconstructionResult` 1. Validates `planes` (see `validate_planes`). 2. If `deconvolver` is set, deblurs each plane (raises `ValueError` if a plane's `pixel_scale` isn't known). 3. Runs `ModalFitter(basis, noise_estimator).fit_auto(planes, max_order)`. 4. Runs the `PhaseRetriever` fallback instead, projecting its recovered field onto all modes up to `max_order`, if `force_phase_retrieval` is `True`, or if `phase_retrieval_residual_threshold` is set and the modal fit's noise-weighted RMS residual exceeds it. In that case `result.residuals` is empty and `coefficient_uncertainty` is `NaN` per mode (phase retrieval doesn't produce a fit covariance). ## `plotting` — diagnostic visualizations Each function returns a `matplotlib.figure.Figure` for the caller to display (`fig.show()`) or save (`fig.savefig(...)`); none of them call `plt.show()` themselves. - `plot_mode_purity(result)` — bar chart of power fraction per mode. - `plot_center_trace(planes, result)` — fitted beam center `(x, y)` vs. `z`. - `plot_residuals(planes, result)` — per-plane residual maps. Raises `ValueError` if `result.residuals` is empty (e.g. after the phase-retrieval fallback).