pyfli.data_vnp.cv_plot#
Plot the coefficient of variation of a fitted parameter map against photon count.
This module belongs to pyfli.data_vnp and is part of PyFLI visualization,
normalization, plotting, and mono-versus-bi-exponential comparison tools. Public API
includes class CVPlot.
Classes
|
Bin a fitted parameter map (typically a lifetime map) by photon count and plot its per-bin coefficient of variation, |
- class CVPlot(save_path=None, fig_name=None)[source]#
Bases:
objectBin a fitted parameter map (typically a lifetime map) by photon count and plot its per-bin coefficient of variation,
cv = std(parameter) / mean(parameter).For a shot-noise-limited lifetime estimate,
cvis expected to scale asphoton_count ** -0.5(the Cramer-Rao bound for exponential-decay data) – this class is the standard way to check that scaling empirically, pooled over all pixels or broken out per spatial cluster.The class operates directly on a flat
{key: (H, W) array}maps dict, i.e. exactlyresults["results"]["maps"]as returned by any of PyFLI’s fitters –FLICPUProcessor,FLIGPUProcessor, or anMLEFLIFitter-backed CPU run – as well as the ground-truthmapsdict produced by the simulator, since all of them share the same key naming convention (tau_map/tau1_map/tau2_map/photon_count_map/ …). It has no dependency on how those maps were produced.- Parameters:
save_path (
str | None) – Output path used when saving generated figures.fig_name (
str | None) – Figure name or output stem used when saving; defaults to"cv_plot".
- compute(maps, tau_keys, photon_map=None, photon_key='photon_count_map', mask=None, cluster_mask=None, cluster_names=None, n_bins=10, bin_mode='quantile', bin_scope='pooled')[source]#
Bin pixels by photon count and compute per-bin mean/std/cv for each of tau_keys, pooled over mask or broken out per cluster_mask label.
- Parameters:
maps (
dict[str,np.ndarray]) – Flat{key: (H, W) array}dict of fitted (or ground-truth) parameter maps, e.g.results["results"]["maps"]from any PyFLI fitter.tau_keys (
str | list[str]) – Key(s) in maps to compute the coefficient of variation for (not limited to literal lifetimes – any per-pixel parameter map works, e.g."tau_map",["tau1_map", "tau2_map", "tau_mean_map"],"alpha1_map").photon_map (
np.ndarray | None) – Photon-count map to bin by, e.g.decay.sum(axis=-1)computed directly from the raw decay cube. Takes precedence over photon_key when given – preferred when available, since a fittedphoton_count_mapamplitude can differ in scale/definition from the true detected photon count.photon_key (
str) – Key in maps to use as the photon-count map when photon_map is not given.mask (
np.ndarray | None) – Boolean(H, W)mask selecting pixels to include.Nonekeeps every finite pixel.cluster_mask (
np.ndarray | None) – Integer(H, W)label map for per-region binning.0= background (excluded);1, 2, 3, ...= cluster labels.Nonepools every selected pixel together instead.cluster_names (
dict[int,str] | None) – Optional{label: name}mapping for display; must cover every non-zero label present in cluster_mask. Defaults tof"cluster_{label}".n_bins (
int) – Number of photon-count bins.bin_mode (
str) –"quantile"(equal-frequency bins) or"linear"(equal-width bins).bin_scope (
str) –"pooled"(default) computes ONE set of bin edges shared by every cluster, so clusters sit at directly comparable photon-count positions."per_group"gives each cluster (or the single pooled group, if no cluster_mask) its own edges from its own photon-count distribution.
- Returns:
Long-form frame with columns
cluster(Nonewhen cluster_mask is not given),parameter,bin_rank,bin_center,bin_low,bin_high,mean,std,cv,count.- Return type:
pd.DataFrame
- plot(df, target_keys=None, ncols=3, figsize=None, logx=False, palette=None, show_ideal_trend=False, show_powerlaw_fit=False, ideal_fit_space='linear', ideal_fit_weighted=False)[source]#
Plot cv (from compute) against the photon-count bin.
Without a cluster grouping (
compute(cluster_mask=None)), draws ONE subplot with one line per target_keys entry. With a cluster grouping, draws a grid with one subplot PER target_keys entry, each with one line per cluster.- Parameters:
df (
pd.DataFrame) – Output of compute.target_keys (
list[str] | None) – Which parameter values to plot; defaults to every parameter in df.ncols (
int) – Number of subplot columns (cluster grid only).figsize (
tuple[float,float] | None) – Figure size passed to Matplotlib.logx (
bool) – Use a log-scaled photon-count axis.palette (
dict[str,Any] | None) –{cluster_name: color}mapping (cluster grid only); defaults to a qualitative Seaborn palette.show_ideal_trend (
bool) – Overlay the theoretical shot-noise-limited trendcv = C / sqrt(N)as a dotted line for each data series (same color as the series), so deviation from ideal Poisson-limited precision is easy to spot.Cis fit by least squares to that series’ own data; the -0.5 exponent is fixed (it’s the Cramer-Rao-bound slope, not a free fit parameter). Off by default.show_powerlaw_fit (
bool) – Overlay ana * N ** bpower-law regression fit to each data series (log- log ordinary least squares, the closed-form fit that maximizes R^2 for this model) as a dashed line, labeled with the fitted equation and R^2. Off by default.ideal_fit_space (
str) – Residual space for fittingCof the ideal trend:"linear"(default; low-photon bins dominate) or"log"(every bin counts by its relative error). Only used when show_ideal_trend is True.ideal_fit_weighted (
bool) – Weight each bin by its pixelcountwhen fittingCof the ideal trend, so sparsely populated bins pull it less. Only used when show_ideal_trend is True. Off by default.
- Returns:
(fig, axes)– axes is a length-1 array in the pooled case, or the full subplot grid in the cluster case.- Return type:
tuple[Any,Any]
- compute_and_plot(maps, tau_keys, photon_map=None, photon_key='photon_count_map', mask=None, cluster_mask=None, cluster_names=None, n_bins=10, bin_mode='quantile', bin_scope='pooled', target_keys=None, ncols=3, figsize=None, logx=False, palette=None, show_ideal_trend=False, show_powerlaw_fit=False, ideal_fit_space='linear', ideal_fit_weighted=False)[source]#
Convenience wrapper: compute then plot in one call. show_ideal_trend, show_powerlaw_fit, ideal_fit_space and ideal_fit_weighted are passed straight through to plot – see there.