pyfli.reconstruction.decay_reconstruction#
Reconstruct per-pixel modeled decay curves from fitted FLI parameter maps.
This module belongs to pyfli.reconstruction and sits downstream of
pyfli.solver: it reuses the solver’s mono-/bi-exponential forward-model
kernels and fit-quality metrics to turn a dictionary of fitted parameter maps
(shaped like pyfli.solver.FLICPUProcessor’s output) back into decay
cubes. Public API includes class ParamToDecay.
Classes
|
Reconstruct per-pixel modeled decay curves from fitted parameter maps. |
- class ParamToDecay(model_type, freq, irf=None, num_gates=None)[source]#
Bases:
objectReconstruct per-pixel modeled decay curves from fitted parameter maps.
Rebuilds the forward-model decay for every pixel from a dictionary of parameter maps shaped like
pyfli.solver.FLICPUProcessor’s output, and optionally derives fit-quality maps (TR_mapsand per-pixelcompute_fli_stats()summaries) when the measured decay is also supplied. When an IRF is available, pixels are rebuilt viapyfli.solver.forward_model.model_numpy()(kernel convolved with the IRF); when no IRF is given, pixels are rebuilt directly frompyfli.solver.forward_model.decay_kernel()(the un-convolved model)."photon_count_map","v_shift_map", and"h_shift_map"are optional — missing ones default to 1.0, 0.0, and 0.0 respectively (seePARAM_MAP_DEFAULTS), except"photon_count_map": if it’s omitted anddecayis supplied toreconstruct(), it is instead solved for as the amplitude that makes the model’s own convolved-kernel discrete sum matchdecay’s discrete sum at each pixel (not simplydecay.sum(axis=-1)— see_fill_photon_count_from_decay()), rather than falling back to 1.0. The lifetime map(s) ("tau_map"for mono-exponential;"alpha1_map","tau1_map","tau2_map"for bi-exponential) are always required.A 2-D boolean
bool_maskcan be passed toreconstruct()to only reconstruct pixels where it isTrue; every output map isNaNelsewhere. Single-pixel reconstruction is also supported: pass scalar parameter values (and a 1-D IRF/decay) and every output collapses to a plain 1-D trace (or scalar, for the fit-quality numbers) instead of an(H, W, ...)map — seereconstruct().New model families can be added by extending
PARAM_MAP_KEYS(and the matching kernel inpyfli.solver.forward_model); new post-reconstruction map products can be added by overriding_compute_tr_maps()in a subclass.- Parameters:
model_type (
str) – FLI model family; one of the keys inPARAM_MAP_KEYS("mono-exponential"or"bi-exponential").freq (
float) – Acquisition frequency in MHz — i.e.freq[1]inpyfli.solver.BaseFLIFitter’s/pyfli.solver.FLIGPUProcessor’s(laser_freq_mhz, acq_freq_mhz)convention. Only the acquisition frequency is ever needed here, to derive the time axis asT_acq = 1000.0 / freq.irf (
np.ndarray | None) – Instrument response function; either a shared 1-D trace or a per-pixel(H, W, T)cube. The number of time gates is inferred from its last axis (or its length, if 1-D). If omitted, pixels are reconstructed without IRF convolution (seepyfli.solver.forward_model.decay_kernel()) andnum_gatesmust be supplied instead.num_gates (
int | None) – Number of time gates/bins. Required only whenirfis omitted; otherwise it is inferred fromirfand this argument is ignored.
- PARAM_MAP_KEYS: ClassVar[dict[str, tuple[str, ...]]] = {'bi-exponential': ('photon_count_map', 'alpha1_map', 'tau1_map', 'tau2_map', 'v_shift_map', 'h_shift_map'), 'mono-exponential': ('photon_count_map', 'tau_map', 'v_shift_map', 'h_shift_map')}#
required parameter-map keys}, in the exact order expected by
forward_model.model_numpy/decay_kernel— the last key is always the temporal shift consumed ash_shift. Extend this (plus a matching kernel branch inforward_model.decay_kernel) to support new model families.- Type:
Registry of {model_type
- PARAM_MAP_DEFAULTS: ClassVar[dict[str, float]] = {'h_shift_map': 0.0, 'photon_count_map': 1.0, 'v_shift_map': 0.0}#
Default value used for a parameter map when it’s omitted from
params. Keys absent from this dict are required (no sensible physical default).
- reconstruct_unit_amplitude(params, bool_mask=None)[source]#
Build the un-convolved kernel and IRF-convolved model at whatever literal amplitude
paramscarries (a constant"photon_count_map"of 1.0 gives a pure shape/PDF result), without addingv_shiftor computing any fit-quality maps.Pairs with
rescale_fit_to_measured_totals()for callers whose parameter maps don’t carry a meaningful literal amplitude (e.g. lifetime-only estimator output) and need the final scale pinned to a measured photon count instead — seepyfli.reconstruction.DetailedRecon.reconstruct().
- rescale_fit_to_measured_totals(fit_map, decay, eps=_EPS)[source]#
Rescale
fit_mapper pixel so its sum along the time axis matchesdecay’s exactly, instead of using whatever literal amplitude ("photon_count_map") went into building it.Useful when the parameter maps don’t carry a meaningful absolute amplitude (e.g. lifetime-only estimator output) and the fit’s total should instead be pinned to the measured photon count — this also compensates for any convolution-truncation loss the way
pyfli.reconstruction.DetailedRecon.reconstruct()requires.
- reconstruct_vectorized(params, decay=None, bool_mask=None, verbose=True)[source]#
Vectorized equivalent of
reconstruct()— same contract and (up to floating-point noise) identical numeric output, but built with batched numpy/fftconvolveinstead of a Python per-pixel loop. Prefer this for whole-image reconstruction;reconstructremains available for its progress bar and for subclasses that override the per-pixel hooks.
- reconstruct(params, decay=None, bool_mask=None, verbose=True)[source]#
Rebuild the per-pixel modeled decay from fitted parameter maps.
- Parameters:
params (
dict[str,Any]) – Parameter maps keyed as inpyfli.solver.FLICPUProcessor’s output formodel_type(seeparam_keys). Each value is normally an(H, W)array;"photon_count_map","v_shift_map", and"h_shift_map"may be omitted (seePARAM_MAP_DEFAULTSand, for"photon_count_map", thedecay-derived fallback described in the class docstring). For single-pixel reconstruction, pass plain scalars instead.decay (
np.ndarray | None) – Measured decay,(H, W, T)(or(T,)for a single pixel). When supplied,TR_mapsandfit_stats_mapsare also computed and returned.bool_mask (
np.ndarray | None) – Optional 2-D boolean mask; onlyTruepixels are reconstructed, everything else isNaNin every output map. Ignored for single-pixel reconstruction.verbose (
bool) – Show a progress bar while reconstructing.
- Returns:
{"fit_map": <H, W, T>}, plus"TR_maps"and"fit_stats_maps"whendecayis supplied. For single-pixel input, every value collapses to a(T,)trace or, forfit_stats_maps, a plainfloat.- Return type:
dict[str,Any]