Skip to content

API — nefi.instances

Generated by scripts/gen_api_docs.py — do not edit by hand. Index

nefi.instances

Strong exemplar instances. Importing this package registers every instance.

nefi.instances.base

Instance protocol: a self-contained, registered exemplar inverse problem.

class Instance(cfg: Any | Mapping | None = None, **overrides: Any)

Base class for registered instances. Subclass, set name and Config, implement hooks.

  • baselines(self) -> dict[str, Callable[[Measurement], tuple[InverseProblem, Curriculum]]] — Optional: name -> builder returning (problem, curriculum) for baseline methods.
  • build_problem(self, measurement: Measurement) -> InverseProblem
  • build_problem_measurement_shape(self, field_shape: Sequence[int]) -> tuple[int, ...] | None — Measurement shape at native resolution (default: ask a throwaway problem's operator).
  • config_dict(self) -> dict
  • data_generator(self) -> DataGenerator
  • default_curriculum(self) -> Curriculum
  • default_scene_class(self) -> str | None — Scene class used when run/make_measurement get none (cfg.scene if set).
  • domain(self) -> Domain
  • evaluate(self, result: Result, gt: Mapping[str, torch.Tensor]) -> dict[str, float]
  • make_measurement(self, seed: int = 0, scene_class: str | None = None, gt: Mapping[str, torch.Tensor] | None = None) -> tuple[dict[str, torch.Tensor], Measurement]
  • metrics(self) -> dict[str, Callable]
  • refine(self, result: Result, measurement: Measurement, **kw: Any) — Edge refinement of a reconstruction of measurement: a short second optimization under the same operator and data with a level-set (piecewise-constant) prior, phase values from the instance configuration (nefi.solve.refine.REFINE_DEFAULTS or a refine_defaults attribute).
  • run(self, seed: int = 0, device: str = 'auto', scene_class: str | None = None, curriculum: Curriculum | None = None, callbacks: Sequence = (), **solver_kw) -> R...
  • scene_generator(self) -> SceneGenerator

class RunOutput(result: Result, metrics: dict[str, float], gt: dict[str, torch.Tensor] | None, measurement: Measurement, extra: dict[str, Any] = <factory>)

RunOutput(result: 'Result', metrics: 'dict[str, float]', gt: 'dict[str, torch.Tensor] | None', measurement: 'Measurement', extra: 'dict[str, Any]' = )

nefi.instances.ct3d

ct3d — 3-D parallel-beam sparse-view CT (rotation about z) with a differentiable Radon stack.

class CT3D(cfg: Any = None, preset: str | None = None, **overrides: Any)

3-D sparse-view parallel-beam CT instance (see module docstring).

  • angles(self) -> torch.Tensor
  • baselines(self) -> dict[str, Callable[[Measurement], tuple[InverseProblem, Curriculum]]]
  • build_problem(self, measurement: Measurement) -> InverseProblem
  • build_problem_measurement_shape(self, field_shape)
  • data_generator(self) -> DataGenerator
  • default_curriculum(self) -> Curriculum
  • domain(self) -> Domain
  • fbp(self, measurement: Measurement, filter: str | None = None) -> torch.Tensor — Slice-wise filtered back-projection of measurement on the native grid.
  • field(self) -> NeuralField
  • heads(self) -> Heads
  • losses(self) -> LossSet
  • measurement_image(self, measurement: Measurement) -> torch.Tensor — Compact 2-D view: the sinogram (n_views, n_det) of the most structured slice.
  • metrics(self) -> dict[str, Callable]
  • operator(self, domain: Domain | None = None, det_per_pixel: float | None = None)
  • scene_generator(self) -> SceneGenerator

class CT3DConfig(n: int = 64, n_z: int = 32, extent: float = 1.0, height: float = 1.0, n_views: int = 30, angle_range: float = 180.0, det_per_pixel: float = 1.0, samples_per...

Configuration of the :class:CT3D instance (every number is a field).

def make_problem(seed: int = 0, scene: str | None = None, **cfg: Any) -> tuple[InverseProblem, dict[str, torch.Tensor], Measurement]

Convenience: (problem, gt, measurement) for docs and tests.

def run(cfg: CT3DConfig | dict | None = None, seed: int = 0, **kw: Any)

End-to-end demo (generate → invert → evaluate); returns a RunOutput.

nefi.instances.ct3d.radon3d

Differentiable 3-D parallel-beam Radon transform (rotation about z) and slice-wise FBP.

class Radon3DOperator(domain: Domain, n_views: int = 20, field: str = 'mu', angles: torch.Tensor | Sequence[float] | None = None, angle_range: float = 3.141592653589793, det_per_...

Parallel-beam CT about the z axis: μ (n, n, n_z) ↦ sinograms (V, n_det, n_z).

  • adjoint(self, sinogram: torch.Tensor) -> torch.Tensor — Exact adjoint Rᵀ y of this discretization (autograd VJP; the operator is linear).
  • at_resolution(self, shape: Sequence[int]) -> Radon3DOperator
  • backproject(self, sinogram: torch.Tensor) -> torch.Tensor — Pixel-driven back-projection ≈ Rᵀ y (independent discretization).
  • dt (property) — Physical ray step Δt.
  • extra_repr(self) -> str
  • fbp(self, sinogram: torch.Tensor, filter: str = 'ramp', circle: bool = False) — Slice-wise filtered back-projection onto this operator's grid.
  • forward(self, fields: Fields) -> torch.Tensor
  • n_views (property)
  • output_shape(self, shape: Sequence[int]) -> tuple[int, ...]
  • tau (property) — Physical detector bin width.

def backproject3d(sinogram: torch.Tensor, angles: torch.Tensor, n: int | None = None, width: float = 1.0, samples_per_pixel: float = 1.0) -> torch.Tensor

Pixel-driven back-projection of a sinogram stack, scaled to approximate Rᵀ.

def fbp3d(sinogram: torch.Tensor, angles: torch.Tensor | Sequence[float], filter: str = 'ramp', *, n: int | None = None, width: float = 1.0, circle: bool = False) -> ...

Slice-wise filtered back-projection f(·, z) ≈ (π/V) Σ_θ q_θ(x cos θ + y sin θ, z).

nefi.instances.ct3d.scenes

Procedural 3-D CT phantoms (normalized coordinates, inside the scanner cylinder, in [0, 1]).

class CT3DScenes(domain: Domain, render_factor: int = 2)

Attenuation volumes for 3-D parallel-beam CT (rotation axis z).

  • blobs(self, rng: np.random.Generator) -> Painter3D
  • ellipsoids(self, rng: np.random.Generator) -> Painter3D
  • piecewise(self, rng: np.random.Generator) -> Painter3D
  • sample(self, rng, cls=None, shape=None)

nefi.instances.current_density

current_density — NV-magnetometry current imaging: sheet current from its stray field B_z.

class BiotSavartDataGenerator(operator: Operator, noise_std: float = 0.0, relative: bool = True, dtype: torch.dtype = torch.float64, device: str | torch.device = 'cpu', supersample: int ...

g on a fine grid → direct Biot–Savart B_z at the native pixels (float64) + noise.

  • generate(self, gt_fields, rng: np.random.Generator, noise_std=None, target_shape=None)

class CurrentDensity(cfg: Any | Mapping | None = None, **overrides: Any)

NV magnetometry current-density imaging (stream-function parameterization).

  • baselines(self)
  • build_problem(self, measurement: Measurement) -> InverseProblem
  • build_problem_measurement_shape(self, field_shape)
  • data_generator(self) -> BiotSavartDataGenerator
  • default_curriculum(self) -> Curriculum
  • domain(self) -> Domain
  • evaluate(self, result: Result, gt: Mapping[str, torch.Tensor]) -> dict[str, float]
  • field(self) -> NeuralField
  • fourier_reconstruction(self, measurement: Measurement) -> torch.Tensor — Classical regularized k-space inversion of the measured B_z (stream function).
  • heads(self) -> Heads
  • losses(self, tv: float | None = None) -> LossSet
  • make_measurement(self, seed=0, scene_class=None, gt=None)
  • metrics(self) -> dict[str, Callable]
  • mu0 (property)
  • operator(self, domain: Domain | None = None) -> CurrentDensityOperator
  • scene_generator(self) -> SceneGenerator

class CurrentDensityConfig(n: int = 64, pixel: float = 0.1, z0: float = 0.2, nv_layer: float = 0.0, length_unit: str = 'um', current_unit: str = 'mA', field_unit: str = 'uT', pad_fact...

NV current-imaging instance configuration (every number used by the pipeline).

def current_metrics(pred_g: torch.Tensor, gt_g: torch.Tensor, spacing, pred_bz: torch.Tensor | None = None, gt_bz: torch.Tensor | None = None) -> dict[str, float]

PSNR / relative error of K = ∇×g (central differences, both components) and of B_z.

def make_problem(seed: int = 0, scene_class: str | None = None, **cfg)

Convenience: (problem, gt, measurement) for docs, tests and notebooks.

def run(cfg: CurrentDensityConfig | dict | None = None, seed: int = 0, **kw)

End-to-end demo: generate → invert → evaluate. Returns (Result, metrics).

nefi.instances.current_density.scenes

Current-density scenes for NV magnetometry: wires, loops and branching current networks.

class CurrentScenes(domain: Domain, current: Sequence[float] = (0.5, 1.5), width: Sequence[float] = (0.2, 0.3), margin: float = 0.15, loop_radius: Sequence[float] = (0.08, 0.2)...

Stream-function scenes (see module docstring). Lengths in domain units.

  • components(self, rng: np.random.Generator, cls: str) -> list[dict] — Sample the scene's current paths: dicts with kind, geometry, I and w.
  • render(self, comps: list[dict], shape: Sequence[int] | None = None) -> torch.Tensor — Stream function g (float64) on the grid shape.
  • sample(self, rng, cls=None, shape=None)

nefi.instances.darcy_flow

darcy_flow — permeability recovery from steady pressure data (subsurface flow).

class DarcyConfig(n: int = 32, length: float = 1.0, viscosity: float = 1.0, bc: str = 'neumann', n_configs: int = 6, well_radius: float = 0.3, well_rate: float = 1.0, well_an...

Darcy-flow instance configuration (every number used by the pipeline).

class DarcyFlow(cfg: Any | Mapping | None = None, **overrides: Any)

Steady Darcy flow: log-permeability from sparse pressure gauges, several well patterns.

  • baselines(self)
  • build_problem(self, measurement: Measurement) -> InverseProblem
  • build_problem_measurement_shape(self, field_shape)
  • data_generator(self) -> SupersampledObservationGenerator
  • default_curriculum(self) -> Curriculum
  • domain(self) -> Domain
  • field(self) -> NeuralField
  • heads(self) -> Heads
  • losses(self, tv: float | None = None) -> LossSet
  • make_measurement(self, seed=0, scene_class=None, gt=None)
  • metrics(self) -> dict[str, Callable]
  • observation_weights(self, shape: tuple[int, ...]) -> torch.Tensor — Sensor weights at grid shape (exact native-cell footprints).
  • operator(self, domain: Domain | None = None, **overrides) -> DarcyOperator
  • scene_generator(self) -> SceneGenerator
  • sensors(self) -> torch.Tensor — (n_configs, n, n) native sensor mask (deterministic unless sensor_jitter > 0).
  • wells(self) -> list[list[tuple[float, float, float]]]

def make_problem(seed: int = 0, scene_class: str | None = None, **cfg)

Convenience: (problem, gt, measurement) for docs, tests and notebooks.

def run(cfg: DarcyConfig | dict | None = None, seed: int = 0, **kw)

End-to-end demo: generate → invert → evaluate. Returns (Result, metrics).

nefi.instances.darcy_flow.operator

Steady single-phase Darcy flow: log-permeability → pressure at sparse sensors.

class DarcyOperator(domain: Domain, wells: Sequence[Sequence[Well]], *, sensors: torch.Tensor | None = None, obs_shape: Sequence[int] | None = None, field: str = 'log_k', sigma...

{log_k} → p (n_configs, *obs_shape): steady Darcy pressure per well configuration.

  • output_shape(self, shape: Sequence[int]) -> tuple[int, ...]
  • post(self, u: torch.Tensor, sigma: torch.Tensor, fields) -> torch.Tensor

def sensor_mask(domain: Domain, wells: Sequence[Sequence[Well]], n_sensors: int = 6, exclusion: float = 1.5, jitter: float = 0.0, rng=None) -> torch.Tensor

(n_configs, *grid) pressure-sensor mask on a regular n_sensors × n_sensors lattice.

def well_configurations(domain: Domain, n_configs: int, radius: float = 0.35, rate: float = 1.0, angle0: float = 0.3) -> list[list[Well]]

Injector/producer pairs on a circle, rotated over half a turn.

def wells_rhs(domain: Domain, wells: Sequence[Sequence[Well]], viscosity: float = 1.0, spread: str = 'linear') -> torch.Tensor

(n_configs, *grid) source density μ Σ Q δ(x − x_w) (cloud-in-cell point sources).

nefi.instances.darcy_flow.scenes

Darcy-flow ground-truth permeability fields (log-permeability Y = log k).

class DarcyScenes(domain: Domain, mean: float = 0.0, std: float = 0.8, corr_length: float = 0.15, n_modes: int = 128, channel_contrast: float = 2.5, channel_bg_std: float = 0...

Log-permeability scenes (see module docstring).

  • sample(self, rng, cls=None, shape=None)

def high_k_iou(pred, gt, n_std: float = 1.0) -> float

IoU of the high-permeability region Y > mean(Y_gt) + n_std·std(Y_gt) (flow paths).

nefi.instances.deconvolution

deconvolution — 2-D image deblurring with Gaussian / motion / disk PSFs.

class Deconvolution(cfg: Any | Mapping | None = None, **overrides: Any)

2-D image deblurring instance (see module docstring).

  • baselines(self) -> dict[str, Callable[[Measurement], tuple[InverseProblem, Curriculum]]]
  • blur(self, domain: Domain | None = None) -> FFTConvolution — Blur operator in image units (no count scaling).
  • build_problem(self, measurement: Measurement, losses: LossSet | None = None) -> InverseProblem
  • build_problem_measurement_shape(self, field_shape)
  • data_generator(self) -> DataGenerator
  • default_curriculum(self) -> Curriculum
  • domain(self) -> Domain
  • field(self) -> NeuralField
  • heads(self) -> Heads
  • losses(self, l2: float = 0.0) -> LossSet
  • measurement_image(self, measurement: Measurement) -> torch.Tensor — Measurement in image units (counts → intensity for Poisson data).
  • metrics(self) -> dict[str, Callable]
  • noise_level(self, measurement: Measurement) -> float — Noise std in image units (known Gaussian std, or √λ / peak for Poisson counts).
  • operator(self, domain: Domain | None = None) -> Operator — Inversion operator: blur, times peak_counts plus background for Poisson data.
  • psf_fn(self) -> KernelFn
  • scene_generator(self) -> SceneGenerator
  • wiener(self, measurement: Measurement) -> torch.Tensor — Closed-form Wiener reconstruction of measurement (image units, clipped ≥ 0).
  • wiener_reconstruction(self, measurement: Measurement) -> tuple[torch.Tensor, float] — Closed-form Wiener reconstruction (image units, ≥ 0) and the SNR used.

class DeconvolutionConfig(n: int = 64, extent: float = 1.0, scene: str = 'phantom', psf: str = 'gaussian', psf_sigma: float = 0.02, motion_length: float = 0.1, motion_angle: float = ...

Configuration of the :class:Deconvolution instance (all numbers are config fields).

def make_problem(n: int = 64, seed: int = 0, scene: str | None = None, **cfg) -> tuple[InverseProblem, dict[str, torch.Tensor], Measurement]

Convenience: (problem, gt, measurement) for docs and tests.

def run(cfg: DeconvolutionConfig | dict | None = None, seed: int = 0, **kw)

End-to-end demo (generate → invert → evaluate); returns a RunOutput.

nefi.instances.deconvolution.data

Inverse-crime-safe blur data generation with Gaussian or Poisson (photon-count) noise.

class BlurDataGenerator(operator: Operator, noise: str = 'gaussian', noise_std: float = 0.01, peak_counts: float = 200.0, background_counts: float = 0.0, relative: bool = True, dty...

Blur on a finer grid in float64, area-average to the detector grid, then add noise.

  • generate(self, gt_fields: dict[str, torch.Tensor], rng: np.random.Generator, noise_std: float | None = None, target_shape: Sequence[int] | None = None) -> Measurement

nefi.instances.deconvolution.phantoms

Procedural 2-D phantom primitives shared by the imaging instances.

class Painter(background: float = 0.0, clip: tuple[float | None, float | None] | None = (0.0, 1.0))

Accumulates primitives into a scene: additive terms and painted (overwriting) regions.

  • add(self, value: float, fn: Callable) -> Painter
  • paint(self, value: float, fn: Callable) -> Painter

def disk(x, y, cx: float, cy: float, r: float) -> torch.Tensor

def ellipse(x, y, cx: float, cy: float, a: float, b: float, theta: float = 0.0) -> torch.Tensor

Indicator of an ellipse with semi-axes a, b rotated by theta (radians).

def gaussian(x, y, cx: float, cy: float, sx: float, sy: float | None = None, theta: float = 0.0) -> torch.Tensor

Unit-peak anisotropic Gaussian.

def point_max(fn: SceneFn, domain: Domain, render_factor: int = 4, normalized: bool = False)

Maximum of the point-sampled rendering sub-grid (grid-independent normalization).

def rectangle(x, y, cx: float, cy: float, w: float, h: float, theta: float = 0.0) -> torch.Tensor

Indicator of a w × h rectangle centered at (cx, cy) rotated by theta.

def render(fn: SceneFn, domain: Domain, shape: Sequence[int] | None = None, render_factor: int = 4, normalized: bool = False) -> torch.Tensor

Cell-averaged rendering of a continuous 2-D scene (float64).

def uniform(rng: np.random.Generator, lo: float, hi: float) -> float

nefi.instances.deconvolution.psf

Point-spread functions as kernel functions of the grid spacing (rebuilt at every resolution).

def disk_psf(radius: float, supersample: int = 8) -> KernelFn

Uniform out-of-focus (pillbox) blur of physical radius, anti-aliased per pixel.

def gaussian_psf(sigma: float | Sequence[float]) -> KernelFn

Gaussian blur with physical standard deviation sigma (isotropic or per axis).

def make_psf(kind: str, sigma: float = 0.02, motion_length: float = 0.1, motion_angle: float = 30.0, disk_radius: float = 0.04) -> KernelFn

PSF kernel function by name: "gaussian" | "motion" | "disk".

def motion_psf(length: float, angle_deg: float = 0.0, samples_per_cell: int = 8) -> KernelFn

Linear motion blur: a uniform line segment of physical length at angle_deg.

nefi.instances.deconvolution.scenes

Ground-truth scene classes for image deblurring (cell-averaged, resolution-consistent).

class DeconvolutionScenes(domain: Domain, dot_cells: float = 0.7, render_factor: int = 4)

Scene classes (values in [0, 1], zero-ish background):

  • phantom(self, rng: np.random.Generator) -> Painter
  • sample(self, rng, cls=None, shape=None)
  • smooth(self, rng: np.random.Generator) -> Painter
  • sparse_dots(self, rng: np.random.Generator) -> Painter

nefi.instances.deconvolution.wiener

Classical Wiener deconvolution — the closed-form reference reconstruction.

def wiener(measurement: Measurement | torch.Tensor, psf: torch.Tensor | FFTConvolution, snr: float = 100.0, pad: int | None = None, clip: tuple[float | None, float | N...

Wiener filter X = conj(H) Y / (|H|² + 1/snr) (Wiener 1949; e.g. Gonzalez & Woods §5.8).

def wiener_discrepancy(measurement: Measurement | torch.Tensor, psf: FFTConvolution, noise_std: float, tau: float = 1.0, snrs: torch.Tensor | None = None, **kw) -> tuple[torch.Ten...

Wiener filter with the SNR chosen by Morozov's discrepancy principle.

nefi.instances.deconvolution3d

deconvolution3d — fluorescence-microscopy z-stack deblurring with an anisotropic 3-D PSF.

class Deconvolution3D(cfg: Any = None, preset: str | None = None, **overrides: Any)

3-D widefield fluorescence deconvolution instance (see module docstring).

  • baselines(self) -> dict[str, Callable[[Measurement], tuple[InverseProblem, Curriculum]]]
  • blur(self, domain: Domain | None = None) -> FFTConvolution — The PSF convolution in image units (no count scaling).
  • build_problem(self, measurement: Measurement) -> InverseProblem
  • build_problem_measurement_shape(self, field_shape)
  • data_generator(self) -> DataGenerator
  • default_curriculum(self) -> Curriculum
  • domain(self) -> Domain
  • field(self) -> NeuralField
  • heads(self) -> Heads
  • losses(self) -> LossSet
  • measurement_image(self, measurement: Measurement) -> torch.Tensor — Compact 2-D view: the z-slice (image units) with the largest in-slice variance.
  • measurement_stack(self, measurement: Measurement) -> torch.Tensor — Measurement in image units (counts → intensity for Poisson data).
  • metrics(self) -> dict[str, Callable]
  • noise_level(self, measurement: Measurement) -> float — Noise std in image units (known Gaussian std, or √λ / peak for Poisson counts).
  • operator(self, domain: Domain | None = None) -> Operator — Inversion operator: blur, times peak_counts plus background for Poisson data.
  • psf_sigma(self) -> tuple[float, float, float] — Physical PSF standard deviations (σ_xy, σ_xy, σ_z) in µm.
  • richardson_lucy(self, measurement: Measurement, n_iter: int | None = None) -> torch.Tensor — Richardson–Lucy reconstruction (rl_iters EM iterations) in image units.
  • scene_generator(self) -> SceneGenerator
  • wiener(self, measurement: Measurement) -> torch.Tensor — Closed-form 3-D Wiener reconstruction of measurement.
  • wiener_reconstruction(self, measurement: Measurement) -> tuple[torch.Tensor, float] — Closed-form 3-D Wiener reconstruction (image units, ≥ 0) and the SNR used.

class Deconvolution3DConfig(n: int = 64, n_z: int = 32, pixel_size: float = 0.1, z_step: float = 0.2, scene: str = 'filaments', render_factor: int = 2, filament_sigma: tuple[float, flo...

Configuration of the :class:Deconvolution3D instance (every number is a field).

def make_problem(seed: int = 0, scene: str | None = None, **cfg: Any) -> tuple[InverseProblem, dict[str, torch.Tensor], Measurement]

Convenience: (problem, gt, measurement) for docs and tests.

def run(cfg: Deconvolution3DConfig | dict | None = None, seed: int = 0, **kw: Any)

End-to-end demo (generate → invert → evaluate); returns a RunOutput.

nefi.instances.deconvolution3d.classical

Classical 3-D deconvolution references: Wiener filtering and Richardson–Lucy.

def richardson_lucy(counts: torch.Tensor, blur: FFTConvolution, n_iter: int = 40, gain: float = 1.0, background: float = 0.0, x0: torch.Tensor | None = None, eps: float = 1e-08...

Richardson–Lucy deconvolution of (photon-count or intensity) data.

def wiener3d(image: torch.Tensor, psf: FFTConvolution | torch.Tensor, snr: float = 100.0, pad: tuple[int, ...] | None = None, clip: tuple[float | None, float | None] | N...

Wiener deconvolution of a 1-/2-/3-D image (image in image units).

def wiener3d_discrepancy(image: torch.Tensor, psf: FFTConvolution, noise_std: float, tau: float = 1.0, snrs: torch.Tensor | None = None, **kw) -> tuple[torch.Tensor, float]

Wiener filter with the SNR chosen by Morozov's discrepancy principle.

nefi.instances.deconvolution3d.scenes

Fluorescence-microscopy ground-truth volumes (physical µm coordinates, intensities ~[0, 1]).

class Deconvolution3DScenes(domain: Domain, render_factor: int = 2, filament_sigma: tuple[float, float] = (0.06, 0.09), puncta_sigma: tuple[float, float] = (0.04, 0.07), membrane_width...

Z-stack scene classes (fluorophore density, zero-ish background):

  • cells(self, rng: np.random.Generator)
  • filaments(self, rng: np.random.Generator)
  • puncta(self, rng: np.random.Generator)
  • sample(self, rng, cls=None, shape=None)

nefi.instances.diffraction_tomography

diffraction_tomography — 2-D Born / Rytov inversion of a weak scattering contrast.

class DiffractionTomography(cfg: Any | Mapping | None = None, **overrides: Any)

Born diffraction tomography instance (see module docstring).

  • backpropagation(self, measurement: Measurement, domain: Domain | None = None) — Filtered backpropagation reconstruction of χ (closed form).
  • baselines(self)
  • build_problem(self, measurement: Measurement) -> InverseProblem
  • build_problem_measurement_shape(self, field_shape)
  • data_generator(self) -> DataGenerator
  • default_curriculum(self, lr_mult: float = 1.0) -> Curriculum
  • domain(self) -> Domain
  • field(self) -> NeuralField
  • heads(self) -> Heads
  • losses(self) -> LossSet
  • metrics(self) -> dict[str, Callable]
  • operator(self, domain: Domain | None = None) -> BornOperator
  • scene_generator(self) -> SceneGenerator

class DiffractionTomographyConfig(n: int = 32, extent: float = 4.0, wavelength: float = 1.0, background_index: float = 1.0, scene: str = 'blobs', contrast: float = 0.02, n_angles: int = 16, ...

Configuration (defaults = CPU smoke preset: 32², 16 angles, 64 receivers).

class DiffractionTomographyScenes(domain: Domain, contrast: float)

Weak-contrast phantoms χ(x) (analytic, any resolution).

  • sample(self, rng: np.random.Generator, cls: str | None = None, shape=None)

def make_problem(seed: int = 0, **cfg)

Convenience: (problem, gt, measurement).

def run(cfg=None, seed: int = 0, **kw)

End-to-end demo (DESIGN §3.10): (result, metrics).

nefi.instances.dot3d

dot3d — continuous-wave diffuse optical tomography: absorption from surface reflectance.

class DOT3D(cfg: Any = None, preset: str | None = None, **overrides: Any)

CW diffuse optical tomography instance (see module docstring).

  • A (property) — Robin boundary factor from the refractive index (Groenhuis fit).
  • D (property) — Diffusion coefficient 1/(3 μ_s') (mm).
  • background_prediction(self) -> torch.Tensor — Readings of the homogeneous background slab (inversion operator, float64, cached).
  • baselines(self) -> dict[str, Callable[[Measurement], tuple[InverseProblem, Curriculum]]]
  • build_problem(self, measurement: Measurement) -> InverseProblem
  • build_problem_measurement_shape(self, field_shape)
  • data_generator(self) -> DOTDataGenerator
  • default_curriculum(self) -> Curriculum
  • depths(self) -> torch.Tensor — Cell-center depths (mm) of the native grid.
  • detectors(self) -> tuple[torch.Tensor, float] — Detector centers (n_dx, n_dy, 2) and pixel size (mm).
  • domain(self) -> Domain
  • evaluate(self, result: Result, gt: Mapping[str, torch.Tensor]) -> dict[str, float]
  • field(self) -> NeuralField
  • heads(self) -> Heads
  • inclusion_mask(self, mua: torch.Tensor) -> torch.Tensor — Half-maximum inclusion mask {e > iou_fraction · max e} of the absorption excess e = [μ_a − μ_bg]_+ (contrast independent: DOT under-recovers contrast by design).
  • inclusion_metrics(self, pred: torch.Tensor, gt: torch.Tensor) -> dict[str, float] — Inclusion localization, depth and contrast recovery (half-maximum masks).
  • losses(self) -> LossSet
  • measurement_image(self, measurement: Measurement) -> torch.Tensor — Compact 2-D view: source-averaged Rytov data log(y / y₀) (%, observed pairs), with y₀ the homogeneous-background reading (1 for calibrated data) — the inclusions' shadow.
  • metrics(self) -> dict[str, Callable]
  • observation_mask(self) -> torch.Tensor — (n_sources, n_dx, n_dy) mask of the observed source–detector pairs.
  • operator(self, domain: Domain | None = None, tol: float | None = None)
  • scene_generator(self) -> SceneGenerator
  • sensitivity(self, problem: InverseProblem | None = None, **kw: Any) -> torch.Tensor — Depth-resolved sensitivity ‖∂y/∂μ_a(x)‖ of the observed data at the background (:func:nefi.diagnostics.sensitivity_map: stochastic output probes by default, one adjoint solve each; exact=True computes every column, one solve per voxel).
  • sources(self) -> torch.Tensor — Source positions (n_sources, 3): a grid on the top face, depth 1/μ_s'.

class DOT3DConfig(extent: tuple[float, float, float] = (40.0, 40.0, 20.0), grid: tuple[int, int, int] = (32, 32, 16), musp: float = 1.0, refractive_index: float = 1.4, mua_ba...

Configuration of the :class:DOT3D instance (every number is a field; lengths in mm, coefficients in mm⁻¹).

def make_problem(seed: int = 0, scene: str | None = None, **cfg: Any) -> tuple[InverseProblem, dict[str, torch.Tensor], Measurement]

Convenience: (problem, gt, measurement) for docs and tests.

def run(cfg: DOT3DConfig | dict | None = None, seed: int = 0, **kw: Any)

End-to-end demo (generate → invert → evaluate); returns a RunOutput.

nefi.instances.dot3d.data

DOT data generation (fine-grid physics, multiplicative noise, source–detector mask) and the relative-residual data loss.

class DOTDataGenerator(operator: Operator, noise_std: float = 0.01, min_separation: float = 6.0, supersample: int = 2, fidelity_tag: str = 'dot-fv-robin-2x-float64', dtype: torch....

Fine-grid CW DOT data with multiplicative (shot-noise-like) Gaussian noise.

  • generate(self, gt_fields: dict[str, torch.Tensor], rng: np.random.Generator, noise_std: float | None = None, target_shape: Sequence[int] | None = None) -> Measurement

class RelativeResidualMSE(floor: float = 1e-06, name: str | None = None)

mean_obs [(pred − obs) / |obs|]² — the relative (per-entry normalized) residual.

  • forward(self, ctx: Context) -> torch.Tensor

def separation_mask(sources: torch.Tensor, detectors: torch.Tensor, min_separation: float) -> torch.Tensor

(n_sources, n_dx, n_dy) mask of source–detector pairs with a lateral separation of at least min_separation (the diffusion approximation fails close to the source, and the huge near-source dynamic range would dominate any fit).

nefi.instances.dot3d.operator

Continuous-wave diffuse optical tomography (DOT) forward model on a 3-D slab.

class DiffuseOpticalOperator(domain: Domain, sources: torch.Tensor | Sequence[Sequence[float]], detectors: torch.Tensor, detector_size: float, *, D: float, A: float, field: str = 'mu_a'...

CW DOT: absorption μ_a(x) → top-face exitance at detector footprints for every source.

  • coefficient(self, fields: Fields) -> torch.Tensor — The (known, homogeneous) diffusion coefficient on the grid.
  • detector_shape (property)
  • extra_repr(self) -> str
  • fluence(self, mua: torch.Tensor) -> torch.Tensor — Full fluence Φ (n_sources, *grid) for an absorption map (diagnostics).
  • kappa_value(self, fields: Fields, ref: torch.Tensor) -> torch.Tensor — κ = μ_a + κ_b (unknown absorption + Robin boundary sink).
  • n_sources (property)
  • output_shape(self, shape: Sequence[int]) -> tuple[int, ...]
  • post(self, u: torch.Tensor, sigma: torch.Tensor, fields: Fields) -> torch.Tensor
  • readout(self, u: torch.Tensor) -> torch.Tensor — Top-face exitance K_b Φ[..., 0] averaged over the detector footprints.
  • reference_readout(self, device=None, dtype=None) -> torch.Tensor — Readings of the homogeneous reference slab (μ_a = reference_mua), cached; the solve bypasses the warm-start state of the optimization loop.
  • required_fields(self) -> tuple[str, ...]

def boundary_conductance(h: float, D: float, A: float) -> float

Series conductance K_b = 1 / (2A + h / 2D) of a boundary face (flux K_b Φ_0).

def detector_layout(domain: Domain, n: Sequence[int], span: float = 0.8) -> tuple[torch.Tensor, float]

Detector centers (n_dx, n_dy, 2) covering the central span fraction of the top face and the detector pitch (square pixels, one per layout cell).

def grid_positions(n: Sequence[int], lo: Sequence[float], hi: Sequence[float]) -> torch.Tensor

Cell centers of a regular n[0] × n[1] layout over [lo, hi] → (n0, n1, 2).

def robin_A(refractive_index: float) -> float

Boundary mismatch factor A = (1 + R_eff) / (1 − R_eff) with the Groenhuis et al. (1983) fit R_eff = −1.440 n⁻² + 0.710 n⁻¹ + 0.668 + 0.0636 n (n = 1.4 → A ≈ 3.25; n = 1 → A ≈ 1).

def robin_sink(domain: Domain, D: float, A: float, dtype=torch.float64) -> torch.Tensor

Volumetric sink κ_b = Σ_faces K_b / h of the boundary cells (Robin on all six faces).

nefi.instances.dot3d.scenes

Absorbing inclusions in a scattering slab (physical mm coordinates, μ_a in mm⁻¹).

class DOT3DScenes(domain: Domain, mua_background: float = 0.01, inclusion_mua: tuple[float, float] = (0.03, 0.05), radius: tuple[float, float] = (3.0, 5.0), depth_single: tup...

Absorption maps μ_a(x, y, z) of a slab (depth = last axis, top face at z = 0).

  • draw(self, rng: np.random.Generator, cls: str | None = None) -> list[Inclusion] — Draw the inclusions of one scene (grid independent).
  • render(self, inclusions: list[Inclusion], shape=None) -> torch.Tensor
  • sample(self, rng, cls=None, shape=None)

class Inclusion(center: tuple[float, float, float], radius: float, mua: float)

One spherical absorber: physical center (x, y, depth), radius and μ_a.

  • depth (property)

nefi.instances.eit

eit — electrical impedance tomography: conductivity from boundary voltages.

class EIT(cfg: Any | Mapping | None = None, **overrides: Any)

Electrical impedance tomography (continuum or gap electrode model).

  • baselines(self)
  • build_problem(self, measurement: Measurement) -> InverseProblem
  • build_problem_measurement_shape(self, field_shape)
  • data_generator(self) -> SupersampledObservationGenerator
  • default_curriculum(self) -> Curriculum
  • difference_data(self, measurement: Measurement) -> torch.Tensor — Boundary signature of the inclusions (difference EIT): per observed strip cell, the RMS over the current patterns of V − V_bg in % of the RMS boundary voltage, where V_bg is the prediction for the homogeneous body σ ≡ σ_bg; NaN off the observed strip.
  • domain(self) -> Domain
  • field(self) -> NeuralField
  • heads(self) -> Heads
  • losses(self, tv: float | None = None) -> LossSet
  • make_measurement(self, seed=0, scene_class=None, gt=None)
  • measurement_image(self, measurement: Measurement) -> tuple[torch.Tensor, str] — Compact measurement view for the viewers (:mod:nefi.viz): :meth:difference_data.
  • metrics(self) -> dict[str, Callable]
  • observation_weights(self, shape: tuple[int, ...]) -> torch.Tensor — Boundary length observed per strip cell at grid shape (mask = > 0).
  • operator(self, domain: Domain | None = None, **overrides) -> EITOperator
  • scene_generator(self) -> SceneGenerator

class EITConfig(n: int = 32, half_width: float = 1.0, sigma_bg: float = 1.0, sigma_min: float = 0.05, sigma_max: float = 20.0, n_patterns: int = 8, amplitude: float = 1.0, ...

EIT instance configuration (every number used by the pipeline).

def make_problem(seed: int = 0, scene_class: str | None = None, **cfg)

Convenience: (problem, gt, measurement) for docs, tests and notebooks.

def run(cfg: EITConfig | dict | None = None, seed: int = 0, **kw)

End-to-end demo: generate → invert → evaluate. Returns (Result, metrics).

nefi.instances.eit.operator

Continuum-model EIT forward operator: conductivity → boundary potentials for current patterns.

class EITBoundary(rhs: torch.Tensor, offset: torch.Tensor, weights: torch.Tensor, faces: dict[str, np.ndarray])

Boundary data of the EIT model on one grid.

class EITOperator(domain: Domain, n_patterns: int = 8, *, amplitude: float = 1.0, electrodes: int = 0, coverage: float = 0.5, obs_shape: Sequence[int] | None = None, field: s...

Continuum / gap-model EIT: {σ} → V (n_patterns, *obs_shape), strip = boundary traces.

  • face_traces(self, u: torch.Tensor, sigma: torch.Tensor) -> torch.Tensor — (n_patterns, n_faces) boundary traces u + (h_n/2) j/σ on this operator's grid.
  • observation_weights (property) — (*obs_shape) observed boundary length per strip cell (mask = > 0).
  • output_shape(self, shape: Sequence[int]) -> tuple[int, ...]
  • post(self, u: torch.Tensor, sigma: torch.Tensor, fields) -> torch.Tensor

def boundary_faces(domain: Domain) -> dict[str, np.ndarray]

Boundary faces of a 2-D rectangular grid in counter-clockwise arc-length order.

def eit_boundary(domain: Domain, n_patterns: int, amplitude: float = 1.0, electrodes: int = 0, coverage: float = 0.5, dtype: torch.dtype = torch.float64) -> EITBoundary

Right-hand sides, trace offsets and observation weights of the EIT model on domain.

def face_interpolation(src: dict[str, np.ndarray], dst: dict[str, np.ndarray]) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]

Periodic linear interpolation in arc length from src to dst boundary-face centres.

nefi.instances.eit.scenes

EIT ground-truth scenes: homogeneous background with elliptical inclusions.

class EITScenes(domain: Domain, sigma_bg: float = 1.0, contrast: Sequence[float] = (3.0, 6.0), high_contrast: Sequence[float] = (10.0, 20.0), radius: Sequence[float] = (0.1...

Background σ_bg plus elliptical inclusions (see module docstring).

  • inclusions(self, rng: np.random.Generator, cls: str) -> list[dict] — Sample inclusion parameters (independent of the rendering resolution).
  • render(self, inclusions: list[dict], shape: Sequence[int] | None = None) -> torch.Tensor — σ on the grid shape (float64), area-weighted at inclusion boundaries.
  • sample(self, rng, cls=None, shape=None)

def inclusion_iou(pred, gt, sigma_bg: float = 1.0, fraction: float = 0.5) -> float

IoU of the recovered inclusion support (half-maximum, sign-aware, log-contrast).

nefi.instances.holography

holography — multi-distance inline (Gabor) holography phase retrieval.

class Holography(cfg: Any | Mapping | None = None, **overrides: Any)

Multi-distance inline holography instance (see module docstring).

  • baselines(self)
  • build_problem(self, measurement: Measurement) -> InverseProblem
  • build_problem_measurement_shape(self, field_shape)
  • data_generator(self) -> DataGenerator
  • default_curriculum(self, lr_mult: float = 1.0) -> Curriculum
  • domain(self) -> Domain
  • field(self) -> NeuralField
  • gerchberg_saxton(self, measurement: Measurement, domain: Domain | None = None) — Multi-distance Gerchberg–Saxton phase (closed-form-style baseline).
  • heads(self) -> Heads
  • losses(self) -> LossSet
  • metrics(self) -> dict[str, Callable]
  • operator(self, domain: Domain | None = None) -> HolographyOperator
  • scene_generator(self) -> SceneGenerator
  • viz_hints (property) — Display hints (:mod:nefi.viz.hints): with the :class:~nefi.fields.ZeroMean head the phase and the phantoms share one gauge, so the viewer's zero_mean display transform (the fallback for zero_mean=False) is switched off.

class HolographyConfig(n: int = 32, pixel_size: float = 1.0, wavelength: float = 0.5, distances: tuple[float, ...] = (10.0, 25.0, 50.0), scene: str = 'smooth_phase', phase_amplitu...

Configuration (defaults = CPU smoke preset: 32², 3 distances).

class HolographyScenes(domain: Domain, amplitude: float, zero_mean: bool = True)

Phase phantoms φ(x) in rad (analytic, any resolution).

  • sample(self, rng: np.random.Generator, cls: str | None = None, shape=None)

def make_problem(seed: int = 0, **cfg)

Convenience: (problem, gt, measurement).

def run(cfg=None, seed: int = 0, **kw)

End-to-end demo (DESIGN §3.10): (result, metrics).

nefi.instances.nv_relaxometry

nv_relaxometry — NeTMY: sparse spin-density recovery from NV-center relaxometry spectra.

class NVRelaxometry(cfg: Any | Mapping | None = None, **overrides: Any)

NeTMY NV-relaxometry instance (arXiv 2605.13988).

  • band_center (property)
  • baselines(self) -> dict[str, Callable[[Measurement], tuple[InverseProblem, Curriculum]]] — grid (Tikhonov, F2), grid_f1, f1 (NeTMY under F1), f2 (NeTMY, F2).
  • build_grid_problem(self, measurement: Measurement, mode: str = 'F2') -> tuple[InverseProblem, Curriculum] — Tikhonov free-density baseline (NeTMY App. E.2): grid ρ ≥ 0 (softplus) + ℓ2 + TV.
  • build_problem(self, measurement: Measurement, mode: str | None = None, field=None, seed: int | None = None) -> InverseProblem — NeTMY problem for measurement under inversion operator mode ("F2" | "F1").
  • build_problem_measurement_shape(self, field_shape: Sequence[int]) -> tuple[int, ...]
  • compare(self, seed: int = 0, scene_class: str | None = None, methods: Sequence[str] = ('netmy', 'f1', 'grid', 'grid_f1'), device: str = 'auto', step_scale: float = ... — Run several methods on the same F3-generated sample (NeTMY Tab. 1 in one call).
  • data_generator(self) -> NVDataGenerator — F3 (default) or F2/F1 (matched-operator) data generator with relative noise.
  • default_curriculum(self) -> Curriculum — Tab. 6: 32² (3000 steps, η) → 64² (7000 steps, η/2), cosine to 0.01η, β reset.
  • direct_simulator(self) -> NVDirectSimulator — Source-side direct simulator F3 (NeTMY Eq. 11), float64.
  • domain(self) -> Domain
  • evaluate(self, result: Result, gt: Mapping[str, torch.Tensor]) -> dict[str, float] — Density metrics on result.fields["rho"] (scale-corrected) + Larmor MAE on support.
  • field(self, seed: int | None = None) -> NeuralField — Coordinate MLP with annealed Fourier features (Tab. 5, Eq. 27).
  • frequencies(self, dtype: torch.dtype = torch.float32) -> torch.Tensor
  • heads(self) -> Heads — ρ = gated softplus (Eq. 5); ω_L = support-masked bounded head (Eq. 26).
  • kernels(self) -> DipolarKernels
  • log_eps(self, measurement: Measurement | None = None) -> float — Additive constant of the log-MSE (Eq. 19): paper 1e-10, or the noise floor of N̂.
  • losses(self, measurement: Measurement | None = None) -> LossSet — NeTMY objective Eq. (6), Tab. 7 weights (log_mse = D, noise_map = R_nm, ...).
  • metrics(self) -> dict[str, Callable] — GMSD, Hungarian F1, SWD (primary) + density MSE, masked SSIM (App. E.3).
  • operator(self, mode: str | None = None, domain: Domain | None = None) -> NVOperator — Inversion operator F2 / F1 (NeTMY Eq. 2) on domain (default native).
  • postprocess(self) -> list
  • run(self, seed: int = 0, device: str = 'auto', scene_class: str | None = None, curriculum: Curriculum | None = None, callbacks: Sequence = (), **solver_kw: Any)... — Generate one sample (F3 + noise), invert it with NeTMY and evaluate (Algorithm 1).
  • scene_generator(self) -> NVScenes

class NVRelaxometryConfig(n: int = 64, spacing: float = 20.0, z0: float = 20.0, gamma: float = 0.5, larmor_band: tuple[float, float] = (1.5, 2.5), freq_range: tuple[float, float] = (...

Configuration of the NV-relaxometry instance; defaults follow NeTMY.

def build_problem(measurement: Measurement, mode: str = 'F2', cfg: NVRelaxometryConfig | Mapping | None = None, **overrides: Any) -> InverseProblem

NeTMY :class:InverseProblem for measurement under mode ("F2" | "F1").

def default_curriculum(cfg: NVRelaxometryConfig | Mapping | None = None, **overrides) -> Curriculum

Tab. 6 curriculum for cfg.

def make_problem(seed: int = 0, scene: str | None = None, mode: str = 'F2', **cfg: Any) -> tuple[InverseProblem, dict[str, torch.Tensor], Measurement]

Convenience: (problem, gt, measurement) for docs, tests and notebooks.

def run(cfg: NVRelaxometryConfig | Mapping | None = None, seed: int = 0, **run_kw: Any) -> tuple[Result, dict[str, float]]

End-to-end demo (DESIGN §3.10): generate (F3) → invert (NeTMY) → evaluate.

nefi.instances.nv_relaxometry.data

Measurement generation for NV relaxometry (NeTMY App. E.1).

class NVDataGenerator(operator, noise_std: float = 0.01, relative: bool = True, dtype: torch.dtype = torch.float64, device: str | torch.device = 'cpu', fidelity_tag: str | None =...

Data generator with noise relative to max(S) − min(S) of each clean spectrum.

  • add_noise(self, clean: torch.Tensor, rng: np.random.Generator, noise_std: float | None = None) -> tuple[torch.Tensor, float]
  • generate(self, gt_fields: dict[str, torch.Tensor], rng: np.random.Generator, noise_std: float | None = None, target_shape=None) -> Measurement

def downsample_spectrum(measurement: Measurement, shape) -> Measurement

Area-average the spatial dims of a (n_freq, H, W) spectrum to shape = (h, w).

nefi.instances.nv_relaxometry.losses

NeTMY-specific loss terms (App. D.4) and noise-map helpers.

class DirectDensityLoss(field: str = 'rho', freq_axis: int = 0, eps: float = 1e-12, name: str | None = None)

Direct-density proxy R_ds = MSE(ρ² / mean ρ², N_obs / mean N_obs) (NeTMY App. D.4).

  • forward(self, ctx: Context) -> torch.Tensor

def noise_map(spectrum: torch.Tensor, freq_axis: int = 0) -> torch.Tensor

Frequency-summed noise map N(r; S) = Σ_{ω∈W} S(ω, r) (NeTMY §3.2, App. B.1).

def normalized_noise_map(spectrum: torch.Tensor, how: str = 'max', freq_axis: int = 0, eps: float = 1e-30) -> torch.Tensor

N̂ = N / max N (how="max", Eq. 19) or N / mean N (how="mean", R_nm).

nefi.instances.nv_relaxometry.operator

NV relaxometry forward operators F1 / F2 (FFT-factorized) and F3 (direct, source-side).

class NVDirectSimulator(domain: Domain, freqs: torch.Tensor | Sequence[float], z0: float = 20.0, gamma: float = 0.5, units: str = 'normalized', length_scale: float = 1e-09, nv_axis...

Source-side direct simulator F3 (NeTMY Eq. 11), float64, no FFT factorization.

  • extra_repr(self) -> str
  • forward(self, fields: Fields) -> torch.Tensor
  • n_freq (property)
  • output_shape(self, shape: Sequence[int]) -> tuple[int, ...]
  • required_fields(self) -> tuple[str, ...]

class NVOperator(domain: Domain, freqs: torch.Tensor | Sequence[float], z0: float = 20.0, gamma: float = 0.5, mode: str = 'F2', units: str = 'normalized', length_scale: floa...

FFT-factorized NV relaxometry operator (NeTMY Eq. 2): {rho, omega_L} -> S(ω, r).

  • at_resolution(self, shape: Sequence[int]) -> NVOperator
  • extra_repr(self) -> str
  • fidelity_tag (property) — Physics/discretization tag for the benchmark inverse-crime guard ("F2-fft").
  • forward(self, fields: Fields) -> torch.Tensor
  • kernel(self, shape: Sequence[int] | None = None, device=None, dtype=None) -> torch.Tensor — The sampled convolution kernel (P or G_zz) for a field grid of shape.
  • lorentzian(self, omega_L: torch.Tensor) -> torch.Tensor — L(ω; ω_L(r)) at the readout pixels, shape (n_freq, *omega_L.shape).
  • n_freq (property)
  • output_shape(self, shape: Sequence[int]) -> tuple[int, ...]
  • required_fields(self) -> tuple[str, ...]
  • spatial_response(self, fields: Fields) -> torch.Tensor — Frequency-independent spatial factor: P ∗ ρ (F2) or (G_zz ∗ ρ)² (F1).

nefi.instances.nv_relaxometry.physics

NV-relaxometry physics: dipolar Green tensor, tensor power kernels and the Lorentzian.

class DipolarKernels(z0: float = 20.0, units: str = 'normalized', length_scale: float = 1e-09, nv_axis: tuple[float, float, float] = (0.0, 0.0, 1.0))

Dipolar kernels for an NV array at standoff z0 (NeTMY Eq. 1-2, App. A).

  • channel(self, offsets: torch.Tensor, a: str | int) -> torch.Tensor — Single channel G_nv,a for a ∈ {x, y, z}.
  • channel_fn(self, a: str | int) -> KernelFn — (spacing, shape, device, dtype) -> G_nv,a sampled on the offset grid.
  • channels(self, offsets: torch.Tensor) -> torch.Tensor — NV-projected channels G_nv,a(R) = Σ_i n_i G_ia(R), shape (..., 3) (a = x, y, z).
  • nv(self, offsets: torch.Tensor) -> torch.Tensor — Scalar NV-axis kernel G_nn(R) = Σ_a n_a G_nv,a(R) (G_zz for n = z; F1).
  • nv_fn(self) -> KernelFn — (spacing, shape, device, dtype) -> G_nn (G_zz) sampled on the offset grid.
  • peak (property) — Peak of |G_zz| for a z-aligned NV in the chosen units (1 when normalized).
  • power(self, offsets: torch.Tensor) -> torch.Tensor — Tensor power kernel P(R) = Σ_a |G_nv,a(R)|² (NeTMY Eq. 2 F2, Eq. 11).
  • power_fn(self) -> KernelFn — (spacing, shape, device, dtype) -> P sampled on :func:kernel_offsets.

def channel_kernel_fn(a: str | int, z0: float, units: str = 'normalized', length_scale: float = 1e-09, nv_axis: Sequence[float] = (0.0, 0.0, 1.0)) -> KernelFn

Kernel callable for a single channel G_az (a ∈ {x, y, z}; App. A.1, Fig. 6).

def dipolar_green_tensor(R: torch.Tensor, prefactor: float = 1.0000000000000001e-07) -> torch.Tensor

Dipolar Green tensor G_ia(R) = c (3 R_i R_a − |R|² δ_ia) / |R|⁵ (NeTMY Eq. 1).

def frequency_grid(lo: float = 1.0, hi: float = 3.0, n: int = 50, dtype: torch.dtype = torch.float32) -> torch.Tensor

Uniform readout frequency grid W (NeTMY App. E.1: 50 frequencies).

def gzz_kernel_fn(z0: float, units: str = 'normalized', length_scale: float = 1e-09, nv_axis: Sequence[float] = (0.0, 0.0, 1.0)) -> KernelFn

Kernel callable for the F1 NV-axis kernel G_nv = Σ_a n_a G_az (G_zz, Eq. 2).

def lorentzian(omega: torch.Tensor | float, omega_L: torch.Tensor | float, gamma: float) -> torch.Tensor

Lorentzian spectral response L(ω; ω_L) = γ² / ((ω − ω_L)² + γ²) (NeTMY Eq. 13).

def power_kernel_fn(z0: float, units: str = 'normalized', length_scale: float = 1e-09, nv_axis: Sequence[float] = (0.0, 0.0, 1.0)) -> KernelFn

Kernel callable for the F2 tensor power kernel P = Σ_a |G_az|² (NeTMY Eq. 2).

nefi.instances.nv_relaxometry.scenes

Sparse spin-source scenes for NV relaxometry (NeTMY App. E.1).

class NVScenes(domain: Domain, z0: float = 20.0, larmor_band: Sequence[float] = (1.5, 2.5), background_larmor: float | None = None, amp_range: Sequence[float] = (0.5, 1.0)...

Ground-truth {"rho", "omega_L"} scenes with sparse point sources (NeTMY App. E.1).

  • check_class(self, cls: str | None) -> str
  • render(self, sources: Mapping, shape: Sequence[int] | None = None) -> dict — Rasterize sources (from :meth:sample_sources) on a grid of shape.
  • sample(self, rng: np.random.Generator, cls: str | None = None, shape: Sequence[int] | None = None) -> dict[str, torch.Tensor]
  • sample_sources(self, rng: np.random.Generator, cls: str | None = None) -> dict — Sample source positions (physical), amplitudes and Larmor frequencies for cls.

def normalize_class(cls: str) -> str

Canonical "<count>/<separation>" form (accepts _, - or / separators).

nefi.instances.photoacoustic3d

photoacoustic3d — 3-D photoacoustic tomography (PAT) from a planar sensor array.

class Photoacoustic3D(cfg: Any = None, preset: str | None = None, **overrides: Any)

3-D planar-array photoacoustic tomography instance (see module docstring).

  • baselines(self) -> dict[str, Callable[[Measurement], tuple[InverseProblem, Curriculum]]]
  • build_problem(self, measurement: Measurement) -> InverseProblem
  • build_problem_measurement_shape(self, field_shape)
  • data_generator(self) -> DataGenerator
  • default_curriculum(self) -> Curriculum
  • domain(self) -> Domain
  • field(self) -> NeuralField
  • heads(self) -> Heads
  • losses(self) -> LossSet
  • metrics(self) -> dict[str, Callable]
  • n_t (property)
  • operator(self, domain: Domain | None = None, order: int | None = None) -> SensorBandwidth — Inversion operator: the wave solver followed by the sensors' bandwidth.
  • scene_generator(self) -> SceneGenerator
  • sensors(self) -> torch.Tensor — Sensor positions (n_sx · n_sy, 3): a regular grid on the top face.
  • time_reversal(self, measurement: Measurement, mode: str | None = None) -> torch.Tensor — Time-reversal (or adjoint) reconstruction on the native grid, clipped to ≥ 0.
  • wave_operator(self, domain: Domain | None = None, order: int | None = None) -> WaveInitialConditionOperator — The bare wave solver (ideal point sensors).

class Photoacoustic3DConfig(extent: tuple[float, float, float] = (12.0, 12.0, 8.0), grid: tuple[int, int, int] = (48, 48, 32), sound_speed: float = 1.5, sensor_grid: tuple[int, int] = ...

Configuration of the :class:Photoacoustic3D instance (every number is a field; mm, µs).

def make_problem(seed: int = 0, scene: str | None = None, **cfg: Any) -> tuple[InverseProblem, dict[str, torch.Tensor], Measurement]

Convenience: (problem, gt, measurement) for docs and tests.

def run(cfg: Photoacoustic3DConfig | dict | None = None, seed: int = 0, **kw: Any)

End-to-end demo (generate → invert → evaluate); returns a RunOutput.

nefi.instances.photoacoustic3d.scenes

Initial-pressure (absorbed-energy) phantoms for 3-D photoacoustic tomography (physical mm).

class PAT3DScenes(domain: Domain, vessel_radius: tuple[float, float] = (0.3, 0.6), sphere_radius: tuple[float, float] = (0.6, 1.5), edge_width: float = 0.15, depth_range: tup...

Initial pressure p0(x, y, z) ≥ 0 (arbitrary units, ≲ 1; depth = last axis).

  • sample(self, rng, cls=None, shape=None)
  • spheres(self, rng: np.random.Generator) -> Painter3D
  • vessels(self, rng: np.random.Generator) -> Painter3D

nefi.instances.photoacoustic3d.sensor

Finite sensor bandwidth: a zero-phase Gaussian low-pass of the pressure traces.

class SensorBandwidth(inner: Operator, dt_obs: float, f_cutoff: float | None)

Wraps a trace operator (…, n_t) with the sensors' low-pass response.

  • at_resolution(self, shape: Sequence[int]) -> SensorBandwidth
  • extra_repr(self) -> str
  • forward(self, fields: Fields) -> torch.Tensor
  • output_shape(self, shape: Sequence[int]) -> tuple[int, ...] | None
  • required_fields(self) -> tuple[str, ...]

def gaussian_lowpass(traces: torch.Tensor, dt: float, f_cutoff: float | None) -> torch.Tensor

Zero-phase Gaussian low-pass exp(−½ (f/f_c)²) along the last axis (sample step dt).

nefi.instances.poisson_source

poisson_source — PDE-constrained source recovery for the Poisson equation (elliptic).

class PoissonSource(cfg: Any | Mapping | None = None, **overrides: Any)

Elliptic source-recovery instance (see module docstring).

  • baselines(self) -> dict[str, Callable[[Measurement], tuple[InverseProblem, Curriculum]]]
  • build_problem(self, measurement: Measurement) -> InverseProblem
  • build_problem_measurement_shape(self, field_shape)
  • data_generator(self) -> DataGenerator
  • default_curriculum(self) -> Curriculum
  • domain(self) -> Domain
  • field(self) -> NeuralField
  • heads(self) -> Heads
  • losses(self) -> LossSet
  • metrics(self) -> dict[str, Callable]
  • operator(self, domain: Domain | None = None) -> PoissonOperator
  • scene_generator(self) -> SceneGenerator

class PoissonSourceConfig(n: int = 64, extent: float = 1.0, conductivity: float = 1.0, spectrum: str = 'continuous', scene: str = 'blobs', point_cells: float = 0.8, obs_mode: str = '...

Configuration of the :class:PoissonSource instance (all numbers are config fields).

def make_problem(n: int = 64, seed: int = 0, scene: str | None = None, **cfg) -> tuple[InverseProblem, dict[str, torch.Tensor], Measurement]

Convenience: (problem, gt, measurement) for docs and tests.

def run(cfg: PoissonSourceConfig | dict | None = None, seed: int = 0, **kw)

End-to-end demo (generate → invert → evaluate); returns a RunOutput.

nefi.instances.poisson_source.data

Sparse / boundary observation data for the Poisson source problem, and masked downsampling.

class PoissonDataGenerator(operator: Operator, noise_std: float = 0.01, obs_mode: str = 'random', obs_fraction: float = 0.1, boundary_width: int = 3, relative: bool = True, dtype: tor...

Finite-difference solve on a finer grid (float64), area-average, sample a mask, add noise.

  • generate(self, gt_fields: dict[str, torch.Tensor], rng: np.random.Generator, noise_std: float | None = None, target_shape: Sequence[int] | None = None) -> Measurement

def masked_downsample(measurement: Measurement, shape: Sequence[int]) -> Measurement

Mask-aware area downsampling for coarse curriculum stages.

def observation_mask(shape: Sequence[int], rng: np.random.Generator, mode: str = 'random', fraction: float = 0.1, boundary_width: int = 3) -> torch.Tensor

Binary observation mask: a random pixel subset, a boundary strip, or everything.

nefi.instances.poisson_source.operator

Differentiable spectral Poisson solver (discrete sine transforms via torch.fft).

class FDPoissonOperator(domain: Domain, field: str = 'f', conductivity: float = 1.0)

Non-differentiable finite-difference Poisson solver used by the data generator.

  • at_resolution(self, shape: Sequence[int]) -> FDPoissonOperator
  • forward(self, fields: Fields) -> torch.Tensor
  • output_shape(self, shape: Sequence[int]) -> tuple[int, ...]

class PoissonOperator(domain: Domain, field: str = 'f', conductivity: float = 1.0, spectrum: str = 'continuous')

Source-to-potential map f ↦ u = (-κ Δ)^{-1} f (Dirichlet), spectral and differentiable.

  • at_resolution(self, shape: Sequence[int]) -> PoissonOperator
  • eigenvalues(self, device=None, dtype=None) -> torch.Tensor — Eigenvalues λ of -κΔ on the operator's grid, shape domain.shape.
  • forward(self, fields: Fields) -> torch.Tensor
  • laplacian(self, u: torch.Tensor) -> torch.Tensor — Spectral -κΔu (the inverse map), for residual checks.
  • output_shape(self, shape: Sequence[int]) -> tuple[int, ...]

def dst1(x: torch.Tensor, dim: int = -1) -> torch.Tensor

Unnormalized DST-I X_k = Σ_n x_n sin(π (n + 1)(k + 1) / (N + 1)) along dim.

def dst2(x: torch.Tensor, dim: int = -1) -> torch.Tensor

Unnormalized DST-II X_k = Σ_n x_n sin(π (n + ½)(k + 1) / N) along dim.

def fd_poisson_solve(f: np.ndarray, spacing: Sequence[float], conductivity: float = 1.0) -> np.ndarray

Finite-difference solve of -κΔu = f (float64, scipy sparse direct solver).

def idst1(X: torch.Tensor, dim: int = -1) -> torch.Tensor

Inverse of :func:dst1 (DST-I is an involution up to 2 / (N + 1)).

def idst2(X: torch.Tensor, dim: int = -1) -> torch.Tensor

Inverse of :func:dst2 along dim (a scaled DST-III).

nefi.instances.poisson_source.scenes

Non-negative source fields for the Poisson source problem (cell-averaged, grid-consistent).

class SourceScenes(domain: Domain, point_cells: float = 0.8, render_factor: int = 4)

Source classes (field "f", maximum ≈ 1):

  • blobs(self, rng: np.random.Generator) -> Painter
  • points(self, rng: np.random.Generator) -> Painter
  • sample(self, rng, cls=None, shape=None)
  • smooth(self, rng: np.random.Generator) -> Painter

nefi.instances.reaction_diffusion

reaction_diffusion — recover a spatially varying Gray–Scott feed rate F(x) from snapshots.

class ReactionDiffusion(cfg: Any | Mapping | None = None, **overrides: Any)

Gray–Scott feed-rate inversion instance (see module docstring).

  • baselines(self)
  • build_problem(self, measurement: Measurement) -> InverseProblem
  • build_problem_measurement_shape(self, field_shape)
  • data_generator(self) -> DataGenerator
  • default_curriculum(self, lr_mult: float = 1.0) -> Curriculum
  • domain(self) -> Domain
  • field(self) -> NeuralField
  • heads(self) -> Heads
  • initial_model(self) -> torch.Tensor
  • losses(self) -> LossSet
  • metrics(self) -> dict[str, Callable]
  • operator(self, domain: Domain | None = None, substeps: int = 1) -> ReactionDiffusionOperator
  • scene_generator(self) -> SceneGenerator

class ReactionDiffusionConfig(n: int = 32, extent: float = 0.64, scene: str = 'blobs', F_background: float = 0.045, F_amplitude: float = 0.015, F_min: float = 0.02, F_max: float = 0.07, ...

Configuration (defaults = CPU smoke preset: 32², 4 snapshots of u and v, 100 steps).

class ReactionDiffusionScenes(domain: Domain, cfg: ReactionDiffusionConfig)

Feed-rate fields F(x) (analytic, any resolution).

  • sample(self, rng: np.random.Generator, cls: str | None = None, shape=None)

def make_problem(seed: int = 0, **cfg)

Convenience: (problem, gt, measurement).

def run(cfg=None, seed: int = 0, **kw)

End-to-end demo (DESIGN §3.10): (result, metrics).

nefi.instances.sparse_view_ct

sparse_view_ct — parallel-beam CT from a few views with a differentiable Radon transform.

class SparseViewCT(cfg: Any | Mapping | None = None, **overrides: Any)

Sparse-view parallel-beam CT instance (see module docstring).

  • angles(self) -> torch.Tensor
  • baselines(self) -> dict[str, Callable[[Measurement], tuple[InverseProblem, Curriculum]]]
  • build_problem(self, measurement: Measurement) -> InverseProblem
  • build_problem_measurement_shape(self, field_shape)
  • data_generator(self) -> DataGenerator
  • default_curriculum(self) -> Curriculum
  • domain(self) -> Domain
  • fbp(self, measurement: Measurement, filter: str | None = None) -> torch.Tensor — Filtered back-projection of measurement on the native grid.
  • field(self) -> NeuralField
  • heads(self) -> Heads
  • losses(self) -> LossSet
  • metrics(self) -> dict[str, Callable]
  • operator(self, domain: Domain | None = None) -> RadonOperator
  • scene_generator(self) -> SceneGenerator

class SparseViewCTConfig(n: int = 64, extent: float = 1.0, n_views: int = 20, angle_range: float = 180.0, det_per_pixel: float = 1.0, samples_per_pixel: float = 1.0, scene: str = 's...

Configuration of the :class:SparseViewCT instance (all numbers are config fields).

def make_problem(n: int = 64, seed: int = 0, scene: str | None = None, **cfg) -> tuple[InverseProblem, dict[str, torch.Tensor], Measurement]

Convenience: (problem, gt, measurement) for docs and tests.

def run(cfg: SparseViewCTConfig | dict | None = None, seed: int = 0, **kw)

End-to-end demo (generate → invert → evaluate); returns a RunOutput.

nefi.instances.sparse_view_ct.radon

Differentiable parallel-beam Radon transform, back-projection and filtered back-projection.

class RadonOperator(domain: Domain, n_views: int = 20, field: str = 'mu', angles: torch.Tensor | Sequence[float] | None = None, angle_range: float = 3.141592653589793, det_per_...

Parallel-beam Radon transform μ ↦ sinogram (n_views, n_det) (differentiable, linear).

  • adjoint(self, sinogram: torch.Tensor) -> torch.Tensor — Exact adjoint Rᵀ y of this discretization (autograd VJP; the operator is linear).
  • at_resolution(self, shape: Sequence[int]) -> RadonOperator
  • backproject(self, sinogram: torch.Tensor) -> torch.Tensor — Pixel-driven back-projection ≈ Rᵀ y (independent discretization).
  • dt (property) — Physical ray step Δt.
  • fbp(self, sinogram: torch.Tensor, filter: str = 'ramp', circle: bool = False) — Filtered back-projection onto this operator's grid.
  • forward(self, fields: Fields) -> torch.Tensor
  • n_views (property)
  • output_shape(self, shape: Sequence[int]) -> tuple[int, ...]
  • tau (property) — Physical detector bin width.

def backproject(sinogram: torch.Tensor, angles: torch.Tensor, n: int | None = None, width: float = 1.0, samples_per_pixel: float = 1.0) -> torch.Tensor

Pixel-driven back-projection, scaled to approximate the adjoint of :class:RadonOperator.

def fbp(sinogram: torch.Tensor, angles: torch.Tensor | Sequence[float], filter: str = 'ramp', *, n: int | None = None, width: float = 1.0, circle: bool = False) -> ...

Filtered back-projection f ≈ (π / V) Σ_θ q_θ(x cos θ + y sin θ), q = (h ⊛ p) / τ.

def ramp_filter(sinogram: torch.Tensor, filter: str = 'ramp', pad_factor: int = 2) -> torch.Tensor

Convolve each projection with the Kak-Slaney ramp at unit bin spacing (± window).

def uniform_angles(n_views: int, angle_range: float = 3.141592653589793) -> torch.Tensor

n_views equispaced angles in [0, angle_range) (radians, float64).

nefi.instances.sparse_view_ct.scenes

Procedural CT phantoms (normalized coordinates, inside the field of view, values in [0, 1]).

class CTScenes(domain: Domain, render_factor: int = 4)

Attenuation phantoms for sparse-view CT.

  • blobs(self, rng: np.random.Generator) -> Painter
  • piecewise(self, rng: np.random.Generator) -> Painter
  • sample(self, rng, cls=None, shape=None)
  • shepp(self, rng: np.random.Generator) -> Painter

nefi.instances.thermal_tomography

thermal_tomography — NeFTY: 3-D inverse heat conduction from pulsed-thermography surface frames.

class ThermalTomography(cfg: Any = None, preset: str | None = None, **overrides: Any)

NeFTY thermal tomography (pulsed thermography, 3-D inverse heat conduction).

  • baselines(self) -> dict[str, Callable[[Measurement], tuple[InverseProblem, Curriculum]]] — Baselines on the same measurement.
  • boundary_conditions(self) -> tuple[str, ...]
  • build_problem(self, measurement: Measurement) -> InverseProblem
  • build_problem_measurement_shape(self, field_shape: Sequence[int]) -> tuple[int, ...]
  • data_generator(self) -> DataGenerator
  • default_curriculum(self) -> Curriculum — Single stage (paper): Adam, step decay ×0.1 / 1000, annealing over the first anneal_steps (Tab. 5); n_stages > 1 gives a coarse-to-fine curriculum.
  • domain(self) -> Domain
  • evaluate(self, result: Result, gt: Mapping[str, torch.Tensor], measurement: Measurement | None = None) -> dict[str, float] — Volumetric metrics, App. H projections and — given the measurement — the surface-fit PSNR of the recovered field's re-simulation next to that of the initial uniform field (the data-fit-paradox diagnostic, NeFTY §5.2 / App. G.2).
  • field(self) -> NeuralField — NeFTY neural diffusivity field (App. D.1, Tab. 5).
  • heads(self) -> Heads
  • initial_condition(self) — Post-flash temperature (App. A.5): Gaussian (synthetic) or near-uniform flash (PVC).
  • losses(self) -> LossSet — Surface MSE + isotropic TV (Eq. 22: lateral periodic differences, zero δz on the last slice, physical spacing).
  • make_measurement(self, seed: int = 0, scene_class: str | None = None, gt: Mapping[str, torch.Tensor] | None = None) -> tuple[dict[str, torch.Tensor], Measurement] — Draw a scene, simulate it with the explicit float64 simulator (optionally on a sim_supersample× finer grid), add noise.
  • metrics(self) -> dict[str, Callable] — Volumetric metrics of NeFTY App. E.2 / G.5 on the diffusivity field.
  • obs_frames(self) -> tuple[int, ...]
  • operator(self, domain: Domain | None = None, **overrides: Any) -> HeatOperator — The inversion operator (implicit Euler + Jacobi/CG + discrete adjoint).
  • projection_metrics(self, alpha: torch.Tensor, gt: torch.Tensor, gt_mask: torch.Tensor | None = None) -> dict[str, float] — App. H projections evaluated against the ground truth: 2-D footprint IoU / Dice and 2.5-D depth AbsRel / RMSE / δ<1.25 on the correctly detected pixels.
  • run(self, seed: int = 0, device: str = 'auto', scene_class: str | None = None, curriculum: Curriculum | None = None, callbacks: Sequence = (), **solver_kw: Any)... — Generate → invert → evaluate (with the surface-fit diagnostics).
  • scene_generator(self) -> ThermalScenes
  • simulator(self, domain: Domain | None = None) -> ExplicitHeatSimulator — The independent data simulator (explicit, substepped, float64; App. E.1).
  • surface_metrics(self, pred: torch.Tensor, measurement: Measurement, reference: torch.Tensor | None = None) -> dict[str, float] — Surface-fit MSE / PSNR of re-simulated frames against the observed frames (App. G.2); PSNR uses the observed data range.
  • uniform_prediction(self, value: float | None = None, dtype=torch.float64) -> torch.Tensor — Frames predicted by the inversion operator for a uniform field (the initial iterate).

class ThermalTomographyConfig(extent: tuple[float, ...] = (10.0, 10.0, 1.0), grid: tuple[int, ...] = (64, 64, 16), dt: float = 0.05, n_frames: int = 100, first_frame: int = 1, frame_stri...

NeFTY configuration; defaults reproduce NeFTY Tab. 5 / App. A.5 / E.1 (see the docs page docs/instances/thermal_tomography.md for the field-by-field mapping).

def surface_downsample(measurement: Measurement, field_shape: Sequence[int]) -> Measurement

Measurement at a coarse curriculum stage: surface frames area-averaged laterally.

nefi.instances.thermal_tomography.pinn

Soft-constrained PINN baseline for thermal tomography (NeFTY Eq. 4, §3.3, App. C / F.1).

class InitialConditionLoss(initial: Callable[[Domain], torch.Tensor], normalize: bool = True, name=None)

mean (T_φ(x, 0) − T0(x))² on the cell centres of the current grid (NeFTY Eq. 4).

  • forward(self, ctx: Context) -> torch.Tensor

class NormalizedSurfaceMSE(scale: float = 100.0, name: str | None = None)

mean (T_φ|_Γ − T̂)² / scale² — the PINN data term in the same dimensionless units as the residual and initial-condition penalties.

  • forward(self, ctx: Context) -> torch.Tensor

class PDEResidualLoss(n_points: int = 24576, normalize: bool = True, name: str | None = None)

mean r² with r = ∂_t T_φ − α_θ ΔT_φ − ∇α_θ·∇T_φ at random collocation points (NeFTY Eq. 4 / App. C.1, Eq. 19). Space is sampled uniformly in the slab, time in (0, t_end]; derivatives are taken by autograd in physical units.

  • forward(self, ctx: Context) -> torch.Tensor

class SoftPINNSurface(domain: Domain, frame_times: Sequence[float], t_end: float, tnet: TemperatureNet, field: str = 'alpha')

The PINN's "forward model": T_φ read off at the observed surface and frame times.

  • at_resolution(self, shape: Sequence[int]) -> SoftPINNSurface
  • forward(self, fields: Fields) -> torch.Tensor
  • normalize(self, x_phys: torch.Tensor, t: torch.Tensor) -> torch.Tensor — Physical (…, ndim) coordinates and times (…) → normalized (…, ndim + 1).
  • output_shape(self, shape: Sequence[int]) -> tuple[int, ...]
  • temperature(self, x_phys: torch.Tensor, t: torch.Tensor) -> torch.Tensor

class TemperatureNet(ndim: int, hidden: int = 128, depth: int = 5, n_octaves: int = 0, scale: float = 100.0)

T_φ(x, t): tanh MLP on (optionally Fourier-encoded) normalized space-time coordinates.

  • forward(self, xt: torch.Tensor) -> torch.Tensor — xt: (..., ndim + 1) normalized (x, [y,] z, t) → temperature (...).

nefi.instances.thermal_tomography.projection

Projections of a reconstructed 3-D diffusivity to 2-D defect masks and 2.5-D depth maps.

def bulk_profile(alpha: torch.Tensor, alpha_base: float | torch.Tensor | None = None) -> torch.Tensor

Bulk (defect-free) diffusivity broadcast to alpha's shape.

def defect_mask_2d(alpha: torch.Tensor, alpha_base: float | torch.Tensor | None = None, k: float = 2.0, min_sigma: float = 0.001, return_info: bool = False, mad_of: str = 'sig...

2-D defect mask from a 3-D diffusivity (NeFTY App. H.3).

def depth_map_25d(alpha: torch.Tensor, alpha_base: float | torch.Tensor | None = None, mask2d: torch.Tensor | None = None, depth_coords: Sequence[float] | torch.Tensor | None...

2.5-D defect depth map (NeFTY App. H.3).

def gt_depth_map(defect_mask: torch.Tensor, depth_coords: Sequence[float] | torch.Tensor | None = None, thickness: float | None = None, reduce: str = 'median') -> torch.Tensor

Ground-truth 2.5-D depth labels from a 3-D defect mask (same reduction as the prediction).

def mad_sigma(x: torch.Tensor) -> torch.Tensor

Robust standard deviation 1.4826 · median(|x − median(x)|).

nefi.instances.thermal_tomography.realdata

Real pulsed-thermography data: loading, ambient shift, physical ↔ unitless scaling (NeFTY App. A.5 / H).

class PhysicalScales(alpha_phys: float, L0: float, thickness: float, t_total: float, lateral_size: tuple[float, float] | None = None)

Dimensional scales of a specimen and its recording (App. A.5, H.2).

  • extent(self) -> tuple[float, float, float]
  • fourier_number (property) — Fo = α_phys · t_total / L0² — the unitless bulk diffusivity α_sim.
  • physical_alpha(self, alpha_sim: float | torch.Tensor)
  • physical_length(self, x_sim: float | torch.Tensor)
  • physical_time(self, t_sim: float) -> float
  • unitless_alpha(self, alpha_phys: float | torch.Tensor | None = None)
  • unitless_length(self, x_phys: float) -> float
  • unitless_time(self, t_phys: float) -> float

def config_for_frames(measurement: Measurement, scales: PhysicalScales, *, nz: int = 16, base: dict[str, Any] | None = None, **overrides: Any) -> dict[str, Any]

Config overrides for :class:ThermalTomography matching a real measurement.

def load_frames(path: str | Path, key: str | None = None, dtype=torch.float32) -> torch.Tensor

Load a surface temperature sequence (n_t, H, W) from a local file or directory.

def measurement_from_frames(frames: torch.Tensor, *, dt: float, t_ambient: float | torch.Tensor | None = None, pre_flash_frames: int = 0, first_frame: int = 1, frame_stride: int = 1, c...

Ambient-shift, crop, subsample and package recorded frames as a :class:Measurement.

def physical_depth_map(depth_sim: torch.Tensor, scales: PhysicalScales, unit: str = 'mm')

Convert a unitless depth map (fraction of L0) to physical units.

def pvc_overrides(scales: PhysicalScales, *, robin_h: float = 0.0, lateral: str = 'neumann', alpha_contrast: float = 50.0, flash_width_z: float | None = None) -> dict[str, Any]

The three PVC adaptations of App. H.2 as config overrides.

nefi.instances.thermal_tomography.scenes

Synthetic subsurface-defect scenes for pulsed-thermography tomography (NeFTY App. E.1).

class DefectSpec(kind: str, center: tuple[float, ...], radii: tuple[float, ...], half_thickness: float, angle: float, alpha: float)

One buried defect (physical units).

class SceneSpec(cls: str, layer_bounds: tuple[float, ...], layer_alpha: tuple[float, ...], defects: list[DefectSpec] = <factory>)

Parameters of one sample: scene class, bulk strata and defects.

  • to_dict(self) -> dict

class ThermalScenes(domain: Domain, alpha_base_range: Sequence[float] = (0.1, 0.2), alpha_defect_range: Sequence[float] = (0.005, 0.015), n_defects: Sequence[int] = (1, 4), n_l...

Scene generator with classes "homogeneous" and "layered" (NeFTY App. E.1).

  • draw(self, rng: np.random.Generator, cls: str | None = None) -> SceneSpec — Draw the scene parameters (the number of random draws does not depend on shape).
  • rasterize(self, spec: SceneSpec, shape: Sequence[int] | None = None) -> tuple[dict[str, torch.Tensor], dict] — Evaluate a scene on the cell centres of shape (default: the domain's grid).
  • sample(self, rng: np.random.Generator, cls: str | None = None, shape: Sequence[int] | None = None) -> dict[str, torch.Tensor] — Ground-truth fields {"alpha": (*shape)} for one random scene.
  • sample_with_meta(self, rng: np.random.Generator, cls: str | None = None, shape: Sequence[int] | None = None) -> tuple[dict[str, torch.Tensor], dict] — Like :meth:sample but also returns the bulk field, defect mask and parameters.
  • thickness (property)

nefi.instances.toy1d

toy1d — recover a 1-D non-negative signal from its blurred, noisy observation.

class Toy1D(cfg: Any | Mapping | None = None, **overrides: Any)

  • baselines(self)
  • build_problem(self, measurement: Measurement) -> InverseProblem
  • build_problem_measurement_shape(self, field_shape)
  • data_generator(self) -> DataGenerator
  • default_curriculum(self) -> Curriculum
  • domain(self) -> Domain
  • field(self) -> NeuralField
  • metrics(self) -> dict[str, Callable]
  • operator(self, domain: Domain | None = None) -> FFTConvolution
  • scene_generator(self) -> SceneGenerator

class Toy1DConfig(n: int = 128, sigma: float = 0.02, noise_std: float = 0.01, scene: str = 'bumps', supersample: int = 4, hidden: int = 64, depth: int = 4, n_octaves: int = 6...

Toy1DConfig(n: 'int' = 128, sigma: 'float' = 0.02, noise_std: 'float' = 0.01, scene: 'str' = 'bumps', supersample: 'int' = 4, hidden: 'int' = 64, depth: 'int' = 4, n_octaves: 'int' = 6, steps: 'tuple[int, int]' = (300, 600), lr: 'float' = 0.01, tv: 'float' = 0.0001, l1: 'float' = 0.0)

class Toy1DScenes(domain: Domain)

  • sample(self, rng, cls=None, shape=None)

def make_problem(n: int = 128, seed: int = 0, **cfg) -> tuple[InverseProblem, dict[str, torch.Tensor], Measurement]

Convenience: (problem, gt, measurement) for docs and tests.

nefi.instances.wave_fwi

wave_fwi — acoustic full-waveform inversion (FWI) of a 2-D sound-speed map.

class TraceDataGenerator(operator, trace_mask: torch.Tensor | None = None, **kw)

:class:~nefi.bench.DataGenerator with an optional trace mask (near-offset mute).

  • generate(self, gt_fields, rng, noise_std=None, target_shape=None) -> Measurement

class WaveFWI(cfg: Any | Mapping | None = None, **overrides: Any)

Acoustic FWI instance (see module docstring).

  • acquisition(self) -> tuple[torch.Tensor, torch.Tensor] — (sources, receivers) physical positions (km).
  • baselines(self)
  • build_problem(self, measurement: Measurement) -> InverseProblem
  • build_problem_measurement_shape(self, field_shape)
  • data_generator(self) -> DataGenerator
  • default_curriculum(self, lr_mult: float = 1.0) -> Curriculum
  • domain(self) -> Domain
  • field(self) -> NeuralField
  • heads(self) -> Heads
  • initial_model(self) -> torch.Tensor — The uniform starting model c_background on the native grid.
  • losses(self) -> LossSet
  • metrics(self) -> dict[str, Callable]
  • n_t (property)
  • offset_mask(self) -> torch.Tensor | None — Near-offset mute: (n_sources, n_receivers, 1) with 0 where the source–receiver distance is below min_offset (None when nothing is muted).
  • operator(self, domain: Domain | None = None, order: int | None = None) -> WaveOperator
  • scene_generator(self) -> SceneGenerator

class WaveFWIConfig(n: int = 24, extent: float = 1.0, scene: str = 'smooth_anomaly', c_background: float = 2.0, c_min: float = 1.5, c_max: float = 2.5, anomaly: float = 0.4, ge...

Configuration (defaults = CPU smoke / gallery preset: 24², surround acquisition with 6 sources and 32 receivers, near offsets < 0.3 km muted, 150 + 250 steps).

class WaveFWIScenes(domain: Domain, cfg: WaveFWIConfig)

Analytic sound-speed models (evaluated at any resolution; km/s).

  • sample(self, rng: np.random.Generator, cls: str | None = None, shape=None)

def make_problem(seed: int = 0, **cfg) -> tuple[InverseProblem, dict[str, torch.Tensor], Measurement]

Convenience: (problem, gt, measurement) for docs and tests.

def run(cfg: dict | WaveFWIConfig | None = None, seed: int = 0, **kw)

End-to-end demo (DESIGN §3.10): generate → invert → evaluate → (result, metrics).

nefi.instances.wave_fwi.losses

Band-limited trace misfit for multiscale (frequency-continuation) full-waveform inversion.

class BandLimitedMSE(f_max: float | None, dt: float, taper: float = 0.3, relative: bool = True, name: str | None = None)

(Relative) MSE between low-pass filtered predicted and observed traces.

  • extra_repr(self) -> str
  • forward(self, ctx: Context) -> torch.Tensor

def lowpass(x: torch.Tensor, dt: float, f_max: float, taper: float = 0.3) -> torch.Tensor

Zero-phase low-pass filter along the last (time) axis with a cosine roll-off.