Skip to main content

Multi-view light sheet microscopy image processing pipeline

Project description

IsoView Light Sheet Microscopy Pipeline

Input is a flat directory of raw SPC##_TM#####_ANG###_CM#_CHN##_PH#.stack files (little-endian uint16) with a push_config XML per channel describing the acquisition (dimensions, pixel/axial spacing, wavelength, exposure, stage, etc.).

Quickstart

  1. Point input_dir in pipeline/correct_stack.py at your raw data directory.
  2. Run pipeline/correct_stack.py (correction) then pipeline/multi_fuse.py (fusion).
  3. Each step appends its config + isoview_version to isoview_config.json next to the data, so every run is reproducible.

Usage

Entrypoints: pipeline/correct_stack.py (correction) and pipeline/multi_fuse.py (fusion).

from pathlib import Path
from isoview import ProcessingConfig, correct_stack, multi_fuse

config = ProcessingConfig(
    input_dir=Path(r"E:\isoview\dataset"),
    # specimens=None,                       # auto-detect from SPC## in filenames
    # timepoints=None,                      # auto-detect from TM## in filenames
    output_suffix="",                       # appended as ".corrected_<suffix>" / ".fused_<suffix>" if set
    specimen=0,                             # default specimen index
    camera_pairs=[(0, 1), (2, 3)],          # ortho camera pairs to fuse

    # output
    output_format="tif",                    # tif, zarr, or klb
    compression="zstd",                     # zstd, lzw, deflate, or None
    compression_level=3,                    # 1-22 for zstd, 1-9 for others

    # transforms (applied to second camera in each pair)
    rotation=0,                             # 0=none, 1=90cw, -1=90ccw
    flip_horizontal=False,
    flip_vertical=False,

    # correction
    median_kernel=(3, 3),                   # dead pixel filter, None to disable
    background_percentile=5.0,
    mask_percentile=1.0,
    segment_mode=1,                         # 0=none, 1=segment+mask, 2=masks, 3=global

    # fusion
    blending_method="adaptive",             # adaptive, geometric, average, wavelet
    blending_range=20,                      # transition zone width (z-planes)

    # per-specimen overrides (tiled mode)
    # tile_crops={"SPM00": {"crop_depth": {0: 450}}}
    # view_orientation={"SPM00": {"flip_axis": 1}, "SPM01": {"flip_axis": 0}}
)

correct_stack(config)
multi_fuse(config)

Acquisition Modes

Raw input is always flat — SPC##_TM#####_ANG###_CM#_CHN##_PH#.stack files in a single directory. Mode is auto-detected from SPC/TM counts:

Condition Mode Description
Multiple TM values timelapse time series, any number of specimens
Single TM + multiple SPC tiled spatial tiles, one timepoint
Single TM + single SPC single treated as timelapse with 1 timepoint

XML Metadata

read_xml_metadata(xml_path) parses one push_config XML; read_all_xml_metadata(input_dir, specimen) returns (common, per_camera) — fields equal across cameras vs camera-specific.

Field Type Source Notes
data_header str @data_header acquisition session label
specimen_name str @specimen_name
timestamp str @timestamp acquisition datetime
time_point int @time_point
specimen_XYZT str @specimen_XYZT also parsed → stage_x/y/z (float, µm)
angle float @angle
camera_index str @camera_index comma-separated per camera
camera_type str @camera_type
camera_roi str @camera_roi
wavelength str @wavelength emission, per camera
illumination_arms str @illumination_arms per camera
illumination_filter str @illumination_filter
exposure_time float @exposure_time ms
detection_filter str @detection_filter
detection_objective str @detection_objective also parsed → objective_mag (float)
dimensions ndarray @dimensions (n_cameras, 3) from "WxHxD,WxHxD,…"
z_step float @z_step µm; VW00 (Z-scan)
y_step float @y_step µm; VW90 (Y-scan)
stack_direction str @stack_direction drives camera_view_map
planes str @planes
laser_power str @laser_power
experiment_notes str @experiment_notes
zplanes int derived dimensions[0][-1]
fps float derived 1000.0 / exposure_time
vps float derived fps / zplanes
camera_pixel_size_um float constant 6.5 (Hamamatsu C11440-22C)
pixel_resolution_um float derived camera_pixel_size_um / objective_mag
axial_step float merged unifies z_step / y_step across XMLs
camera_view_map dict synthesized from stack_direction: Z-scan → {0:0,1:0}, Y-scan → {2:90,3:90}

XML discovery order (in read_all_xml_metadata): ch*_spec{NN}.xmlch*.xml*_CHN*.xml. Channel inferred from filename via ch(\d+)CHN(\d+)VW(\d+).

Filename Tags

Tag Meaning Raw Corrected Fused
SPC## / SPM## specimen / tile SPC00 SPM00 SPM00
TM###### timepoint TM00000 TM000000 TM000000
CM## camera CM0 CM00 CM00_CM01 (pair)
CHN## acquisition channel CHN00, CHN01 CHN00, CHN01 CHN00, CHN01
VW## fused view (scan axis) VW00 (z-scan), VW90 (y-scan)
ANG### illumination angle ANG000
PH# phase PH0

Correction iterates over all (camera, channel) pairs present in the raw data, so dual-channel acquisitions (same camera capturing multiple wavelengths) produce one corrected volume per (CM, CHN). Fusion fuses each camera pair separately for every channel both cameras share.

Output Layout

Correction writes to {input_dir.name}.corrected[_<output_suffix>] (default .corrected) and fusion writes to a sibling {input_dir.name}.fused[_<output_suffix>] (default .fused), both as siblings of the raw input directory. output_suffix is one shared field — a non-empty value is appended as _<value> to every per-step prefix (.corrected, .fused, .stitcher).

Correction (correct_stack.py)

Mode Path Filename
Timelapse root.corrected/SPM00/TM000000/ SPM00_TM000000_CM00_CHN00.ome.tif
Tiled root.corrected/SPM00/ SPM00_CM00_CHN00.ome.tif

Each tile gets a SPM0N folder, where N is the tile index. Each SPM## dir also contains a projections/ subfolder with per-view XY MIPs and a raw.xyProjection counterpart for QC. Masks share the same prefix with suffixes .segmentationMask, .xyMask, .xzMask. minIntensity.npz carries the percentile values used downstream.

Fusion (multi_fuse)

Mode Path Filename
Timelapse root.fused/adaptive/SPM00/TM000000/ SPM00_TM000000_CM00_CM01_VW00_CHN00.ome.tif
Tiled root.fused/adaptive/SPM00/ SPM00_CM00_CM01_VW00_CHN00.ome.tif

Default pairs: [(0, 1), (2, 3)] — cameras 0,1 fuse to VW00 (z-scan); cameras 2,3 fuse to VW90 (y-scan). The CHN value reflects the acquisition channel of the pair (in the standard Keller IsoView wiring, CHN00 for CM0/1 and CHN01 for CM2/3). For dual-channel acquisitions, each pair fuses once per shared channel, producing multiple outputs with the same VW## but different CHN##.

Only the second camera in each pair gets rotation/flip transforms.

Supported Output Formats

Format Extension Notes
OME-TIFF .ome.tif with metadata, optional resolution pyramids
Zarr v3 ome.zarr OME-NGFF metadata
KLB .klb Keller Lab Block (bzip2)

.stack Reading

Raw .stack is little-endian uint16, shape (D, H, W), memmappable. (W, H) from XML @dimensions[0]; D derived from file size (stat().st_size // 2 // (H*W)) — XML's D may be stale on aborted acquisitions.

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

isoview-0.1.6.tar.gz (2.7 MB view details)

Uploaded Source

Built Distribution

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

isoview-0.1.6-py3-none-any.whl (95.2 kB view details)

Uploaded Python 3

File details

Details for the file isoview-0.1.6.tar.gz.

File metadata

  • Download URL: isoview-0.1.6.tar.gz
  • Upload date:
  • Size: 2.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.2

File hashes

Hashes for isoview-0.1.6.tar.gz
Algorithm Hash digest
SHA256 cac75956859cee64cc6b69436687ba72f019ebfc6c737ed43feb4e4395a9bf7f
MD5 1e749c2677bef54d3d5da948915b2699
BLAKE2b-256 d1c5672ac79a12eaafe201837207861c7ee532f06fd5ce346c6694325ac91649

See more details on using hashes here.

File details

Details for the file isoview-0.1.6-py3-none-any.whl.

File metadata

  • Download URL: isoview-0.1.6-py3-none-any.whl
  • Upload date:
  • Size: 95.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.9.2

File hashes

Hashes for isoview-0.1.6-py3-none-any.whl
Algorithm Hash digest
SHA256 bf3e16e04c6956cf8836ca7a93f11faf263fff55449433a8d55055f76f9aa733
MD5 e7782fd5409d4ea8bbebf5b9239c87ed
BLAKE2b-256 dbfe621fd2b12523b80c816c8e0d3867ed3972a5696687e462f8a0b0bb6b83de

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