Recovery metrics#
Functions to score an analysis pipeline’s output against the ground truth. See the benchmarking guide for how they fit together.
Spatial matching#
.. py:function:: hungarian_match(A_est, A_true, *, metric=’iou’, energy_frac=0.9) :module: minisim
Optimally pair estimated spatial footprints to true ones by overlap.
Each footprint is binarized to the smallest pixel set holding energy_frac
of its energy (see :data:DEFAULT_ENERGY_FRAC), the pairwise IoU (Jaccard)
matrix is formed, and :func:scipy.optimize.linear_sum_assignment finds the
assignment maximizing total IoU. Pairs with zero overlap are dropped from the
returned :attr:Match.pairing.
:param A_est: Footprint stacks (n, height, width), non-negative. Negative values
(if any) are clipped to zero before binarizing.
:param A_true: Footprint stacks (n, height, width), non-negative. Negative values
(if any) are clipped to zero before binarizing.
:param metric: Only "iou" is supported in v1; other values raise ValueError.
:param energy_frac: Fraction of each footprint’s energy its binary mask retains, in (0, 1].
.. py:class:: Match(iou_matrix, pairing) :module: minisim :canonical: minisim.metrics.Match
Bases: :py:class:object
The result of pairing estimated footprints to true ones by spatial overlap.
pairing is the optimal one-to-one assignment (maximizing total IoU) with
pure non-overlapping pairs dropped, so it is safe to feed straight into the
temporal metrics. The threshold-dependent quality summaries (:meth:recall,
:meth:precision) count only pairs whose IoU clears iou_threshold.
Empty denominators (no estimated or no true cells, no matched pairs) report
0.0 rather than nan - convenient for assert metric >= bound tests.
.. py:method:: Match.matched_pairs(iou_threshold=0.5) :module: minisim
The assigned pairs whose IoU is at least ``iou_threshold`` (true positives).
.. py:method:: Match.recall(iou_threshold=0.5) :module: minisim
True positives over the number of true cells (``0.0`` if there are none).
.. py:method:: Match.precision(iou_threshold=0.5) :module: minisim
True positives over the number of estimated cells (``0.0`` if there are none).
.. py:property:: Match.mean_iou :module: minisim :type: float
Mean IoU over the matched (positive-overlap) pairs (``0.0`` if none).
Temporal scores#
.. py:function:: trace_pearson(C_est, C_true, pairing) :module: minisim
Per-matched-pair Pearson correlation between estimated and true traces.
Returns one correlation per (est_idx, true_idx) in pairing (a constant
trace has undefined correlation and yields nan). C_est/C_true are
(unit, frame).
.. py:function:: spike_precision_recall(S_est, S_true, pairing, *, tol_frames=2, spike_thresh=0.0) :module: minisim
Pooled spike-detection precision/recall over the matched units.
A frame is a spike where S > spike_thresh. Within each matched pair, true
spikes are greedily matched to the nearest unused estimated spike within
±tol_frames (a true positive); unmatched true spikes are false negatives
and unmatched estimated spikes are false positives. Counts are pooled across
all pairs, then reduced to precision = TP/(TP+FP) and recall = TP/(TP+FN)
(0.0 when a denominator is empty). S_est/S_true are (unit, frame).
.. py:class:: SpikeScore(precision, recall) :module: minisim :canonical: minisim.metrics.SpikeScore
Bases: :py:class:~typing.NamedTuple
Pooled spike-train detection score across all matched units.
.. py:attribute:: SpikeScore.precision :module: minisim :type: float
Alias for field number 0
.. py:attribute:: SpikeScore.recall :module: minisim :type: float
Alias for field number 1
Field and motion#
.. py:function:: field_pearson(est, true) :module: minisim
Pearson correlation between two 2-D fields (vignette, leakage), flattened.
Scale- and offset-invariant, so it scores the shape of the recovered field
rather than its absolute level. Returns nan if either field is constant.
.. py:function:: shift_rmse(shifts_est, shifts_true) :module: minisim
Root-mean-square error (pixels) between two (frame, 2) shift trajectories.
Pure RMSE over all frames and both axes - the caller must put both arrays in
the same sign convention. A motion-correction estimate is the negation
of the applied GroundTruth.shifts, so negate one before comparing.