rm_lite.utils.fitting

Attributes

Classes

FDFFitResult

Results of a Gaussian FDF fit

FitResult

Results of a Stokes I fit

StokesIFitOptions

Options for Stokes I model fitting, shared by the 1D and 3D tools

StokesIModel

Base class for protocol classes.

Functions

best_aic_func(→ tuple[float, int, int])

Find the best AIC for a set of AICs using Occam's razor.

draw_model_samples(→ numpy.typing.NDArray[numpy.float64])

Monte-Carlo model realisations over the fit covariance, shape

dynamic_fit(→ FitResult)

fit_fdf(→ FDFFitResult)

fit_rmsf(→ float)

fit_stokes_i_model(→ FitResult | None)

Fit a Stokes I spectrum, or return None when it should not be fitted.

fwhm_to_sigma(→ float)

gaussian(→ numpy.typing.NDArray[numpy.float64])

gaussian_integrand(→ float)

polynomial(→ StokesIModel)

power_law(→ StokesIModel)

sample_model_error(...)

Median model and 1-sigma (16th/84th-percentile) error via Monte-Carlo

sigma_to_fwhm(→ float)

static_fit(→ FitResult)

stokes_i_snr(→ float)

Frequency-averaged Stokes I SNR: mean(I) * sqrt(n) / rms(error).

unit_centred_gaussian(...)

unit_gaussian(→ numpy.typing.NDArray[numpy.float64])

Module Contents

class rm_lite.utils.fitting.FDFFitResult

Bases: NamedTuple

Results of a Gaussian FDF fit

amplitude_fit: float

Amplitude of the best fit model

mean_fit: float

Mean (Faraday depth) of the best fit model

stddev_fit: float

Standard deviation (Faraday depth) of the best fit model

class rm_lite.utils.fitting.FitResult

Bases: NamedTuple

Results of a Stokes I fit

aic: float

Akaike Information Criterion of the fit

pcov: numpy.typing.ArrayLike

Covariance matrix of the fit

popt: numpy.typing.ArrayLike

Best fit parameters

stokes_i_model_func: StokesIModel

Function of the best fit model

class rm_lite.utils.fitting.StokesIFitOptions

Options for Stokes I model fitting, shared by the 1D and 3D tools

__post_init__() None
compute_model_error: bool = False

Also compute the per-pixel model error (3D fit path only)

fit_function: Literal['log', 'linear'] = 'log'

“log” fits a power law, “linear” a polynomial

fit_order: int = 2

Fit order; negative iterates orders and picks the best by AIC

n_error_samples: int = 1000

Monte-Carlo samples for the model error

snr_cut: float | None = 5.0

Skip the fit below this frequency-averaged SNR; None fits everything

class rm_lite.utils.fitting.StokesIModel

Bases: Protocol

Base class for protocol classes.

Protocol classes are defined as:

class Proto(Protocol):
    def meth(self) -> int:
        ...

Such classes are primarily used with static type checkers that recognize structural subtyping (static duck-typing).

For example:

class C:
    def meth(self) -> int:
        return 0

def func(x: Proto) -> int:
    return x.meth()

func(C())  # Passes static type check

See PEP 544 for details. Protocol classes decorated with @typing.runtime_checkable act as simple-minded runtime protocols that check only the presence of given attributes, ignoring their type signatures. Protocol classes can be generic, they are defined as:

class GenProto[T](Protocol):
    def meth(self) -> T:
        ...
__call__(x: numpy.typing.NDArray[numpy.float64], *params: float) numpy.typing.NDArray[numpy.float64]
rm_lite.utils.fitting.best_aic_func(aics: numpy.typing.NDArray[numpy.float64], n_param: numpy.typing.NDArray[numpy.integer[Any]]) tuple[float, int, int]

Find the best AIC for a set of AICs using Occam’s razor.

rm_lite.utils.fitting.draw_model_samples(fit: FitResult, x_arr: numpy.typing.NDArray[numpy.float64], n_error_samples: int) numpy.typing.NDArray[numpy.float64]

Monte-Carlo model realisations over the fit covariance, shape (n_error_samples, len(x_arr)), evaluated at x_arr = freq / ref_freq.

