2.5D Reconstruction Workflow#
Overview#
The 2.5D reconstruction workflow (soct_2.5d_reconst.nf) converts a set of per-slice 2D mosaic
grids (TIFF format) into a stacked 3D volume using illumination correction, image-based tile
placement, and XY-shift-based stacking.
This is the legacy workflow. New acquisitions should use the full
3D Reconstruction Workflow
(soct_3d_reconst.nf), which operates on OME-Zarr mosaic grids and provides much richer
correction and diagnostics.
When to Use This Workflow#
Data acquired as TIFF-format mosaic grids (
mosaic_grid_z*.tiff)Re-processing older datasets that pre-date the OME-Zarr pipeline
Quick 2D stitching + stacking without the full 3D pipeline overhead
Location#
workflows/reconst_2.5d/
├── soct_2.5d_reconst.nf # Workflow definition
├── soct_2.5d_reconst_beluga.config # Compute Canada / Beluga cluster config
└── soct_2.5d_reconst_docker.config # Docker-based config
Input#
Item |
Description |
|---|---|
|
Directory of |
|
XY inter-slice shifts file (standard linumpy format) |
Running#
# Basic usage (run from workflow directory or with full path)
nextflow run soct_2.5d_reconst.nf \
--directory /path/to/subject
# With custom output directory and resolution
nextflow run soct_2.5d_reconst.nf \
--directory /path/to/subject \
--output_directory /path/to/output
# Resume after partial run
nextflow run soct_2.5d_reconst.nf \
--directory /path/to/subject \
-resume
Parameters#
Parameter |
Default |
Description |
|---|---|---|
|
|
Root subject directory |
|
|
Directory containing |
|
|
Inter-slice XY shifts file |
|
|
Output directory |
Tile Shape#
Parameter |
Default |
Description |
|---|---|---|
|
|
Tile width in pixels |
|
|
Tile height in pixels |
|
|
Lateral pixel spacing (µm) |
|
|
Axial (slice) spacing (µm) |
Tile Cropping#
A border is removed from each tile before processing to avoid edge artifacts.
Parameter |
Default |
Description |
|---|---|---|
|
|
Left crop (pixels) |
|
|
Right crop (pixels); effective tile width = |
|
|
Top crop (pixels) |
|
|
Bottom crop (pixels); effective tile height = |
Illumination Bias#
Parameter |
Default |
Description |
|---|---|---|
|
|
Tiles sampled to estimate flat-field |
|
|
Tiles sampled to estimate dark-field |
|
|
Internal BaSIC working resolution (pixels) |
Stitching#
Parameter |
Default |
Description |
|---|---|---|
|
|
Expected tile overlap fraction for position estimation |
Output Resolution#
Parameter |
Default |
Description |
|---|---|---|
|
|
Isotropic resolution for the resampled NIfTI output (µm) |
Pipeline Processes#
The workflow runs processes in a linear sequence:
flowchart TD
A[crop_tiles] --> B[estimate_illumination_bias]
B --> C[compensate_illumination_bias]
C --> D[estimate_position<br/>pools all grids]
C --> E[stitch_mosaic<br/>per-slice]
D --> E
E --> F[stack_mosaic]
F --> G[compress_stack<br/>stack.zarr.zip]
F --> H[convert_to_omezarr]
H --> I[resample_stack<br/>stack_10um.nii.gz]
F --> J[(stack.zarr)]
1. crop_tiles#
Crops a border from each tile within the mosaic grid TIFF to remove edge artifacts.
linum_crop_tiles.py <mosaic_dir> <output.tiff> --xmin --xmax --ymin --ymax --tile_shape
Input: mosaic_grid_z*.tiff directory
Output: {basename}_cropped.tiff
2. estimate_illumination_bias#
Estimates per-tile flat-field and dark-field using the BaSIC algorithm.
linum_estimate_illumination.py <mosaic.tiff> <flatfield.nii.gz> --tile_shape --output_darkfield
Input: Cropped mosaic grid (per slice)
Output: {key}_flatfield.nii.gz, {key}_darkfield.nii.gz
3. compensate_illumination_bias#
Applies the estimated flat/dark field correction to each mosaic grid.
linum_compensate_illumination.py <mosaic.tiff> <output.nii.gz> --flatfield --darkfield --tile_shape
Input: Cropped mosaic + flat/dark field
Output: {key}_mosaic_grid_compensated.nii.gz
4. estimate_position#
Pools all compensated mosaic grids to estimate a single shared tile-placement transform (.npy).
This single transform is applied to all slices, avoiding per-slice jitter.
linum_estimate_transform.py <all_mosaics...> <position_transform.npy> --tile_shape --initial_overlap
Input: All compensated mosaic grids (collected)
Output: position_transform.npy
5. stitch_mosaic#
Stitches each compensated mosaic grid into a 2D slice using the shared position transform.
Blending method is diffusion.
linum_stitch_2d.py <mosaic.nii.gz> <transform.npy> <output.nii.gz> --blending_method diffusion --tile_shape
Input: Compensated mosaic (per slice) + position transform
Output: {key}_stitched.nii.gz
6. stack_mosaic#
Stacks all stitched 2D slices into a 3D volume using XY shifts from shifts_xy.csv.
linum_stack_slices.py <all_stitched...> stack.zarr --xy_shifts --resolution_xy --resolution_z
Input: All stitched slices (collected) + shifts CSV
Output: stack.zarr
7. compress_stack#
Compresses the Zarr stack to a ZIP archive for transfer.
Input: stack.zarr
Output: stack.zarr.zip
8. convert_to_omezarr#
Converts the Zarr stack to OME-Zarr format for visualization in napari/neuroglancer.
Input: stack.zarr
Output: stack.ome.zarr
9. resample_stack#
Resamples the OME-Zarr to isotropic resolution and exports a NIfTI file.
linum_convert_omezarr_to_nifti.py stack.ome.zarr stack_10um.nii.gz --resolution 10.0
Input: stack.ome.zarr
Output: stack_10um.nii.gz
Outputs#
File |
Description |
|---|---|
|
Full-resolution 3D volume (Zarr format) |
|
Compressed archive of |
|
OME-Zarr for visualization |
|
Isotropic 10 µm NIfTI for atlas registration and analysis |
Cluster / Container Configs#
Config |
Use case |
|---|---|
|
Compute Canada Beluga cluster (SLURM) |
|
Docker container execution |
# Beluga cluster
nextflow run soct_2.5d_reconst.nf \
--directory /path/to/subject \
-c soct_2.5d_reconst_beluga.config
# Docker
nextflow run soct_2.5d_reconst.nf \
--directory /path/to/subject \
-c soct_2.5d_reconst_docker.config
Differences from the 3D Workflow#
Aspect |
2.5D workflow |
3D workflow |
|---|---|---|
Input format |
TIFF mosaic grids |
OME-Zarr mosaic grids |
Tile illumination |
BaSIC (per-slice) |
BaSIC (per-slice via |
Tile placement |
Image-based (phase correlation) |
Motor positions + optional image refinement |
Slice alignment |
Motor XY shifts only |
Motor + pairwise registration |
Quality assessment |
None |
Optional auto quality assessment |
Re-homing correction |
None |
|
Interpolation |
None |
|
Atlas registration |
None (requires separate NIfTI step) |
Integrated |
Output |
|
|