API — nefi¶
Generated by scripts/gen_api_docs.py — do not edit by hand. Index
nefi¶
nefi — Neural-Field Inversion.
def enable_logging(level: int = 20)¶
Send nefi logs to stderr (idempotent).
def invert(problem: InverseProblem, curriculum: Curriculum | None = None, **solver_kw) -> Result¶
One-call entry point: run Solver(problem, curriculum, **solver_kw).run().
nefi.auto¶
Adaptive defaults — from your differentiable forward model to a ready-to-solve problem.
def auto_curriculum(shape: Sequence[int], budget: str | int = 'default', multiscale: bool = True, representation: str = 'neural', *, lr: float | None = None, noise_known: bool ...¶
A robust default curriculum for a field of grid shape.
def balance_weights(problem: InverseProblem, strengths: Mapping[str, float] | None = None, *, probe_steps: int = 25, lr: float = 0.001, shape: Sequence[int] | None = None, targ...¶
Automatic loss weights: data term = target at the initial iterate, and each regularizer worth strength × target at a reference iterate.
def budget_steps(budget: str | int, shape: Sequence[int]) -> int¶
Total optimization steps for a budget name (scaled by field size) or an explicit int.
def default_lr(representation: str = 'neural', hidden: int | None = None) -> float¶
Default peak learning rate: :data:DEFAULT_LR, scaled by sqrt(64 / hidden) for MLPs.
def default_octaves(shape: Sequence[int]) -> int¶
clamp(ceil(log2(max(shape))), 4, 12) Fourier octaves for a grid.
def estimate_noise(measurement: Measurement | torch.Tensor | np.ndarray, *, axes: Sequence[int] | None = None, method: str = 'auto', order: int | None = None, region: torch.Te...¶
Robust estimate of the additive noise standard deviation of a measurement.
def from_forward(forward: Callable | Operator, measurement: Measurement | torch.Tensor | np.ndarray, shape: Sequence[int] | int, *, extent: Sequence[tuple[float, float]] | N...¶
Build a complete :class:~nefi.problem.InverseProblem from a differentiable forward model.
def lr_range_test(problem: InverseProblem, lrs: Sequence[float] = (0.0001, 0.0003, 0.001, 0.003, 0.01, 0.03, 0.1), steps: int = 20, *, shape: Sequence[int] | None = None, pro...¶
Cheap learning-rate probe: pick the LR with the largest loss decrease without divergence.
def quick_report(result, problem: InverseProblem, gt: Any = None) -> str¶
Compact markdown summary: does the fit reach the noise floor, and what happened.
nefi.cli¶
nefi command-line interface.
class CLIError(...)¶
User-facing command-line error (bad target, missing file, malformed option).
class RunSpec(instance: str, config: dict[str, Any] = <factory>, curriculum: dict[str, Any] | None = None, solver: dict[str, Any] = <factory>, run: dict[str, Any] = <fact...¶
Everything a command needs to build an instance and its solver settings.
def build_parser()¶
The argparse front-end (always available).
def build_typer_app()¶
The typer front-end (same commands and options as :func:build_parser).
def cmd_ablate(target: str, variants: str = Ellipsis, n: int = 4, seeds: str = '0,1,2', independent: bool = False, base: str | None = None, classes: str | None = None, dev...¶
Cumulative (or one-at-a-time) ablation of the instance's method.
def cmd_autotune(target: str, level: str = 'standard', device: str | None = None, seed: int | None = None, scene: str | None = None, out: str | None = None, smoke: bool = Fa...¶
Auto-tune an instance on a fresh measurement; save the report and a tuned config.
def cmd_bench(target: str, methods: str | None = None, n: int = 4, seeds: str = '0,1,2', classes: str | None = None, metrics: str | None = None, device: str | None = None...¶
Paired benchmark of several methods; prints the markdown table and saves the reports.
def cmd_bench_merge(directory: str, out: str | None = None, by_class: bool = False, allow_missing: bool = False, quiet: bool = False, verbose: bool = False) -> int¶
Merge the benchmark shards of a directory into one table (writes the usual reports).
def cmd_diagnose(target: str, device: str | None = None, seed: int | None = None, scene: str | None = None, out: str | None = None, smoke: bool = False, smoke_steps: int = 4...¶
Diagnostics on a fresh measurement (at initialization, or at the solution with --solve).
def cmd_list(kind: str | None = None, verbose: bool = False, as_json: bool = False) -> int¶
List registered components (instances, fields, operators, losses, baselines, metrics…).
def cmd_run(target: str, device: str | None = None, seed: int | None = None, scene: str | None = None, out: str | None = None, smoke: bool = False, smoke_steps: int = 4...¶
Generate a measurement, invert it, evaluate, save everything and print a summary.
def cmd_sweep(target: str, axis: str = Ellipsis, values: str = Ellipsis, n: int = 4, seeds: str = '0,1,2', base: str | None = None, classes: str | None = None, device: st...¶
One-axis hyperparameter sweep (config field, stage., curriculum., optim., weight.).
def config_files() -> list[Path]¶
All *.yaml / *.yml / *.json files in :func:config_dirs.
def import_plugin(ref: str)¶
Import a plugin module by dotted name or by .py path (idempotent).
def load_plugins(extra: Sequence[str] = ())¶
Import NEFI_PLUGINS, nefi.plugins entry points and extra modules / files.
def load_spec(target: str, overrides: Sequence[str] = (), smoke: bool = False) -> RunSpec¶
Resolve a CLI target (instance name or config file) plus --smoke and --set.
def main(argv: Sequence[str] | None = None) -> int¶
Console-script entry point; returns the exit code (usable in-process).
def make_instance(spec: RunSpec) -> Any¶
Instantiate the registered instance from the configuration file's settings.
def read_spec_file(path: str | Path) -> RunSpec¶
Parse a config file in either accepted layout (see the module docstring).
def resolve_curriculum(spec: RunSpec, default: Curriculum, smoke: bool = False, smoke_steps: int = 40) -> Curriculum¶
Curriculum from the config file (or default) + overrides + smoke budget cap.
nefi.config¶
Config helpers: dataclass <-> dict / YAML, and stable config hashing.
def config_hash(cfg: Any, n: int = 10) -> str¶
Stable short hash of a config (dataclass or dict).
def from_dict(cls: type[T], d: dict) -> T¶
Build a (possibly nested) dataclass from a dict, ignoring unknown keys with an error.
def load_config(path: str | Path) -> dict¶
def save_config(cfg: Any, path: str | Path)¶
def to_dict(obj: Any) -> Any¶
Recursively convert dataclasses / tuples / tensors to JSON-serializable objects.
nefi.domain¶
Physical domain: extents, resolution and normalized coordinate grids.
class Domain(shape: tuple[int, ...], extent: tuple[tuple[float, float], ...], axes: tuple[str, ...] | None = None)¶
A rectangular physical domain discretized on a uniform grid.
at(self, shape: Sequence[int] | int) -> Domain— Same physical extent at a different resolution.axis_coords(self, shape=None, normalized: bool = True, device=None, dtype=None)— List of 1-D cell-center coordinate tensors, one per axis.coarsen(self, factor: int = 2, min_size: int = 4) -> Domaincoords(self, shape=None, device=None, dtype=None) -> torch.Tensor— Normalized cell-centered grid, shape(*shape, ndim)with values in[-1, 1].from_dict(d: dict) -> Domainfrom_spacing(shape: Sequence[int] | int, spacing: float | Sequence[float], origin: float | Sequence[float] = 0.0, axes: Sequence[str] | None = None) -> Domain— Domain from grid shape and physical cell size (e.g. NeTMY: 64 px × 20 nm).ndim(property)numel(property)physical_coords(self, shape=None, device=None, dtype=None) -> torch.Tensor— Physical cell-centered grid, shape(*shape, ndim).refine(self, factor: int = 2) -> Domainsize(property) — Physical side lengths.spacing(self, shape: Sequence[int] | None = None) -> tuple[float, ...]— Physical cell size per axis at resolutionshape(default native).to_dict(self) -> dictto_normalized(self, x: torch.Tensor) -> torch.Tensor— Map physical coordinates(..., ndim)to[-1, 1].to_physical(self, u: torch.Tensor) -> torch.Tensorunit(shape: Sequence[int] | int, axes: Sequence[str] | None = None) -> Domain— Domain[0, 1]^d.
nefi.errors¶
Exception hierarchy for nefi. All library errors derive from :class:NefiError.
class ConfigError(...)¶
Raised for invalid or incomplete configuration.
class NefiError(...)¶
Base class for all nefi errors.
class OperatorError(...)¶
Raised by forward operators for invalid inputs.
class RegistryError(...)¶
Raised when a registry lookup fails.
class ShapeError(...)¶
Raised when tensor / grid shapes are inconsistent.
class SolverError(...)¶
Raised when optimization cannot proceed (e.g. persistent NaNs).
nefi.measurement¶
Observed data container.
class Measurement(data: torch.Tensor, mask: torch.Tensor | None = None, noise_std: float | torch.Tensor | None = None, meta: dict = <factory>)¶
An observation produced by the forward operator plus noise.
energy(self) -> torch.Tensor— Total observed energy ∑ data (masked), used by energy-anchored scale correction.masked_mean(self, x: torch.Tensor) -> torch.Tensor— Mean ofxover observed entries.resampled(self, shape: Sequence[int], mode: str = 'auto') -> Measurement— Resample the trailing dims ofdata(andmask) toshape.shape(property)to(self, device=None, dtype=None) -> Measurement
nefi.priors¶
The prior catalogue: what you physically know about the unknown → heads, losses, hints.
class Binary(lo: float = 0.0, hi: float = 1.0, sharpen: bool = True, eps_start: float = 1.0, eps_end: float = 0.05, perimeter: float = 0.0)¶
Two-phase field x ∈ {lo, hi} via a sharpening level-set head.
curriculum_hints(self)head(self) -> Headinterval(self)losses(self, field_name, context=None)
class Bounded(lo: float = 0.0, hi: float = 1.0, init: float | None = None)¶
lo ≤ x ≤ hi through a sigmoid head (NeFTY Eq. 6).
head(self) -> Headinterval(self)
class CombinedPrior(priors: list[Prior], field: str = 'x', ndim: int | None = None, domain: Any = None, top: Prior = <factory>, periodic_axes: tuple[int, ...] = ())¶
The resolved set of priors for one field (see :func:combine).
auto_init(property)base_head(self) -> Headbuild_field(self, builder: Callable[[int], Field], ndim: int) -> Field— Build the (possibly symmetry-wrapped) field;builder(ndim)makes the inner field.context(self) -> PriorContextcurriculum_hints(self) -> dict[str, Any]describe(self) -> strfield_hints(self) -> dict[str, Any]head(self) -> Head— The output head: the top prior's head wrapped by modifiers (support, conservation).losses(self) -> LossSpec—{name: (Loss, relative_strength)}of every prior (names made unique).postprocess(self) -> list[Postprocess]
class Conserved(total: float = 1.0, kind: str = 'sum', hard: Any = 'auto', weight: float = 1.0)¶
The field's total is known (mass / charge / number of particles).
losses(self, field_name, context=None)wrap_head(self, head, context)
class KnownSupport(mask: Any = None, fill: float | None = None, hard: bool = True, weight: float = 1.0)¶
The unknown vanishes (equals fill) outside a known support mask (1 = inside).
losses(self, field_name, context=None)wrap_head(self, head, context)
class Monotone(axis: int = 0, direction: str = 'increasing', weight: float = 1.0)¶
Monotone along an axis (soft penalty on violations).
losses(self, field_name, context=None)
class NonNegative(init: Any = 'auto', beta: float = 1.0, peak_ratio: float = 3.0)¶
x ≥ 0 through a softplus head (x = s · softplus(h)).
head(self) -> Headheadroom(self) -> floatinterval(self)
class Periodic(axes: Any = None)¶
Periodic domain along axes (default: all): regularizers wrap around; with all axes periodic the neural field uses a purely periodic Fourier encoding (no raw coordinates).
field_hints(self, ndim=None)resolved_axes(self, ndim: int | None) -> tuple[int, ...]
class PiecewiseConstant(tv: float = 0.01, eps: float = 1e-06, isotropic: bool = True)¶
Piecewise-constant field: total-variation penalty (isotropic, NeFTY Eq. 22).
losses(self, field_name, context=None)
class Positive(init: Any = 'auto')¶
x > 0 with a log-parameterization x = s · exp(h) (large dynamic ranges).
head(self) -> Headinterval(self)
class Prior()¶
Base class. Subclasses are dataclasses with a class-level key (DSL name).
auto_init(self) -> bool— True when the head's scale should be fitted to the data byfrom_forward.curriculum_hints(self) -> dict[str, Any]— Suggestions for :func:nefi.auto.auto_curriculum(e.g.anneal_fraction).describe(self) -> strfield_hints(self, ndim: int | None = None) -> dict[str, Any]— Suggestions for the representation (e.g.max_octaves,include_input).head(self) -> Head | None— The output head, orNoneif this prior does not define one.headroom(self) -> float— Ratio between the head's natural scale and the fitted initial level (1 = same).inner_ndim(self, ndim: int) -> int— Coordinate dimension of the field wrapped by :meth:wrap_field.interval(self) -> tuple[float, float]— Values allowed by this prior (used to check compatibility with other priors).losses(self, field_name: str, context: PriorContext | None = None) -> LossSpec—{name: (Loss, relative_strength)}contributed by this prior.params(self) -> dict[str, Any]parse(spec: Any) -> list[Prior]— Parse the prior DSL (or pass through Prior objects / lists) into a list of priors.postprocess(self, field_name: str | None = None) -> list[Postprocess]rank(self) -> int— Specificity of the head this prior defines (-1: no head).wrap_field(self, inner: Field, ndim: int) -> Fieldwrap_head(self, head: Head, context: PriorContext) -> Head— Wrap the resolved head (head modifiers such as known support / conservation).
class PriorContext(field: str = 'x', ndim: int | None = None, domain: Any = None, periodic_axes: tuple[int, ...] = (), value_range: tuple[float, float] = (-inf, inf))¶
Information shared with priors while building losses / heads / fields.
class PriorList(iterable=())¶
A list of priors supporting + with priors, strings and lists.
class Scale(homogeneity: float | None = None)¶
Recover the absolute scale after fitting (energy-anchored correction, NeTMY Eq. 30).
postprocess(self, field_name=None)
class Smooth(laplacian: float | None = None, tikhonov: float | None = None, gradient: float | None = None)¶
Smooth field: Laplacian (second-order), gradient (first-order Tikhonov) and/or ridge penalties. With no argument: laplacian=1e-2.
field_hints(self, ndim=None)losses(self, field_name, context=None)
class Sparse(l1: float = 0.01, gated: bool = True, init: Any = 'auto', peak_ratio: float = 30.0)¶
Mostly-zero, non-negative field: gated softplus head (NeTMY Eq. 5) + L1 penalty.
auto_init(self) -> boolhead(self) -> Head | Noneheadroom(self) -> floatinterval(self)losses(self, field_name, context=None)rank(self) -> int
class Symmetric(kind: str = 'mirror_x', axes: Any = None, hard: bool = True, weight: float = 1.0)¶
Mirror or radial symmetry, exact by coordinate folding (hard) or as a penalty.
inner_ndim(self, ndim: int) -> intlosses(self, field_name, context=None)wrap_field(self, inner, ndim)wraps_field(property)
class Unconstrained(init: Any = 'auto', scale: float = 1.0, offset: float = 0.0)¶
Signed, unconstrained values (identity/affine head).
head(self) -> Head
def combine(priors: Any, field: str = 'x', ndim: int | None = None, domain: Any = None) -> CombinedPrior¶
Resolve a set of priors for one field: pick the head, check compatibility.
def describe_catalogue() -> str¶
Markdown table of the DSL (name, class, meaning) — used by the docs.
def parse(spec: Any) -> list[Prior]¶
Parse spec (DSL string, Prior, list/tuple of those, CombinedPrior) into priors.
def register_prior(name: str, cls: type[Prior]) -> type[Prior]¶
Make a custom :class:Prior subclass available in the DSL under name.
nefi.problem¶
The inverse problem: domain + field + operator + losses + measurement (+ post-processing).
class InverseProblem(domain: Domain, field: Field, operator: Operator, losses: LossSet, measurement: Measurement, postprocess: Sequence[Postprocess] = (), curriculum: Curriculum...¶
A fully specified per-measurement inverse problem.
context(self, shape=None, progress: float = 1.0, stage=None, step: int = 0) -> Contextdescribe(self) -> dictdevice(property)dtype(property)evaluate(self, shape: Sequence[int] | None = None, progress: float = 1.0, grad: bool = False) -> tuple[dict[str, torch.Tensor], torch.Tensor]— Fields and prediction atshape(default native resolution).loss(self, shape=None, progress: float = 1.0, stage=None, step: int = 0)— Total loss and components at the current parameters (with autograd).measurement_at(self, shape: Sequence[int]) -> Measurementto(self, device=None, dtype=None) -> InverseProblem— Move modules todeviceand cast real floating tensors todtype.
nefi.registry¶
A tiny registry so every component is constructible from config ({"type": name, ...}).
def build(kind: str, cfg: str | dict | Any, **extra: Any) -> Any¶
Instantiate a registered component.
def get(kind: str, name: str) -> Any¶
def list_registered(kind: str | None = None) -> dict[str, list[str]]¶
def register(kind: str, name: str | None = None) -> Callable¶
Decorator registering a class / factory under kind and name.