Source code for specmod.fitting.base
"""What the fitting layer expects of whatever it is handed.
Structural rather than nominal: :class:`~specmod.fitting.FitSpectrum` reads
attributes off its input and does not care what class provides them, which is
what lets it take a :class:`~specmod.core.collection.FittableView`, a bare
spectrum, or something assembled by hand in a notebook.
"""
from __future__ import annotations
from typing import Any
from .. import config as cfg
__all__ = [
"REQUIRED_SPECTRUM_ATTRIBUTES",
"SpectraLike",
"Spectrumish",
"plot_columns",
]
#: What a spectrum-like object handed to :class:`FitSpectrum` looks like.
#: Structural rather than nominal on purpose — see :meth:`FitSpectrum.__check_input`.
Spectrumish = Any
#: A container mapping trace ids to paired spectra; see
#: :meth:`FitSpectra.__check_spectra`.
SpectraLike = Any
[docs]
def plot_columns() -> int:
"""How many columns a multi-panel figure uses, from ``[viz]``.
A function rather than a constant, and that is the whole point. This was
``PLOT_COLUMNS = cfg.load_config().config.viz.plot_columns`` evaluated at
import time, so importing :mod:`specmod.fitting` resolved configuration
against whatever directory the process happened to start in and froze the
answer for the life of the interpreter. Measured: importing from a project
whose ``specmod.toml`` says 5, then moving to one that resolves to 3, left
the constant at 5 — a worker serving two projects would use the first
one's layout for both.
One home for the setting either way: it used to be defined in *both* the
SPECTRAL and FITTING dicts, and the two copies could disagree.
"""
return int(cfg.load_config().config.viz.plot_columns)
#: What :class:`FitSpectrum` reads off whatever it is given. Kept as data so
#: the requirement is stated once and can be asserted against.
REQUIRED_SPECTRUM_ATTRIBUTES = ("id", "meta", "freq", "amp", "bfreq", "bamp")