Skip to content

Commit a182b68

Browse files
galenlynchclaude
andcommitted
fix(pipeline_transformed): warn on unknown pipeline versions instead of erroring
Adds pipeline major version 5 to the known-good set (verified to behave identically to v4 — RAS corner anchor bug still present). For versions newer than known, emits a warning and falls back to the latest registered transform chain rather than raising. Older-than-supported versions still raise. Also fixes pipeline_transforms() which previously hardcoded the v3 chain regardless of the actual processing pipeline version. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent e22e96b commit a182b68

1 file changed

Lines changed: 52 additions & 5 deletions

File tree

src/aind_zarr_utils/pipeline_transformed.py

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
from __future__ import annotations
1717

18+
import logging
1819
import os
1920
from dataclasses import dataclass
2021
from pathlib import PurePath, PurePosixPath
@@ -63,7 +64,10 @@
6364
from mypy_boto3_s3 import S3Client
6465
from ome_zarr.reader import Node # type: ignore[import-untyped]
6566

67+
logger = logging.getLogger(__name__)
68+
6669
T = TypeVar("T", int, float)
70+
_KNOWN_GOOD_PIPELINE_VERSIONS = {3, 4, 5}
6771

6872

6973
@dataclass(slots=True, frozen=True)
@@ -227,7 +231,7 @@ def _zarr_base_name_any(base: str) -> str | None:
227231
)
228232
}
229233

230-
_PIPELINE_INDIVIDUAL_TRANSFORM_CHAINS: dict[int, TransformChain] = {
234+
_KNOWN_INDIVIDUAL_TRANSFORM_CHAINS: dict[int, TransformChain] = {
231235
3: TransformChain(
232236
fixed="template",
233237
moving="individual",
@@ -244,6 +248,34 @@ def _zarr_base_name_any(base: str) -> str | None:
244248
)
245249
}
246250

251+
_PIPELINE_INDIVIDUAL_TRANSFORM_CHAINS: dict[int, TransformChain] = {
252+
3: _KNOWN_INDIVIDUAL_TRANSFORM_CHAINS[3],
253+
4: _KNOWN_INDIVIDUAL_TRANSFORM_CHAINS[3],
254+
5: _KNOWN_INDIVIDUAL_TRANSFORM_CHAINS[3],
255+
}
256+
257+
258+
def _resolve_individual_transform_chain(
259+
pipeline_ver: int,
260+
) -> TransformChain:
261+
"""Look up the individual (LS → template) transform chain for a pipeline major version.
262+
263+
Falls back to the latest known chain when the version is newer than
264+
anything registered.
265+
"""
266+
chain = _PIPELINE_INDIVIDUAL_TRANSFORM_CHAINS.get(pipeline_ver)
267+
if chain is not None:
268+
return chain
269+
max_known = max(_PIPELINE_INDIVIDUAL_TRANSFORM_CHAINS)
270+
if pipeline_ver > max_known:
271+
logger.warning(
272+
f"No individual transform chain registered for pipeline "
273+
f"version {pipeline_ver}; falling back to chain for version "
274+
f"{max_known}. Results may not be accurate."
275+
)
276+
return _PIPELINE_INDIVIDUAL_TRANSFORM_CHAINS[max_known]
277+
raise ValueError(f"No individual transform chain registered for pipeline version {pipeline_ver}")
278+
247279

248280
def _get_processing_pipeline_data(
249281
processing_data: dict[str, Any],
@@ -265,14 +297,25 @@ def _get_processing_pipeline_data(
265297
Raises
266298
------
267299
ValueError
268-
If the pipeline version is missing or the major version is not 3.
300+
If the pipeline version is missing or the major version is older
301+
than the minimum supported version. Newer-than-known versions emit
302+
a warning instead of raising.
269303
"""
270304
ver_str = processing_data.get("processing_pipeline", {}).get("pipeline_version", None)
271305
if not ver_str:
272306
raise ValueError("Missing pipeline version")
273307
pipeline_ver = int(ver_str.split(".")[0])
274-
if pipeline_ver not in set((3, 4)):
275-
raise ValueError(f"Unsupported pipeline version: {pipeline_ver}")
308+
if pipeline_ver not in _KNOWN_GOOD_PIPELINE_VERSIONS:
309+
maxver = max(_KNOWN_GOOD_PIPELINE_VERSIONS)
310+
if pipeline_ver > maxver:
311+
logger.warning(
312+
f"Pipeline version {pipeline_ver} is greater than max "
313+
f"verified version {maxver}, results may not be accurate. "
314+
"File an issue at "
315+
"https://github.com/AllenNeuralDynamics/aind-zarr-utils/issues."
316+
)
317+
else:
318+
raise ValueError(f"Unsupported pipeline version: {pipeline_ver}")
276319
pipeline: dict[str, Any] = processing_data.get("processing_pipeline", {})
277320
return pipeline
278321

@@ -1175,9 +1218,13 @@ def pipeline_transforms(
11751218
bucket,
11761219
asset_pathlike / alignment_rel_path,
11771220
)
1221+
pipeline = _get_processing_pipeline_data(processing_data)
1222+
pipeline_ver = int(pipeline["pipeline_version"].split(".")[0])
1223+
transform_chain = _resolve_individual_transform_chain(pipeline_ver)
1224+
11781225
individual_ants_paths = TemplatePaths(
11791226
alignment_path,
1180-
_PIPELINE_INDIVIDUAL_TRANSFORM_CHAINS[3],
1227+
transform_chain,
11811228
)
11821229
if template_base:
11831230
template_ants_paths = TemplatePaths(

0 commit comments

Comments
 (0)