Skip to main content

3D fluorescent puncta detection for microscopy z-stacks.

Project description

SNAPpy

SNAPpy is a Python implementation of a two-stage workflow for detecting fluorescent puncta in 3D microscopy z-stacks. It first finds candidate puncta with configurable 3D image-processing recipes, then uses local 3D features and an SVM classifier to remove false candidates.

The package includes bundled ch1, ch2, and ch3 models optimized for Rothstein lab z-stack images. These models are intended to make routine lab processing simple while preserving the lower-level API for training, benchmarking, and custom model development.

SNAPpy does not require a GPU. The primary publication benchmark ran SNAPpy on a small CPU-only AWS r7i.large worker with 2 vCPUs and 16 GiB RAM.

Installation

Install SNAPpy from PyPI with:

python -m pip install mrsnappy

Then check that the command-line tool is available:

mrsnappy --help

To install the current GitHub version instead of the PyPI release:

python -m pip install "git+https://github.com/marcorojas-cessa/SNAPpy.git"

If you are installing from a local checkout:

git clone https://github.com/marcorojas-cessa/SNAPpy.git
cd SNAPpy
python -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install .

For development:

python -m pip install -e ".[dev]"

Naming

  • The repository and project are named SNAPpy.
  • The PyPI distribution name is mrsnappy.
  • The terminal command is mrsnappy.
  • The Python import package is mrsnappy.

Python packages are installed with pip, so the install command is python -m pip install ..., not python install .... The PyPI name snappy is already used by an unrelated project, so SNAPpy uses mrsnappy as both its install name and command-line tool.

Quick Start

Run the optimized ch1 model on one 3D TIFF stack:

mrsnappy detect \
  --model ch1 \
  --input /path/to/zstack.tif \
  --output /path/to/detections.csv

Run the optimized ch2 or ch3 models by changing --model:

mrsnappy detect --model ch2 --input image.tif --output ch2_detections.csv
mrsnappy detect --model ch3 --input image.tif --output ch3_detections.csv

The output CSV contains detection_id, x, y, z, and score columns. Coordinates are written in image voxel coordinates, with z corresponding to the stack axis.

Typical output:

detection_id,x,y,z,score
1,42.3,88.1,12.0,1.74
2,51.9,91.5,13.2,0.62

Batch Detection

For a folder arranged as:

images/
  image_001.tif
  image_002.tif

run:

mrsnappy detect \
  --model ch1 \
  --input /path/to/images \
  --output /path/to/detections

For an explicit image list, pass --input-list image_paths.txt instead of --input.

Custom Model Detection

Use this only if you trained or optimized your own model:

mrsnappy detect \
  --model /path/to/model.joblib \
  --input /path/to/zstack.tif \
  --output /path/to/detections.csv

Optimized SNAPpy models embed the selected processing recipe. Use --config /path/to/config.yaml only when intentionally overriding that recipe.

Model Optimization

Create an editable optimization config, then run optimization:

mrsnappy init-config --output config.yaml
mrsnappy optimize \
  --train-dir /path/to/labeled_dataset \
  --out-dir /path/to/model \
  --config config.yaml

The config controls Stage 1 candidate-generation sweeps, Stage 1 pass/fail guardrails, the number of Stage 1 recipes shortlisted into Stage 2, Stage 2 feature-pack sweeps, fitting choices, and SVM tuning.

The train/ and val/ folders have distinct roles. SNAPpy uses train/ to fit the Stage 2 SVM candidate classifier. It uses val/ to screen and rank Stage 1 recipes, select Stage 2 feature/SVM settings, tune the final decision threshold, and choose the winning model. Final held-out test scoring should be done outside SNAPpy with mrsnappy detect.

The default Stage 1 background-correction sweep uses rolling_box_3d, a SciPy 3D grayscale-opening approximation that is substantially faster than exact 3D rolling-ball correction on large z-stacks. Custom configs can instead request slice_opening_2d for slice-wise 2D morphological opening, rolling_ball_2d for slice-wise scikit-image rolling-ball correction, or rolling_ball_3d for scikit-image n-dimensional rolling-ball correction.

Expected Dataset Layout

mrsnappy optimize expects a labeled dataset root containing train/ and val/ directories. Each 3D TIFF image must have a same-stem CSV file with ground-truth coordinates:

labeled_dataset/
  train/
    image_001.tif
    image_001.csv
    image_002.tif
    image_002.csv
  val/
    image_101.tif
    image_101.csv

Ground-truth CSV files must contain case-insensitive x, y, and z columns in voxel coordinates. TIFF files must contain finite numeric voxel values; images with NaN or Inf are rejected.

Optimizer Outputs

By default, optimization writes only the essential model files:

model/
  model.joblib
  model_manifest.json
  effective_config.yaml
  optimizer_plan.json
  dataset_profile.json
  summary.json
  summary.md

model.joblib is the trained model used by mrsnappy detect. model_manifest.json records the winning Stage 1 recipe, Stage 2 recipe, selected feature pack, SVM parameters, decision threshold, and validation metrics. effective_config.yaml is the exact resolved config used for the run. optimizer_plan.json records the number of Stage 1 configs, Stage 2 recipes after shortlist, and SVM settings before computation.

To export concise optimizer evidence, add:

mrsnappy optimize ... --export-optimize-report

This creates:

model/
  export_optimize_report/
    stage1_recipes.csv
    stage1_by_image.csv
    stage1_summary.csv
    stage2_recipes.csv
    stage2_summary.csv
    selection_decision.json
    selection_decision.md

stage1_recipes.csv lists every Stage 1 candidate-generation recipe and its ID. stage1_by_image.csv reports per-validation-image Stage 1 TP, FP, FN, candidate count, GT count, precision, recall, and F1 before SVM classification. stage1_summary.csv reports aggregate Stage 1 metrics, guardrail pass/fail status, preflight score, rank, and shortlist status. stage2_recipes.csv lists every Stage 2 recipe expanded from the shortlisted Stage 1 recipes. stage2_summary.csv reports the finalized Stage 1 plus Stage 2 validation outcome, including TP, FP, FN, precision, recall, F1, SVM parameters, decision threshold, runtime, and winner status.

To export candidate-level validation features for the winning pipeline, add:

mrsnappy optimize ... --export-candidate-features

This creates:

model/
  export_candidate_features/
    val_candidates.csv
    candidate_features_manifest.json

val_candidates.csv includes validation candidates from only the winning Stage 1 recipe and winning Stage 2 feature pack. It includes image_id, candidate_id, subpixel x/y/z, maxima_score, svm_score, model_score, decision_threshold, accepted_by_model, accepted_detection_id, candidate ground-truth label, matched GT ID and coordinates, nearest GT distance, and the selected feature columns. maxima_score is the detector response value at the candidate maximum before Gaussian fitting and SVM classification. For LoG detection, this is the robust-z-normalized LoG response. For h-max detection, this is the processed-image value at the accepted h-max local maximum.

The candidate feature export uses the fitted validation candidates generated during Stage 2 evaluation for the winning recipe and does not export non-winning recipes.

Custom Optimization Configs

The default config is only a readable YAML file. You can use it as a template:

mrsnappy init-config --output config.yaml

To test a small custom optimizer, edit config.yaml so it contains only the Stage 1 recipe, Stage 2 feature pack, fit variant, and SVM settings you want. The command stays the same:

mrsnappy optimize \
  --train-dir /path/to/labeled_dataset \
  --out-dir /path/to/custom_model \
  --config config.yaml

Before running an expensive optimization, inspect the planned search:

mrsnappy optimize \
  --train-dir /path/to/labeled_dataset \
  --out-dir /path/to/model \
  --config config.yaml \
  --dry-run

The dry run writes optimizer_plan.dry_run.json and prints the Stage 1 recipe count, Stage 2 recipe count after shortlist, SVM grid size, and safety caps without training a model.

Bundled Lab Models

Channel Source run Validation main F1 Test main F1 Notes
ch1 native_ch1_replay_v12 0.941 0.919 Strong performance on the ch1 validation and held-out test split.
ch2 native_ch2_replay_v5 0.862 0.885 Balanced precision/recall on the ch2 held-out test split.
ch3 native_ch3_replay_v5 0.935 0.858 High recall but lower strict localization F1; review detections for quantitative localization-sensitive analyses.

These bundled models were optimized on existing Rothstein lab channel-specific data. They should be validated on any new microscope, acquisition settings, sample preparation, or staining condition before being used for final quantitative conclusions.

Python API

The command-line interface is the simplest way to process routine lab images. Use the Python API when integrating SNAPpy into another analysis script.

from mrsnappy import detect, init_config, optimize, optimize_dry_run

detect(model="ch1", input_path="image.tif", output="detections.csv")
detect(model="/path/to/model.joblib", input_path="/path/to/images", output="/path/to/detections")

init_config("config.yaml")
optimize_dry_run(
    train_dir="/path/to/labeled_dataset",
    out_dir="/path/to/model",
    config="default",
)

optimize(
    train_dir="/path/to/labeled_dataset",
    out_dir="/path/to/model",
    config="default",
    export_optimize_report=True,
    export_candidate_features=False,
)

The API expects the same dataset layout and produces the same output files as the CLI. See docs/cli_api.md for the complete CLI/API reference.

How It Works

SNAPpy uses a two-stage workflow:

  1. It processes the 3D image with optional background correction, mandatory global robust z-score normalization, and optional smoothing, then searches for local maxima in 3D.
  2. It refines each candidate with local Gaussian-style fitting and measures intensity, shape, contrast, and background features.
  3. It applies a trained classifier to keep candidates that resemble true puncta and reject likely artifacts.
  4. It writes final 3D puncta coordinates and decision scores.

During optimization, SNAPpy first screens candidate-generation recipes on validation images for enough recall without excessive candidate burden. It then ranks the candidate-generation recipes that pass this screen and sends the top three Stage 1 configurations to Stage 2 by default. Stage 2 fits each SVM configuration on train/, evaluates it on all val/ images, and chooses the final recipe from validation performance.

See docs/workflow.md for a more detailed explanation.

Repository Scope

This repository contains the installable SNAPpy package, bundled lab-use models, documentation, and lightweight tests. Raw microscopy data, benchmark result trees, cluster logs, and manuscript-generation artifacts are intentionally excluded.

More Documentation

Citation

If you use SNAPpy in a publication, cite the associated manuscript once available.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mrsnappy-0.2.2.tar.gz (107.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mrsnappy-0.2.2-py3-none-any.whl (95.7 kB view details)

Uploaded Python 3

File details

Details for the file mrsnappy-0.2.2.tar.gz.

File metadata

  • Download URL: mrsnappy-0.2.2.tar.gz
  • Upload date:
  • Size: 107.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mrsnappy-0.2.2.tar.gz
Algorithm Hash digest
SHA256 dc61e8e2803fa2d2ea528a20e2c3cab8e0e8c4a8b8cb23a0244d7a376ab5ae14
MD5 570264e31d9e25d9ba9836e82f49032f
BLAKE2b-256 22b9d512285877e4794220be3a7978781f9c5a70e108969b0e7a426d9cfb3469

See more details on using hashes here.

File details

Details for the file mrsnappy-0.2.2-py3-none-any.whl.

File metadata

  • Download URL: mrsnappy-0.2.2-py3-none-any.whl
  • Upload date:
  • Size: 95.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for mrsnappy-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 20bb8ab593e9ed360547d0adf59c2bdf9bf6a6f263cdc78d7514a6eeb58e5f38
MD5 076576343c0d5dfc800d243d16cd2c23
BLAKE2b-256 05e14ae138ac21e96d7df75c74bfb43b41447b5e2e48da42fc3029814d3eef70

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page