Skip to content

Handle empty and tiny localization inputs without crashing#14

Merged
kalidke merged 1 commit into
mainfrom
fix/empty-localizations
Jun 15, 2026
Merged

Handle empty and tiny localization inputs without crashing#14
kalidke merged 1 commit into
mainfrom
fix/empty-localizations

Conversation

@kalidke

@kalidke kalidke commented Jun 14, 2026

Copy link
Copy Markdown
Member

Summary

frameconnect and its building blocks crashed on a BasicSMLD with 0 (or untyped/abstract) emitters: internal reductions (counts/mean/extrema) ran over empty collections, producing MethodError: zero(Type{Any}) from reduce_empty(+, Type{Any}) and "reducing over an empty collection". This surfaced from the SMLMAnalysis pipeline on near-empty dSTORM cells (some cells yield ~0 localizations) — the pipeline should degrade gracefully, not crash.

Changes

isempty guards at the empty-input sites so 0-localization data returns a passthrough/empty result instead of crashing:

  • frameconnect — early-return the (empty) input + a zeroed FrameConnectInfo before the pipeline. When calibration is configured, it still emits a graceful fallback CalibrationResult (calibration_applied=false) so downstream code reading info.calibration.* sees a uniform shape for 0 vs 1–2 localizations.
  • precluster — return the input unchanged for 0 emitters (guards counts on datasetnum/framenum and first(emitters)).
  • combinelocalizations — return the input unchanged for 0 emitters.
  • calibration.jl — no change needed; analyze_calibration already falls back at n_pairs < 100 before any reduction, and the empty branch reuses it.

Tests

New test/test_empty_input.jl covers 0/1/2 localizations × (default + calibration-enabled) × (concrete + abstract Emitter2DFit eltype), plus the combinelocalizations/precluster building blocks.

Full suite: 224/224 pass. 0-emitter BasicSMLD now returns (empty_smld, info) with n_combined=0; 1/2/9-loc inputs return cleanly; calibration-enabled empty/tiny → calibration_applied=false.

Notes

  • Patch bump 0.3.2 → 0.3.3. Draft / branch-only — not for merge or registration in this state.
  • Out of scope (separate, pre-existing): two localizations at exactly identical float positions → zero-area cluster → Inf density → Optim/LAP spins. Does not occur with real sub-pixel data; can be a follow-up if a real cell ever triggers it.

🤖 Generated with Claude Code

frameconnect and its building blocks crashed on a BasicSMLD with 0 (or
untyped/abstract) emitters: reductions like `counts`/`mean`/`extrema` ran
over empty collections, e.g. `MethodError: zero(Type{Any})` from
`reduce_empty(+, Type{Any})` and "reducing over an empty collection".
This surfaced from the SMLMAnalysis pipeline on near-empty dSTORM cells.

Add isempty guards at the empty-input sites so 0-localization data
degrades gracefully (passthrough/empty result) instead of crashing:
- frameconnect: early-return the (empty) input + zeroed info before the
  pipeline. When calibration is configured, still emit a graceful fallback
  CalibrationResult (calibration_applied=false) so downstream code sees a
  uniform shape for 0 and 1-2 localizations.
- precluster: return the input unchanged for 0 emitters (guards `counts`
  on datasetnum/framenum and `first(emitters)`).
- combinelocalizations: return the input unchanged for 0 emitters.

The calibration path was already empty-safe (n_pairs < 100 -> fallback);
1-2 localization inputs already worked and are now covered by tests.

Add test/test_empty_input.jl covering 0/1/2 localizations (default and
calibration-enabled, concrete and abstract emitter eltype) plus the
combinelocalizations/precluster building blocks.

Patch bump 0.3.2 -> 0.3.3.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@kalidke kalidke marked this pull request as ready for review June 15, 2026 23:17
@kalidke kalidke merged commit 185706d into main Jun 15, 2026
6 checks passed
@kalidke kalidke deleted the fix/empty-localizations branch June 16, 2026 18:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant