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=4,                       # 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.8.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.8-py3-none-any.whl (97.3 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: isoview-0.1.8.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.8.tar.gz
Algorithm Hash digest
SHA256 228ef97ad3783f62468df31c1a7a8cf468d18bf7465e6a9543fe84dcee584a12
MD5 e2a67a7fa2f21240ad6f14017d3d7cc8
BLAKE2b-256 241a24056bea15e169bc4ee1a2723b948dd6cb24f071b2639efaa4499863ace2

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for isoview-0.1.8-py3-none-any.whl
Algorithm Hash digest
SHA256 4ca516dfb6543249aa2635957faa51262de17f7e9ab745ae9a2f8597c994eaae
MD5 01fa5753a1ebc27768dd1985d0dafd09
BLAKE2b-256 87b6d49a7444f6fa148180362ca7baa936c5067f2895370f6cc36b24431b7487

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