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
- Point
input_dirinpipeline/correct_stack.pyat your raw data directory. - Run
pipeline/correct_stack.py(correction) thenpipeline/multi_fuse.py(fusion). - Each step appends its config +
isoview_versiontoisoview_config.jsonnext 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}.xml → ch*.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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
228ef97ad3783f62468df31c1a7a8cf468d18bf7465e6a9543fe84dcee584a12
|
|
| MD5 |
e2a67a7fa2f21240ad6f14017d3d7cc8
|
|
| BLAKE2b-256 |
241a24056bea15e169bc4ee1a2723b948dd6cb24f071b2639efaa4499863ace2
|
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4ca516dfb6543249aa2635957faa51262de17f7e9ab745ae9a2f8597c994eaae
|
|
| MD5 |
01fa5753a1ebc27768dd1985d0dafd09
|
|
| BLAKE2b-256 |
87b6d49a7444f6fa148180362ca7baa936c5067f2895370f6cc36b24431b7487
|