pyfli.analysis.precision.crb_precision#

Cramér-Rao lower bound on mono-exponential lifetime precision for gated / TCSPC data.

Module Attributes

PARAMS

signal photons, lifetime, background.

Functions

_crb_cv_chunk(tau, n, b, irf, laser_period, ...)

crb_cv_map(tau_map, n_photons_map, irf, ...)

Per-pixel ideal CV map.

crb_f_value(tau, irf, laser_period[, ...])

Ideal F-value CV_ideal * sqrt(N).

crb_for_cv_bins(cv_df, tau_map, photon_map, ...)

Ideal CV for every photon-count bin of a pyfli.data_vnp.CVPlot.compute() table, so it can be plotted against (or merged with) the measured curves.

crb_lifetime_cv(tau, n_photons, irf, ...[, ...])

Ideal (Cramér-Rao) coefficient of variation of the lifetime, sigma_tau / tau.

gated_decay_model(params, irf, laser_period)

Expected counts per gate mu_k = N * p_k(tau) + b for parameter vectors params (P, 3) ordered as PARAMS (N, tau, b); irf is (T,) or (P, T).

PARAMS = ('N', 'tau', 'b')#

signal photons, lifetime, background.

Type:

Parameter order of gated_decay_model()

gated_decay_model(params, irf, laser_period)[source]#

Expected counts per gate mu_k = N * p_k(tau) + b for parameter vectors params (P, 3) ordered as PARAMS (N, tau, b); irf is (T,) or (P, T). This is the model handed to the generic fisher_crlb.fisher_information().

Parameters:
Return type:

ndarray

crb_lifetime_cv(tau, n_photons, irf, laser_period, background_per_bin=0.0, fit_background=False)[source]#

Ideal (Cramér-Rao) coefficient of variation of the lifetime, sigma_tau / tau.

The unknowns are the photon count N and tau (plus the background level when fit_background is True, which is what NLSF / MLE fits with a free offset v_shift do). The background level itself always enters the Poisson noise.

Parameters:
  • tau (float | np.ndarray) – True lifetime (ns) and expected number of detected signal photons; broadcast against each other.

  • n_photons (float | np.ndarray) – True lifetime (ns) and expected number of detected signal photons; broadcast against each other.

  • irf (np.ndarray) – IRF of shape (T,), or one IRF per value with shape S + (T,).

  • laser_period (float) – Laser repetition period in ns.

  • background_per_bin (float | np.ndarray) – Expected background (dark) counts per gate, e.g. the simulator’s dcr.

  • fit_background (bool) – Treat the background level as an extra unknown parameter.

Returns:

Ideal CV with the broadcast shape of the inputs; NaN where tau <= 0, N <= 0 or an input is not finite. CV * sqrt(N) is the F-value.

Return type:

np.ndarray

crb_f_value(tau, irf, laser_period, n_photons=1e4, background_per_bin=0.0, fit_background=False)[source]#

Ideal F-value CV_ideal * sqrt(N). Without background it does not depend on n_photons; with background it rises as the signal-to-background ratio drops.

Parameters:
Return type:

ndarray

crb_cv_map(tau_map, n_photons_map, irf, laser_period, mask=None, background_per_bin=0.0, fit_background=False)[source]#

Per-pixel ideal CV map.

Parameters:
  • tau_map (np.ndarray) – True lifetime per pixel, shape (H, W) (e.g. the simulator’s ground-truth maps["tau_map"]).

  • n_photons_map (np.ndarray) – Expected signal photons per pixel, shape (H, W) (e.g. the simulator’s maps["photon_count_map"], or the decay sum minus T * background).

  • irf (np.ndarray) – Shared IRF (T,) or per-pixel IRF cube (H, W, T).

  • laser_period (float) – Laser repetition period in ns.

  • mask (np.ndarray | None) – Pixels to compute; others are NaN. Defaults to tau_map > 0.

  • background_per_bin (float) – See crb_lifetime_cv().

  • fit_background (bool) – See crb_lifetime_cv().

Returns:

(H, W) ideal CV map; multiply by sqrt(n_photons_map) for the F-value.

Return type:

np.ndarray

crb_for_cv_bins(cv_df, tau_map, photon_map, irf, laser_period, mask=None, cluster_mask=None, cluster_names=None, n_photons_map=None, background_per_bin=0.0, fit_background=False)[source]#

Ideal CV for every photon-count bin of a pyfli.data_vnp.CVPlot.compute() table, so it can be plotted against (or merged with) the measured curves.

Bin membership is rebuilt from the table’s bin_low / bin_high edges on photon_map (the same photon map given to CVPlot), per cluster when the table has clusters. Within a bin, the per-pixel CRB variances are averaged, so cv_crb = sqrt(mean((cv_i * tau_i) ** 2)) / mean(tau_i) – the CV an ideal estimator would show across those pixels, excluding the true lifetime spread.

Parameters:
  • cv_df (pd.DataFrame) – Output of CVPlot.compute (columns cluster, bin_rank, bin_low, bin_high, bin_center).

  • tau_map (np.ndarray) – True lifetime per pixel (ground truth), (H, W).

  • photon_map (np.ndarray) – Photon map used for binning in CVPlot (e.g. decay.sum(axis=-1)).

  • irf (ndarray) – See crb_lifetime_cv().

  • laser_period (float) – See crb_lifetime_cv().

  • mask (np.ndarray | None) – Pixel mask used in CVPlot.

  • cluster_mask (ndarray | None) – The same cluster labels and names given to CVPlot, if any.

  • cluster_names (dict[int, str] | None) – The same cluster labels and names given to CVPlot, if any.

  • n_photons_map (np.ndarray | None) – Expected signal photons per pixel for the bound; defaults to photon_map. Pass the ground-truth photon_count_map to exclude dark counts.

  • background_per_bin (float) – See crb_lifetime_cv().

  • fit_background (bool) – See crb_lifetime_cv().

Returns:

One row per (cluster, bin): cluster, bin_rank, bin_center, tau_true, n_signal, cv_crb and F_crb (cv_crb * sqrt(bin_center), directly comparable with a measured cv * sqrt(bin_center)). Merge with the measured table on ["cluster", "bin_rank"].

Return type:

pd.DataFrame