Initialization (greedy CORR-PNR)¶
Source: minicnmfe/initialization.py. Entry: greedy_corr_pnr(...) (and the
parallel greedy_corr_pnr_patched). Produces the first A, C, raw traces, and
neuron centres that the BCD loop then refines.
Initialization is greedy: find the best remaining seed, extract a neuron there, subtract it from the movie, repeat. Each extraction changes the residual the next seed sees, which is why this stage is inherently sequential.
Setup (once)¶
- Filter every frame with the center-surround PSF via
cv2.filter2D→data_filtered. Keep an unfiltered copydata_raw. - Center each pixel in time and estimate the per-pixel noise
noise_pixelonce (estimate_noise). - Initial CORR and PNR, and the search score
v_search = CORR · PNR(zeroed whereCORR < min_corrorPNR < min_pnr). ind_search— a persistent(H, W)boolean mask of pixels that will not be tried as seeds. Initialized from sub-threshold pixels and theborder_pxmargin.
The greedy loop¶
Each outer pass rebuilds the sorted seed list with peak_local_max over the
current v_search. For each candidate seed (highest score first):
- Skip if already in
ind_search; otherwise mark it tried. - Diff-noise guard — reject pure-noise pixels whose
max(diff(trace)) < 3 · std(diff(trace)). - Extract footprint + trace on a
gSiz = max(3·sigma, 5)patch (extract_spatial_temporal, below). Reject if it fails or has fewer thanmin_pixelpixels. - Deconvolve the trace with OASIS (
estimate_ar_params+deconvolve) to a clean calcium tracec_clean. - Subtract the component from both movies:
data_raw: subtractai · c_cleanon the extraction box.data_filtered: subtract the PSF-refiltered footprintcv2.filter2D(ai) · c_cleanon a2·gSizhalo — so the filtered residual stays clean and the soma's PSF sidelobes don't re-seed ghosts.- Suppress the neuron's own support: mark
ai > ai.max()/2pixels inind_search(CaImAn-style support mask). (Theseed_suppress_factor/ suppression-disk parameter is deprecated and ignored.) - Refresh CORR/PNR locally on the
2·gSizbox against the cachednoise_pixel(_local_cn_pnr_box) and updatev_searchthere.
The loop stops when a pass makes no progress, no seeds remain, or max_neurons
is reached.
Single-component extraction¶
extract_spatial_temporal turns one seed into one (footprint, trace) on its
patch:
- Unit-normalize each pixel trace in the patch; correlate every pixel with the seed pixel's trace.
- Neuron pixels = correlation
> min_corr_neuron(default 0.8); their mean (filtered) trace is the temporal estimateci. Background pixels = correlation< max_corr_bg(default 0.4); their median (raw) trace is a local background regressor. - Solve a 3-component OLS
patch_raw ≈ [ci, y_bg, 1] · coef; the footprint isai = coef[0]clipped to≥ 0. - Apply the shape constraints:
circular_constraint(zero pixels farther thancircular_max_dist_factor · √(area/π)from the centroid) andconnectivity_constraint(keep the largest connected component). - Baseline-subtract
ci(median of its near-flat samples).
Patch-parallel variant¶
greedy_corr_pnr_patched recovers parallelism that the serial greedy loop can't
offer: it tiles the FOV into overlapping patches (_tile_grid), runs the
unchanged greedy_corr_pnr on each in parallel processes, remaps each
patch's footprints/centres to global coordinates, concatenates them, and
de-duplicates neurons found in two overlapping patches with
merge_components (their copies have near-identical traces and close centres).
border_px and max_neurons are applied globally after the merge. The pipeline
uses this path for the single full-FOV init when the movie is in RAM, the FOV is
large enough (init_patch_min_fov), and the device is CPU.