Skip to content

Decorator taxonomy: requires / resolves / enforces #42

@andrewendlinger

Description

@andrewendlinger

Problem

Processing functions force users into manual domain juggling:

  • da.xmr.to_hz().xmr.autophase() (Hz vs ppm)
  • da.xmr.to_spectrum().xmr.autophase().xmr.to_fid() (time vs frequency)

Solution

Three decorator tiers, named by agency level:

@enforces_domain(DIMS.frequency)              # actively FFTs if needed, restores after
@resolves_spectral_dim                         # auto-detects Hz/ppm, injects dim=None
@requires_attrs(ATTRS.reference_frequency)     # checks existence, raises if missing
def autophase(da, dim=None):
Decorator Verb Agency Cost
@requires_attrs(...) gate Raises if missing Zero
@resolves_spectral_dim resolve Introspects dims, fills dim=None Zero
@enforces_domain(DIMS.x) transform FFT round-trip if wrong domain O(N log N)

Checklist

  • config.py: add SPECTRAL_DIMS = frozenset({DIMS.frequency, DIMS.chemical_shift})
  • utils.py: add _resolve_spectral_dim() helper
  • validation.py: add @resolves_spectral_dim decorator
  • validation.py: add @enforces_domain() decorator
  • Refactor to_ppm() / to_hz(): no-op guard, always recompute, no dim param
  • Update spectral-agnostic functions: dim: str = DIMS.frequencydim: str | None = None

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions