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.

SNAPpy does not include trained model artifacts in the package. A model used for detection must be generated by the current mrsnappy optimize workflow and passed to mrsnappy detect as a model.joblib path.

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

Create a model from labeled train/ and val/ images, then run detection on a 3D TIFF stack:

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

mrsnappy detect \
  --model /path/to/model/model.joblib \
  --input /path/to/zstack.tif \
  --output /path/to/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 /path/to/model/model.joblib \
  --input /path/to/images \
  --output /path/to/detections

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

Model Detection

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.

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="/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, documentation, and lightweight tests. Raw microscopy data, trained model artifacts, 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.3.tar.gz (68.7 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.3-py3-none-any.whl (53.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: mrsnappy-0.2.3.tar.gz
  • Upload date:
  • Size: 68.7 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.3.tar.gz
Algorithm Hash digest
SHA256 219aa91c86e8905ac1b48dd22489d26ef57bfb915975fe3e3541b472b48e09f7
MD5 7cd9a79c866224723604134980337c67
BLAKE2b-256 cdc6b069d80f460f4d30688393dc1005b55fae61806639058308acd1a78bdc55

See more details on using hashes here.

File details

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

File metadata

  • Download URL: mrsnappy-0.2.3-py3-none-any.whl
  • Upload date:
  • Size: 53.6 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.3-py3-none-any.whl
Algorithm Hash digest
SHA256 054450ffdcb3f8e88304b02dde07115e155a60ab84c25460ed4c27b81ab14096
MD5 5ea1e1bf5e83c1782d3a219ec522a3b6
BLAKE2b-256 d58e90edce64a1bb63eba49e5c32e9f20942c1033f63aa10db7723f11925fd6c

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