Skip to content

Commit

Permalink
Move PSOCT conversion script into modalities
Browse files Browse the repository at this point in the history
  • Loading branch information
calvinchai committed Nov 13, 2024
1 parent 3401c4c commit 9bd60d4
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 97 deletions.
5 changes: 5 additions & 0 deletions linc_convert/modalities/psoct/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""Dark Field microscopy converters."""

__all__ = ["cli", "multi_slice", "single_slice"]

from . import cli, multi_slice, single_slice
9 changes: 9 additions & 0 deletions linc_convert/modalities/psoct/cli.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""Entry-points for Dark Field microscopy converter."""

from cyclopts import App

from linc_convert.cli import main

help = "Converters for PS-OCT .mat files"
psoct = App(name="psoct", help=help)
main.command(psoct)
Original file line number Diff line number Diff line change
@@ -1,17 +1,8 @@
"""
(OCT) Matlab to OME-ZARR
========================
This script converts Matlab files generated by the MGH in-house OCT pipeline
into a pyramidal OME-ZARR hierarchy.
dependencies:
numpy
scipy
zarr
nibabel
cyclopts
Converts Matlab files generated by the MGH in-house OCT pipeline
into a OME-ZARR pyramid.
"""

Check failure on line 4 in linc_convert/modalities/psoct/placeholder.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (D205)

linc_convert/modalities/psoct/placeholder.py:1:1: D205 1 blank line required between summary line and description

Check failure on line 4 in linc_convert/modalities/psoct/placeholder.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (D205)

linc_convert/modalities/psoct/placeholder.py:1:1: D205 1 blank line required between summary line and description

import ast
import json
import math
Expand All @@ -30,12 +21,14 @@
import zarr
from scipy.io import loadmat

from utils import (
ceildiv, make_compressor, convert_unit, to_ome_unit, to_nifti_unit,
orientation_to_affine, center_affine
)
from linc_convert.modalities.psoct.cli import psoct
from linc_convert.utils.orientation import orientation_to_affine, center_affine
from linc_convert.utils.math import ceildiv
from linc_convert.utils.zarr import make_compressor
from linc_convert.utils.unit import (convert_unit, to_ome_unit, to_nifti_unit)

app = cyclopts.App(help_format="markdown")
placeholder = cyclopts.App(name="placeholder", help_format="markdown")
psoct.command(placeholder)


def automap(func):

Check failure on line 34 in linc_convert/modalities/psoct/placeholder.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (ANN201)

linc_convert/modalities/psoct/placeholder.py:34:5: ANN201 Missing return type annotation for public function `automap`

Check failure on line 34 in linc_convert/modalities/psoct/placeholder.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (ANN001)

linc_convert/modalities/psoct/placeholder.py:34:13: ANN001 Missing type annotation for function argument `func`

Check failure on line 34 in linc_convert/modalities/psoct/placeholder.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (ANN201)

linc_convert/modalities/psoct/placeholder.py:34:5: ANN201 Missing return type annotation for public function `automap`

Check failure on line 34 in linc_convert/modalities/psoct/placeholder.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (ANN001)

linc_convert/modalities/psoct/placeholder.py:34:13: ANN001 Missing type annotation for function argument `func`
Expand All @@ -53,7 +46,7 @@ def wrapper(inp, out=None, **kwargs):
return wrapper


@app.default
@placeholder.default
@automap
def convert(

Check failure on line 51 in linc_convert/modalities/psoct/placeholder.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (ANN201)

linc_convert/modalities/psoct/placeholder.py:51:5: ANN201 Missing return type annotation for public function `convert`

Check failure on line 51 in linc_convert/modalities/psoct/placeholder.py

View workflow job for this annotation

GitHub Actions / ruff

Ruff (ANN201)

linc_convert/modalities/psoct/placeholder.py:51:5: ANN201 Missing return type annotation for public function `convert`
inp: List[str],
Expand Down Expand Up @@ -435,6 +428,3 @@ def parse_value_unit(string, n=None):

return meta


if __name__ == "__main__":
app()
76 changes: 0 additions & 76 deletions scripts/utils.py → linc_convert/utils/unit.py
Original file line number Diff line number Diff line change
@@ -1,78 +1,3 @@
import math
import numcodecs
import numpy as np


def orientation_ensure_3d(orientation):
"""
Parameters
----------
orientation : str
Either one of {'coronal', 'axial', 'sagittal'}, or a two- or
three-letter permutation of {('R', 'L'), ('A', 'P'), ('S', 'I')}
Returns
-------
orientation : str
A three-letter permutation of {('R', 'L'), ('A', 'P'), ('S', 'I')}
"""
orientation = {
'coronal': 'LI',
'axial': 'LP',
'sagittal': 'PI',
}.get(orientation.lower(), orientation).upper()
if len(orientation) == 2:
if 'L' not in orientation and 'R' not in orientation:
orientation += 'R'
if 'P' not in orientation and 'A' not in orientation:
orientation += 'A'
if 'I' not in orientation and 'S' not in orientation:
orientation += 'S'
return orientation


def orientation_to_affine(orientation, vxw=1, vxh=1, vxd=1):
orientation = orientation_ensure_3d(orientation)
affine = np.zeros([4, 4])
vx = np.asarray([vxw, vxh, vxd])
for i in range(3):
letter = orientation[i]
sign = -1 if letter in 'LPI' else 1
letter = {'L': 'R', 'P': 'A', 'I': 'S'}.get(letter, letter)
index = list('RAS').index(letter)
affine[index, i] = sign * vx[i]
return affine


def center_affine(affine, shape):
if len(shape) == 2:
shape = [*shape, 1]
shape = np.asarray(shape)
affine[:3, -1] = -0.5 * affine[:3, :3] @ (shape - 1)
return affine


def ceildiv(x, y):
return int(math.ceil(x / y))


def floordiv(x, y):
return int(math.floor(x / y))


def make_compressor(name, **prm):
if not isinstance(name, str):
return name
name = name.lower()
if name == 'blosc':
Compressor = numcodecs.Blosc
elif name == 'zlib':
Compressor = numcodecs.Zlib
else:
raise ValueError('Unknown compressor', name)
return Compressor(**prm)


ome_valid_units = {
'space': [
'angstrom',
Expand Down Expand Up @@ -178,7 +103,6 @@ def make_compressor(name, **prm):
for short, long in si_prefix_short2long.items()
}


si_prefix_exponent = {
'Q': 30,
'R': 27,
Expand Down

0 comments on commit 9bd60d4

Please sign in to comment.