Skip to content
Draft
Show file tree
Hide file tree
Changes from 128 commits
Commits
Show all changes
137 commits
Select commit Hold shift + click to select a range
b748e77
feat: add pipeline for converting single tiff file
calvinchai Oct 16, 2025
27f0d72
fix: hot fix for Emine
calvinchai Oct 16, 2025
cbf5572
wip: oct stitching
calvinchai Dec 4, 2025
2b892a7
wip: oct stitching
calvinchai Dec 4, 2025
e992222
wip: oct stitching
calvinchai Dec 4, 2025
4afb6ea
wip: oct stitching
calvinchai Dec 4, 2025
28a4fec
wip: psoct stitching
calvinchai Dec 4, 2025
9e757c9
refactor: simplify MosaicInfo creation by extracting dimensions and c…
calvinchai Dec 4, 2025
646f62c
feat: add mask loading and application to mosaic2d function, with cro…
calvinchai Dec 4, 2025
ae1856f
refactor: streamline image loading and enhance mosaic2d function with…
calvinchai Dec 4, 2025
cc1c26b
enhance: integrate progress bar for tile processing and streamline re…
calvinchai Dec 5, 2025
b10f06e
feat: add mosaic2d and mosaic3d to module
calvinchai Dec 5, 2025
ecc0d66
feat: enhance mosaic3d function with unit handling and improved NIfTI…
calvinchai Dec 5, 2025
6491067
feat: implement mosaic2d and mosaic3d modules for 2D and 3D mosaic cr…
calvinchai Dec 16, 2025
c8f0aae
refactor: update module exports to include renamed mosaic and mosaic_…
calvinchai Dec 16, 2025
d290267
Enhance SpoolSetInterpreter: Add raw_assembled_spool_shape attribute …
calvinchai Dec 16, 2025
4a11c0c
feat: Add stripe module for converting stripe spool files to Zarr format
calvinchai Dec 16, 2025
8fd30f7
Merge branch 'lsm-single-volume' into lsm-spool-stripe
calvinchai Dec 16, 2025
bb5d312
fix: center_affine call in NIfTI header processing
calvinchai Dec 16, 2025
807fc0a
fix: specify shape and dtype parameters in create_array method
calvinchai Dec 16, 2025
a7d9b9b
fix: center_affine call in NIfTI header processing
calvinchai Dec 16, 2025
d16578f
fix: specify shape and dtype parameters in create_array method
calvinchai Dec 16, 2025
94bd1b1
refactor: rename mosaic3d function to mosaic_complex for clarity
calvinchai Dec 16, 2025
58e5e0b
Add Docker support with Dockerfile, .dockerignore, and GitHub Actions…
calvinchai Dec 5, 2025
8c7c547
Refactor Dockerfile for Poetry installation and entrypoint
calvinchai Dec 16, 2025
0c376ba
add poetry lock file
calvinchai Dec 16, 2025
33de032
Implement multi-stage Docker build with Poetry
calvinchai Dec 16, 2025
79e209c
Add source label to Dockerfile
calvinchai Dec 16, 2025
c7b670d
Update Dockerfile syntax for build stages
calvinchai Dec 16, 2025
d835d1d
fix: line error when apply git
calvinchai Dec 16, 2025
21278a4
fix: spell error
calvinchai Dec 17, 2025
ca0fc5d
refactor: update parameter names and improve documentation in lsm str…
calvinchai Dec 17, 2025
1612cc7
refactor: optimize array concatenation in SpoolSetInterpreter
calvinchai Dec 17, 2025
b532118
Add Docker support with Dockerfile, .dockerignore, and GitHub Actions…
calvinchai Dec 5, 2025
1a2ca9f
Refactor Dockerfile for Poetry installation and entrypoint
calvinchai Dec 16, 2025
bc17826
add poetry lock file
calvinchai Dec 16, 2025
8ca5ddc
Implement multi-stage Docker build with Poetry
calvinchai Dec 16, 2025
3102533
Add source label to Dockerfile
calvinchai Dec 16, 2025
a543252
Update Dockerfile syntax for build stages
calvinchai Dec 16, 2025
f2d72b1
refactor: enhance focus plane handling and normalize weight calculati…
calvinchai Dec 19, 2025
a9547b0
feat: add focus plane support in mosaic2d function
calvinchai Dec 22, 2025
4810673
feat: add voxel size parameter to mosaic2d function
calvinchai Dec 22, 2025
9098230
fix: update window function to use nan-aware statistics in ZarrGroup
calvinchai Dec 23, 2025
78eddf1
feat: enhance mask handling in mosaic processing
calvinchai Dec 23, 2025
b4de82e
refactor: streamline image loading and mask handling in mosaic proces…
calvinchai Dec 23, 2025
87d20fe
Enhance SpoolSetInterpreter: Add raw_assembled_spool_shape attribute …
calvinchai Dec 16, 2025
fe95b2f
feat: Add stripe module for converting stripe spool files to Zarr format
calvinchai Dec 16, 2025
33cf064
feat: add pipeline for converting single tiff file
calvinchai Oct 16, 2025
197e341
fix: hot fix for Emine
calvinchai Oct 16, 2025
1bdd5f2
Add Docker support with Dockerfile, .dockerignore, and GitHub Actions…
calvinchai Dec 5, 2025
73a9665
Refactor Dockerfile for Poetry installation and entrypoint
calvinchai Dec 16, 2025
805525a
add poetry lock file
calvinchai Dec 16, 2025
2ef1723
Implement multi-stage Docker build with Poetry
calvinchai Dec 16, 2025
2939118
Add source label to Dockerfile
calvinchai Dec 16, 2025
9793886
Update Dockerfile syntax for build stages
calvinchai Dec 16, 2025
1e0573d
fix: line error when apply git
calvinchai Dec 16, 2025
264fd04
fix: spell error
calvinchai Dec 17, 2025
55c5cf1
refactor: update parameter names and improve documentation in lsm str…
calvinchai Dec 17, 2025
fbf5d71
refactor: optimize array concatenation in SpoolSetInterpreter
calvinchai Dec 17, 2025
984b790
Merge remote-tracking branch 'origin/lsm-features' into lsm-features
calvinchai Dec 23, 2025
0c0e49e
fix: typo
calvinchai Dec 23, 2025
178cf9d
fix: correct syntax for Dockerfile source label
calvinchai Dec 23, 2025
d6b1d8c
wip: oct stitching
calvinchai Dec 4, 2025
28cb9c0
wip: oct stitching
calvinchai Dec 4, 2025
2b42e99
wip: oct stitching
calvinchai Dec 4, 2025
65e2299
wip: oct stitching
calvinchai Dec 4, 2025
c222a1d
wip: psoct stitching
calvinchai Dec 4, 2025
f435d6d
refactor: simplify MosaicInfo creation by extracting dimensions and c…
calvinchai Dec 4, 2025
d90c705
feat: add mask loading and application to mosaic2d function, with cro…
calvinchai Dec 4, 2025
d6d920c
refactor: streamline image loading and enhance mosaic2d function with…
calvinchai Dec 4, 2025
08c8c02
enhance: integrate progress bar for tile processing and streamline re…
calvinchai Dec 5, 2025
f53b6aa
feat: add mosaic2d and mosaic3d to module
calvinchai Dec 5, 2025
ada14dc
feat: enhance mosaic3d function with unit handling and improved NIfTI…
calvinchai Dec 5, 2025
cc57a44
feat: implement mosaic2d and mosaic3d modules for 2D and 3D mosaic cr…
calvinchai Dec 16, 2025
2db1c6a
refactor: update module exports to include renamed mosaic and mosaic_…
calvinchai Dec 16, 2025
b124917
refactor: rename mosaic3d function to mosaic_complex for clarity
calvinchai Dec 16, 2025
d9eb881
Add Docker support with Dockerfile, .dockerignore, and GitHub Actions…
calvinchai Dec 5, 2025
09bcff5
Refactor Dockerfile for Poetry installation and entrypoint
calvinchai Dec 16, 2025
791317d
add poetry lock file
calvinchai Dec 16, 2025
63b7137
Implement multi-stage Docker build with Poetry
calvinchai Dec 16, 2025
184ce0a
Add source label to Dockerfile
calvinchai Dec 16, 2025
c8dc167
Update Dockerfile syntax for build stages
calvinchai Dec 16, 2025
8a978c6
refactor: enhance focus plane handling and normalize weight calculati…
calvinchai Dec 19, 2025
b57146d
feat: add focus plane support in mosaic2d function
calvinchai Dec 22, 2025
b5c284f
feat: add voxel size parameter to mosaic2d function
calvinchai Dec 22, 2025
1c4ea53
feat: enhance mask handling in mosaic processing
calvinchai Dec 23, 2025
b602b87
refactor: streamline image loading and mask handling in mosaic proces…
calvinchai Dec 23, 2025
a436ae0
Merge remote-tracking branch 'origin/oct-stitch' into oct-stitch
calvinchai Dec 24, 2025
bdcf6da
fix: add ndim property to H5ArrayWrapper and MatArrayWrapper classes
calvinchai Dec 24, 2025
6bce3f5
fix: add clipping functionality to focus plane in mosaic2d function
calvinchai Dec 26, 2025
8e523d6
update
calvinchai Dec 26, 2025
260e95a
Merge branch 'oct-stitch' into lsm-features
calvinchai Jan 13, 2026
cb11c08
feat: improve tile stitching process and normalize coordinates
calvinchai Jan 22, 2026
88d743c
feat: add tile configuration generator for PSOCT mosaics
calvinchai Jan 22, 2026
4c72768
fix: add logging and remove print statement in spool file loading
calvinchai Jan 27, 2026
eee7d05
refactor: move the stitching utility
calvinchai Jan 27, 2026
abe099f
fix: added missing import
calvinchai Jan 27, 2026
c628f3b
refactor: merge matlab io utils into one file
calvinchai Jan 27, 2026
f36b318
fix: correct voxel size format in NIfTI header construction
calvinchai Jan 27, 2026
62bc9c9
chore: make info_file to be optional in strip converter
calvinchai Jan 27, 2026
c5e44c2
tests: add regression test for lsm pipelines
calvinchai Jan 27, 2026
497e0b4
style: cleanup
calvinchai Jan 27, 2026
f56c989
refactor: move complex2processed function
calvinchai Jan 27, 2026
f54006e
docs: add type annotation for psoct pipelines
calvinchai Jan 27, 2026
960bfd6
tests: add regression test for psoct pipelines
calvinchai Jan 27, 2026
b1008f5
fix: make the edge of blending ramp non-zero
calvinchai Jan 27, 2026
395f2c3
style: clean up
calvinchai Jan 27, 2026
5827f7f
refactor: make the tile config generation to be a pipeline in psoct m…
calvinchai Jan 27, 2026
08c8788
chore: update test markers and options in pyproject.toml; remove work…
calvinchai Jan 27, 2026
18ae7cc
refactor: move lsm data fixture to be shared between files
calvinchai Jan 27, 2026
3460dfa
chore: update dependencies in poetry.lock and pyproject.toml; add sci…
calvinchai Jan 27, 2026
302498a
refactor: clean up whitespace and improve formatting in stitch.py
calvinchai Jan 27, 2026
3fe6603
style: improve code formatting and whitespace consistency in psoct mo…
calvinchai Jan 27, 2026
2220e49
fix: set XYZT units for Nifti1Image header in wk_annotation test
calvinchai Jan 28, 2026
db1033f
refactor: update path handling in TensorStore configuration functions…
calvinchai Jan 28, 2026
7a9f80e
test: add unit tests for linc_convert.utils.stitch module, covering t…
calvinchai Jan 28, 2026
021259f
fix: update array comparison in assert_zarr_equal to use assert_allcl…
calvinchai Jan 28, 2026
484350f
style: fix ruff error
calvinchai Feb 4, 2026
39c372c
feat: convert assembly methods in SpoolSetInterpreter to return Dask …
calvinchai Feb 23, 2026
7edc9f0
Implement conditional rechunking for result array
calvinchai Feb 23, 2026
dc8f324
feat: add functionality to save maximum intensity projection images i…
calvinchai Mar 4, 2026
4be1be6
made minor changes
Apr 21, 2026
8f77033
removed unused import
Apr 21, 2026
7205e45
docker workflow bug fix
Apr 21, 2026
7052050
reverted today's commits
Apr 21, 2026
c388aec
Apply suggestion from @kabilar
kabilar Jun 30, 2026
c2e0370
Apply suggestion from @kabilar
kabilar Jun 30, 2026
c5d7ab3
Apply suggestion from @kabilar
kabilar Jun 30, 2026
3df6573
Apply suggestion from @kabilar
kabilar Jun 30, 2026
7de1fd2
Apply suggestion from @kabilar
kabilar Jun 30, 2026
6017245
Apply suggestion from @kabilar
kabilar Jun 30, 2026
8bd371a
Apply suggestion from @kabilar
kabilar Jun 30, 2026
e8b02dd
Apply suggestion from @kabilar
kabilar Jun 30, 2026
e686add
Apply suggestion from @kabilar
kabilar Jun 30, 2026
4514c38
Apply suggestion from @kabilar
kabilar Jun 30, 2026
7af0cd2
Apply suggestion from @kabilar
kabilar Jun 30, 2026
d624d22
Apply suggestion from @kabilar
kabilar Jun 30, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# Git
.git
.gitignore
.github

