Skip to content

Commit 87678cd

Browse files
committed
refactor: port fixes on main to refactor branch
1 parent 129d6cc commit 87678cd

9 files changed

Lines changed: 84 additions & 57 deletions

File tree

src/aind_zarr_utils/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
neuroglancer_annotations_to_indices,
2525
)
2626
from .origin import Origin
27-
from .points import Points, Space
2827

2928
# Pipeline integration
3029
from .pipeline_transformed import (
@@ -36,6 +35,7 @@
3635
neuroglancer_to_ccf_auto_metadata,
3736
swc_data_to_ccf_auto_metadata,
3837
)
38+
from .points import Points, Space
3939
from .zarr import (
4040
scaled_points_to_indices,
4141
zarr_to_ants,

src/aind_zarr_utils/asset.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ def _eagerly(
272272
template_used: str,
273273
template_base: str | os.PathLike | None,
274274
) -> Asset:
275-
"""Internal: build an :class:`Asset` and pre-open its Zarr."""
275+
"""Build an :class:`Asset` and pre-open its Zarr (internal helper)."""
276276
kwargs: dict[str, Any] = {
277277
"zarr_uri": zarr_uri,
278278
"metadata": metadata,

src/aind_zarr_utils/io/processing.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,15 @@
1010

1111
from __future__ import annotations
1212

13+
import logging
1314
from pathlib import PurePosixPath
1415
from typing import Any
1516

1617
from aind_zarr_utils.io.paths import _zarr_base_name_pathlike
1718

19+
logger = logging.getLogger(__name__)
20+
_KNOWN_GOOD_PIPELINE_VERSIONS = {3, 4, 5}
21+
1822

1923
def _get_processing_pipeline_data(
2024
processing_data: dict[str, Any],
@@ -42,8 +46,17 @@ def _get_processing_pipeline_data(
4246
if not ver_str:
4347
raise ValueError("Missing pipeline version")
4448
pipeline_ver = int(ver_str.split(".")[0])
45-
if pipeline_ver not in set((3, 4)):
46-
raise ValueError(f"Unsupported pipeline version: {pipeline_ver}")
49+
if pipeline_ver not in _KNOWN_GOOD_PIPELINE_VERSIONS:
50+
maxver = max(_KNOWN_GOOD_PIPELINE_VERSIONS)
51+
if pipeline_ver > maxver:
52+
logger.warning(
53+
f"Pipeline version {pipeline_ver} is greater than max "
54+
f"verified version {maxver}, results may not be accurate. "
55+
"File an issue at "
56+
"https://github.com/AllenNeuralDynamics/aind-zarr-utils/issues."
57+
)
58+
else:
59+
raise ValueError(f"Unsupported pipeline version: {pipeline_ver}")
4760
pipeline: dict[str, Any] = processing_data.get("processing_pipeline", {})
4861
return pipeline
4962

src/aind_zarr_utils/io/transforms.py

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,25 @@
1515

1616
from __future__ import annotations
1717

18+
import logging
1819
import os
1920
from dataclasses import dataclass
2021
from typing import TYPE_CHECKING, Any
2122

22-
from aind_s3_cache.s3_cache import (
23-
get_local_path_for_resource,
24-
)
23+
from aind_s3_cache.s3_cache import get_local_path_for_resource
2524
from aind_s3_cache.uri_utils import as_pathlike, as_string, join_any
2625

2726
from aind_zarr_utils.io.paths import _asset_from_zarr_pathlike
2827
from aind_zarr_utils.io.processing import (
28+
_get_processing_pipeline_data,
2929
image_atlas_alignment_path_relative_from_processing,
3030
)
3131

3232
if TYPE_CHECKING:
3333
from mypy_boto3_s3 import S3Client
3434

35+
logger = logging.getLogger(__name__)
36+
3537

3638
@dataclass(slots=True, frozen=True)
3739
class TransformChain:
@@ -108,7 +110,7 @@ class TemplatePaths:
108110
)
109111
}
110112

111-
_PIPELINE_INDIVIDUAL_TRANSFORM_CHAINS: dict[int, TransformChain] = {
113+
_KNOWN_INDIVIDUAL_TRANSFORM_CHAINS: dict[int, TransformChain] = {
112114
3: TransformChain(
113115
fixed="template",
114116
moving="individual",
@@ -125,6 +127,34 @@ class TemplatePaths:
125127
)
126128
}
127129

130+
_PIPELINE_INDIVIDUAL_TRANSFORM_CHAINS: dict[int, TransformChain] = {
131+
3: _KNOWN_INDIVIDUAL_TRANSFORM_CHAINS[3],
132+
4: _KNOWN_INDIVIDUAL_TRANSFORM_CHAINS[3],
133+
5: _KNOWN_INDIVIDUAL_TRANSFORM_CHAINS[3],
134+
}
135+
136+
137+
def _resolve_individual_transform_chain(
138+
pipeline_ver: int,
139+
) -> TransformChain:
140+
"""Look up the individual (LS → template) transform chain for a pipeline major version.
141+
142+
Falls back to the latest known chain when the version is newer than
143+
anything registered.
144+
"""
145+
chain = _PIPELINE_INDIVIDUAL_TRANSFORM_CHAINS.get(pipeline_ver)
146+
if chain is not None:
147+
return chain
148+
max_known = max(_PIPELINE_INDIVIDUAL_TRANSFORM_CHAINS)
149+
if pipeline_ver > max_known:
150+
logger.warning(
151+
f"No individual transform chain registered for pipeline "
152+
f"version {pipeline_ver}; falling back to chain for version "
153+
f"{max_known}. Results may not be accurate."
154+
)
155+
return _PIPELINE_INDIVIDUAL_TRANSFORM_CHAINS[max_known]
156+
raise ValueError(f"No individual transform chain registered for pipeline version {pipeline_ver}")
157+
128158

129159
def pipeline_transforms(
130160
zarr_uri: str,
@@ -169,9 +199,12 @@ def pipeline_transforms(
169199
bucket,
170200
asset_pathlike / alignment_rel_path,
171201
)
202+
pipeline = _get_processing_pipeline_data(processing_data)
203+
pipeline_ver = int(pipeline["pipeline_version"].split(".")[0])
204+
transform_chain = _resolve_individual_transform_chain(pipeline_ver)
172205
individual_ants_paths = TemplatePaths(
173206
alignment_path,
174-
_PIPELINE_INDIVIDUAL_TRANSFORM_CHAINS[3],
207+
transform_chain,
175208
)
176209
if template_base:
177210
template_ants_paths = TemplatePaths(

src/aind_zarr_utils/pipeline_domain_selector.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@
2323
fix_corner_compute_origin as fix_corner_compute_origin,
2424
)
2525

26+
from aind_zarr_utils.domain.overlays import (
27+
_PIPELINE_MULTISCALE_FACTOR as _PIPELINE_MULTISCALE_FACTOR,
28+
)
2629
from aind_zarr_utils.domain.overlays import (
2730
FlipIndexAxesOverlay as FlipIndexAxesOverlay,
2831
)
@@ -44,9 +47,6 @@
4447
from aind_zarr_utils.domain.overlays import (
4548
Vec3 as Vec3,
4649
)
47-
from aind_zarr_utils.domain.overlays import (
48-
_PIPELINE_MULTISCALE_FACTOR as _PIPELINE_MULTISCALE_FACTOR,
49-
)
5050
from aind_zarr_utils.domain.overlays import (
5151
_require_cardinal as _require_cardinal,
5252
)

src/aind_zarr_utils/pipeline_transformed.py

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,35 @@
2121

2222
import numpy as np
2323
import SimpleITK as sitk
24-
from aind_anatomical_utils.anatomical_volume import (
25-
AnatomicalHeader,
26-
fix_corner_compute_origin,
27-
)
28-
from aind_anatomical_utils.coordinate_systems import _OPPOSITE_AXES
2924
from aind_registration_utils.ants import (
3025
apply_ants_transforms_to_point_arr,
3126
)
3227
from numpy.typing import NDArray
33-
from packaging.version import Version
3428

3529
from aind_zarr_utils.annotations import annotation_indices_to_anatomical
3630
from aind_zarr_utils.formats.swc import swc_data_to_indices
37-
from aind_zarr_utils.io.metadata import _unit_conversion as _unit_conversion # noqa: F401 # legacy re-export
31+
32+
# The implementations of _pipeline_anatomical_check_args,
33+
# _apply_pipeline_overlays_to_header, and _mimic_pipeline_anatomical_header
34+
# moved to ``aind_zarr_utils.image`` in commit C4. They are re-exported here
35+
# (along with _build_pipeline_header, the new name for the third) so existing
36+
# callers and test patches keep working.
37+
from aind_zarr_utils.image import (
38+
_apply_pipeline_overlays_to_header as _apply_pipeline_overlays_to_header,
39+
)
40+
from aind_zarr_utils.image import (
41+
_build_pipeline_header as _build_pipeline_header,
42+
)
43+
from aind_zarr_utils.image import (
44+
_build_pipeline_header as _mimic_pipeline_anatomical_header,
45+
)
46+
from aind_zarr_utils.image import (
47+
_pipeline_anatomical_check_args as _pipeline_anatomical_check_args,
48+
)
49+
from aind_zarr_utils.image import (
50+
apply_pipeline_overlays as apply_pipeline_overlays,
51+
)
52+
from aind_zarr_utils.io.metadata import _unit_conversion as _unit_conversion # legacy re-export
3853

3954
# Re-exported from io/* so existing test patches (and downstream imports)
4055
# continue to find these names at ``aind_zarr_utils.pipeline_transformed.*``.
@@ -105,14 +120,11 @@
105120
)
106121
from aind_zarr_utils.pipeline_domain_selector import (
107122
OverlaySelector,
108-
apply_overlays,
109-
estimate_pipeline_multiscale,
110123
get_selector,
111124
)
112125
from aind_zarr_utils.zarr import (
113126
zarr_to_ants,
114127
zarr_to_sitk,
115-
zarr_to_sitk_stub,
116128
)
117129

118130
if TYPE_CHECKING:
@@ -123,28 +135,6 @@
123135
T = TypeVar("T", int, float)
124136

125137

126-
# The implementations of _pipeline_anatomical_check_args,
127-
# _apply_pipeline_overlays_to_header, and _mimic_pipeline_anatomical_header
128-
# moved to ``aind_zarr_utils.image`` in commit C4. They are re-exported here
129-
# (along with _build_pipeline_header, the new name for the third) so existing
130-
# callers and test patches keep working.
131-
from aind_zarr_utils.image import (
132-
_apply_pipeline_overlays_to_header as _apply_pipeline_overlays_to_header,
133-
)
134-
from aind_zarr_utils.image import (
135-
_build_pipeline_header as _build_pipeline_header,
136-
)
137-
from aind_zarr_utils.image import (
138-
_build_pipeline_header as _mimic_pipeline_anatomical_header,
139-
)
140-
from aind_zarr_utils.image import (
141-
_pipeline_anatomical_check_args as _pipeline_anatomical_check_args,
142-
)
143-
from aind_zarr_utils.image import (
144-
apply_pipeline_overlays as apply_pipeline_overlays,
145-
)
146-
147-
148138
def base_and_pipeline_anatomical_stub(
149139
zarr_uri: str,
150140
metadata: dict,

tests/conftest.py

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -243,19 +243,13 @@ def mock_overlay_selector(monkeypatch):
243243
def mock_apply_overlays(header, overlays, meta, multiscale_no, **_kwargs):
244244
return header, [] # Return header unchanged with no applied overlays
245245

246-
# ``apply_overlays`` is referenced from three modules now: the canonical
247-
# home (``aind_zarr_utils.domain.selector``), the legacy
248-
# ``aind_zarr_utils.pipeline_transformed`` re-export (kept for tests
249-
# that patch the old path), and ``aind_zarr_utils.image`` where the
250-
# actual call sites in the C4 dispatcher live. Patch all three.
246+
# ``apply_overlays`` lives at ``aind_zarr_utils.domain.selector`` (the
247+
# canonical home) and is called from ``aind_zarr_utils.image`` where the
248+
# C4 dispatcher routes through it. Patch both.
251249
monkeypatch.setattr(
252250
"aind_zarr_utils.domain.selector.apply_overlays",
253251
mock_apply_overlays,
254252
)
255-
monkeypatch.setattr(
256-
"aind_zarr_utils.pipeline_transformed.apply_overlays",
257-
mock_apply_overlays,
258-
)
259253
monkeypatch.setattr(
260254
"aind_zarr_utils.image.apply_overlays",
261255
mock_apply_overlays,

tests/test_asset.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
from aind_zarr_utils.asset import Asset, TransformPaths
1111
from aind_zarr_utils.origin import Origin
1212

13-
1413
# ---------------------------------------------------------------- Origin ---
1514

1615

tests/test_points.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
transform_points,
2626
)
2727

28-
2928
# ----------------------------------------------------------- construction ---
3029

3130

@@ -450,9 +449,8 @@ def test_neuroglancer_to_ccf_numerical_equivalence_new_vs_legacy(
450449
(via ``mock_ants_transforms``) so the result is deterministic and the
451450
test does not depend on the registration files being available.
452451
"""
453-
from tests.conftest import create_comprehensive_processing_data
454-
455452
from aind_zarr_utils.pipeline_transformed import neuroglancer_to_ccf
453+
from tests.conftest import create_comprehensive_processing_data
456454

457455
processing = create_comprehensive_processing_data()
458456

0 commit comments

Comments
 (0)