rm_lite.utils.fitting.dynamic_fit(freq_arr_hz: numpy.typing.NDArray[numpy.float64], ref_freq_hz: float, stokes_i_arr: numpy.typing.NDArray[numpy.float64], stokes_i_error_arr: numpy.typing.NDArray[numpy.float64], fit_order: int = 2, fit_function: Literal['log', 'linear'] = 'log') FitResult
rm_lite.utils.fitting.fit_fdf(fdf_to_fit_arr: numpy.typing.NDArray[numpy.float64], phi_arr_radm2: numpy.typing.NDArray[numpy.float64], fwhm_fdf_radm2: float) FDFFitResult
rm_lite.utils.fitting.fit_rmsf(rmsf_to_fit_arr: numpy.typing.NDArray[numpy.float64], phi_double_arr_radm2: numpy.typing.NDArray[numpy.float64], fwhm_rmsf_radm2: float) float
rm_lite.utils.fitting.fit_stokes_i_model(freq_arr_hz: numpy.typing.NDArray[numpy.float64], ref_freq_hz: float, stokes_i_arr: numpy.typing.NDArray[numpy.float64], stokes_i_error_arr: numpy.typing.NDArray[numpy.float64], options: StokesIFitOptions) FitResult | None

Fit a Stokes I spectrum, or return None when it should not be fitted.

Masks non-finite channels first, then returns None if too few finite channels remain (< abs(options.fit_order) + 2) or, when options.snr_cut is given, the frequency-averaged SNR is below it – letting the caller impose a flat model for that spectrum. A fit that cannot converge does not raise: static_fit falls back to a flat (mean) model.

rm_lite.utils.fitting.fwhm_to_sigma(fwhm: float) float
rm_lite.utils.fitting.gaussian(x: numpy.typing.NDArray[numpy.float64], amplitude: float | complex, mean: float | numpy.typing.NDArray[numpy.float64], stddev: float | None = None, fwhm: float | None = None) numpy.typing.NDArray[numpy.float64]
rm_lite.utils.fitting.gaussian_integrand(amplitude: float, stddev: float | None = None, fwhm: float | None = None) float
rm_lite.utils.fitting.polynomial(order: int) StokesIModel
rm_lite.utils.fitting.power_law(order: int) StokesIModel
rm_lite.utils.fitting.sample_model_error(fit: FitResult, x_arr: numpy.typing.NDArray[numpy.float64], n_error_samples: int) tuple[numpy.typing.NDArray[numpy.float64], numpy.typing.NDArray[numpy.float64]]

Median model and 1-sigma (16th/84th-percentile) error via Monte-Carlo over the fit covariance, evaluated at x_arr = freq / ref_freq.

rm_lite.utils.fitting.sigma_to_fwhm(sigma: float) float
rm_lite.utils.fitting.static_fit(freq_arr_hz: numpy.typing.NDArray[numpy.float64], ref_freq_hz: float, stokes_i_arr: numpy.typing.NDArray[numpy.float64], stokes_i_error_arr: numpy.typing.NDArray[numpy.float64], fit_order: int = 2, fit_function: Literal['log', 'linear'] = 'log') FitResult
rm_lite.utils.fitting.stokes_i_snr(i_spec: numpy.typing.NDArray[numpy.float64], e_spec: numpy.typing.NDArray[numpy.float64]) float

Frequency-averaged Stokes I SNR: mean(I) * sqrt(n) / rms(error).

Averaging n channels beats the noise down by sqrt(n), hence the factor. Returns inf when there is no usable noise (all-zero or non-finite error), so an SNR cut becomes a no-op instead of rejecting everything.

rm_lite.utils.fitting.unit_centred_gaussian(x: numpy.typing.NDArray[numpy.float64], stddev: float | None = None, fwhm: float | None = None) numpy.typing.NDArray[numpy.float64]
rm_lite.utils.fitting.unit_gaussian(x: numpy.typing.NDArray[numpy.float64], mean: float, stddev: float | None = None, fwhm: float | None = None) numpy.typing.NDArray[numpy.float64]
rm_lite.utils.fitting.GAUSSIAN_SIGMA_TO_FWHM