qens.fitting

Inference primitives: likelihood, prior, MAP search, plus utilities to bin the data and build per Q bin resolution kernels.

qens.fitting.build_data_bins(d, cfg=None)[source]

Bin a dataset into “n_q_bins “ equal occupancy Q-bins.

Parameters:
  • d (dict) –

    A processed dataset dict (must already have “e “, “good “, “q “,

    ”data “, “errs “).

  • cfg (Config)

Return type:

list[tuple[ndarray, ndarray, ndarray, float]]

Returns:

  • list of “(omega, spec, errs, q_centre) “ tuples — one per Q-bin —

  • where “omega “ is restricted to ±cfg.energy_window and “q_centre “

  • is the mean Q of the detectors in the bin.

qens.fitting.build_resolution_bins(d_ref, cfg=None, q_centres=None)[source]

Build a measured per Q bin resolution kernel from a frozen sample.

For each Q bin in the data, average the frozen sample spectra at detectors with similar Q to produce a measured resolution function. Use this kernel inside the forward model, it captures the Lorentzian wings of the real instrument that a pure Gaussian fit misses.

Parameters:
  • d_ref (dict) – Resolution reference dataset (typically the frozen low T inc file). Must already have “e “, “good “, “q “, “data “.

  • cfg (Config)

  • q_centres (array, optional) – If given, build kernels at these Q centres instead of percentile bins. Useful when matching the binning of a different (target) dataset.

Return type:

list[ndarray]

Returns:

qens.fitting.extract_hwhm(d, cfg=None)[source]

Fit “elastic + Lorentzian + bg “ independently in each Q-bin.

Parameters:
Return type:

tuple[ndarray, ndarray, ndarray, ndarray]

Returns:

  • q_centres, hwhm, hwhm_err, eisf (1D arrays of length n_qbins (or fewer)

  • if some bins fail to fit).

qens.fitting.save_hwhm_csv(q_centres, hwhm, hwhm_err, eisf, save_dir)[source]

Write the HWHM table to “<save_dir>/hwhm_table.csv “.

Return type:

str

Parameters:
qens.fitting.log_likelihood(params, data_bins, sigma_res, model='anisotropic_rotor', **extras)[source]

Joint X^2 log-likelihood across all Q-bins.

For each bin a 2 column NNLS fits “[overall_amp, flat_bg] “, so the physics determined Bessel weight ratios inside the forward model are preserved as a global Q-constraint.

Parameters:
  • params (array) – Parameter vector matching the registered model.

  • data_bins (list of (omega, spec, errs, q)) – From build_data_bins().

  • sigma_res (float | array | list[array]) – Resolution: scalar Gaussian , single measured kernel, or one kernel per Q-bin (list of arrays).

  • model (str) – Name of a registered forward model. Default “”anisotropic_rotor” “.

  • extras – Forwarded to the model’s “predict “ callable.

Return type:

float

qens.fitting.log_prior(params, model='anisotropic_rotor')[source]

Log-prior: 0 inside the registered model’s prior box, “-inf “ outside.

Return type:

float

Parameters:
qens.fitting.log_posterior(params, data_bins, sigma_res, model='anisotropic_rotor', **extras)[source]

Convenience wrapper: prior + likelihood.

Return type:

float

Parameters:

model (str)

qens.fitting.find_map(data_bins, sigma_res, model='anisotropic_rotor', cfg=None, n_starts=None, verbose=True, **extras)[source]

Maximum- a posteriori search via Nelder Mead from random starts.

Parameters:
  • data_bins (list)

  • sigma_res (float | array | list[array])

  • model (str) – Name of a registered forward model.

  • cfg (Config)

  • n_starts (int, optional) – Random starts. If None uses “cfg.n_map_starts “.

  • verbose (bool)

  • extras – Forwarded to the model’s “predict “ callable.

Return type:

tuple[ndarray, float]

Returns:

(params_map, neg_logp) ((ndarray, float))