# Python
__pycache__
*.py[cod]
*$py.class
*.so
.Python
*.egg-info
dist
build
.venv
venv
env
ENV

# Testing
.pytest_cache
.coverage
htmlcov
.tox
.mypy_cache
.ruff_cache

# Documentation
site
docs/requirements.txt

# IDE
.vscode
.idea
*.swp
*.swo
*~

# OS
.DS_Store
Thumbs.db

# Project specific
scripts/*.ipynb
scripts/*.nii
scripts/*.tiff
scripts/*.jpeg
scripts/*.yaml
tests/data

# Poetry
poetry.lock.bak

2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,4 @@ jobs:
run: poetry install --with dev --extras all
- name: Run the automated tests
run: poetry run pytest -v
working-directory: ./tests
working-directory: tests
65 changes: 65 additions & 0 deletions .github/workflows/docker-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
name: Build and Push Docker Image

on:
push:
branches:
- main
- master
tags:
- 'v*'
pull_request:
branches:
- main
- master
workflow_dispatch:

env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}

jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=ref,event=pr
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha,prefix={{branch}}-
Comment thread
kabilar marked this conversation as resolved.
Outdated
type=raw,value=latest,enable={{is_default_branch}}

- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: .
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha
cache-to: type=gha,mode=max

62 changes: 62 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# ----------------------------------------------------------------------------
# STAGE 1: Builder
# Used to install Poetry, compile dependencies, and create the virtual environment.
# ----------------------------------------------------------------------------
FROM python:3.11-slim AS builder

# Set working directory
WORKDIR /app

# Install build dependencies (GCC, etc.)
# We need these to compile packages, but we don't want them in the final image.
RUN apt-get update && apt-get install -y \
build-essential \
&& rm -rf /var/lib/apt/lists/*

# Install Poetry
RUN pip install poetry==1.8.4

# Configure Poetry to create the venv inside the project folder
# This makes it easy to copy the whole folder to the next stage
ENV POETRY_NO_INTERACTION=1 \
POETRY_VIRTUALENVS_IN_PROJECT=1 \
POETRY_VIRTUALENVS_CREATE=1 \
POETRY_CACHE_DIR=/tmp/poetry_cache

# Copy dependency definition files first (for caching)
COPY pyproject.toml poetry.lock ./
RUN poetry lock
# Install dependencies (only the libraries)
RUN poetry install --no-root --no-dev --extras all && rm -rf $POETRY_CACHE_DIR

# Copy the rest of the application code
COPY . .
RUN poetry lock
# Install the application itself
#RUN poetry install --no-dev --extras all
RUN poetry build -f wheel
RUN ./.venv/bin/pip install dist/*.whl
# ----------------------------------------------------------------------------
# STAGE 2: Runtime
# A fresh, empty image that only contains the Python runtime and our copied venv.
# ----------------------------------------------------------------------------
FROM python:3.11-slim AS runtime

WORKDIR /app

# Create a non-root user for security (Best Practice)
RUN useradd -m -r appuser && chown appuser /app
USER appuser

# Copy the virtual environment from the builder stage
# We assume the path structure is identical (/app/.venv)
COPY --from=builder --chown=appuser:appuser /app/.venv /app/.venv

# Update PATH environment variable
# This allows us to type 'linc-convert' instead of '/app/.venv/bin/linc-convert'
ENV PATH="/app/.venv/bin:$PATH"
LABEL org.opencontainers.image.source=https://github.com/lincbrain/linc-convert
# Set the entrypoint
ENTRYPOINT ["linc-convert"]
# Default command
CMD ["--help"]
20 changes: 18 additions & 2 deletions linc_convert/modalities/lsm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,24 @@
try:
import tifffile as _ # noqa: F401

__all__ = ["cli", "mosaic", "multi_slice", "spool"]
__all__ = [
"cli",
"mosaic",
"multi_slice",
"spool",
"single_volume",
"strip",
"stitch_strips"
]

from . import cli, mosaic, multi_slice, spool
from . import (
cli,
mosaic,
multi_slice,
single_volume,
spool,
stitch_strips,
strip,
)
except ImportError:
pass
1 change: 1 addition & 0 deletions linc_convert/modalities/lsm/mosaic.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
Example input files can be found at
https://lincbrain.org/dandiset/000004/0.240319.1924/files?location=derivatives%2F
"""

import logging

# stdlib
Expand Down
3 changes: 2 additions & 1 deletion linc_convert/modalities/lsm/multi_slice.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
Example input files can be found at
https://lincbrain.org/dandiset/000010/draft/files?location=sourcedata%2Fderivatives
"""

import logging

# stdlib
Expand Down Expand Up @@ -45,7 +46,7 @@ def convert(
) -> None:
"""
Convert a collection of tiff files generated by the LSM pipeline into a Zarr.

Parameters
----------
inp
Expand Down
89 changes: 89 additions & 0 deletions linc_convert/modalities/lsm/single_volume.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
""" Converts TIFF to OME-Zarr or NIfTI-Zarr. """

Check failure on line 1 in linc_convert/modalities/lsm/single_volume.py

View workflow job for this annotation

GitHub Actions / ruff

ruff (D210)

linc_convert/modalities/lsm/single_volume.py:1:1: D210 No whitespaces allowed surrounding docstring text help: Trim surrounding whitespace
Comment thread
kabilar marked this conversation as resolved.
Outdated

import logging
import os

import cyclopts
import dask.array as da
import dask_image.imread
import numpy as np

from linc_convert.modalities.lsm.cli import lsm
from linc_convert.utils.io.zarr import from_config
from linc_convert.utils.nifti_header import build_nifti_header
from linc_convert.utils.unit import to_ome_unit
from linc_convert.utils.zarr_config import (
GeneralConfig,
NiftiConfig,
ZarrConfig,
autoconfig,
)

logger = logging.getLogger(__name__)
single_volume = cyclopts.App(name="single_volume", help_format="markdown")
lsm.command(single_volume)


@single_volume.default
@autoconfig
def convert(
inp: str,
*,
Comment thread
kabilar marked this conversation as resolved.
general_config: GeneralConfig = None,
zarr_config: ZarrConfig = None,
nii_config: NiftiConfig = None,
) -> None:
"""
Tiff to OME-Zarr.

Convert tiff files
into a pyramidal OME-ZARR (or NIfTI-Zarr) hierarchy.

Parameters
----------
inp
Path to the input tiff file
Comment thread
kabilar marked this conversation as resolved.
general_config
General configuration
zarr_config
Zarr related configuration
nii_config
NIfTI header related configuration
"""
general_config.set_default_name(os.path.splitext(inp)[0])

inp_data = dask_image.imread.imread(inp)

# Prepare Zarr group
zgroup = from_config(general_config.out, zarr_config)

if not hasattr(inp_data, "dtype"):
raise Exception("Input is not a numpy array. This is unexpected.")

dataset = zgroup.create_array(
"0",
shape=inp_data.shape,
dtype=np.dtype(inp_data.dtype),
zarr_config=zarr_config,
)

if dataset.shards:
inp_data = da.rechunk(inp_data, dataset.shards)
else:
inp_data = da.rechunk(inp_data, dataset.chunks)

da.store(inp_data, dataset)
Comment thread
kabilar marked this conversation as resolved.
zgroup.generate_pyramid(mode="mean", no_pyramid_axis=zarr_config.no_pyramid_axis)
logger.info("Write OME-Zarr multiscale metadata")
zgroup.write_ome_metadata(axes=["z", "y", "x"], space_unit=to_ome_unit("um"))

if nii_config.nii:
header = build_nifti_header(
zgroup=zgroup,
voxel_size_zyx=[1, 1, 1],
unit="um",
Comment thread
kabilar marked this conversation as resolved.
Outdated
nii_config=nii_config,
)
zgroup.write_nifti_header(header)

logger.info("Conversion complete.")
2 changes: 1 addition & 1 deletion linc_convert/modalities/lsm/spool.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
https://lincbrain.org/dandiset/000010/draft/files?location=sourcedata%2Frawdata
%2Fmicr%2Fsample18_run10__y10_z01_HR&page=1
"""

import logging

# stdlib
Expand Down Expand Up @@ -233,4 +234,3 @@ def convert(
omz.write_nifti_header(header)

logger.info("Conversion complete.")

Loading
Loading