Source code for aind_zarr_utils.annotations

"""Module for working with points in ZARR files."""

from __future__ import annotations

import re

import SimpleITK
from aind_anatomical_utils.sitk_volume import (
    transform_sitk_indices_to_physical_points,
)
from numpy.typing import NDArray


[docs] def annotation_indices_to_anatomical(img: SimpleITK.Image, annotations: dict[str, NDArray]) -> dict[str, NDArray]: """Transform annotation indices from image space to anatomical space. Parameters ---------- img : SimpleITK.Image The reference image. annotations : dict Dictionary where keys are annotation names and values are numpy arrays of indices. Indices can be continuous (floating-point) values representing sub-voxel positions, or integer voxel coordinates. Returns ------- anatomical_points : dict Dictionary where keys are annotation names and values are anatomical points (in LPS coordinate system). """ anatomical_points = {} for annotation, indices in annotations.items(): indices_sitk = indices[:, ::-1] # numpy to sitk indexing anatomical_points[annotation] = transform_sitk_indices_to_physical_points( img, indices_sitk, ) return anatomical_points
[docs] def annotations_and_descriptions_to_dict( annotation_points: dict[str, list[list[float]]], descriptions: dict[str, list[str | None]], ) -> dict[str, dict[str, list[float]]]: """Convert annotation points and descriptions into a description-to-point dictionary. Parameters ---------- annotation_points : dict Dictionary where keys are annotation names and values are lists of points. descriptions : dict Dictionary where keys are annotation names and values are lists of descriptions. Returns ------- dict Dictionary where keys are annotation names and values are point dictionaries. """ pt_dicts = {} for annotation_name, points in annotation_points.items(): description_list = descriptions[annotation_name] pt_dict = _pts_and_descriptions_to_pt_dict(points, description_list) pt_dicts[annotation_name] = pt_dict return pt_dicts
def _pts_and_descriptions_to_pt_dict( points: list[list[float]], description_list: list[str | None] ) -> dict[str, list[float]]: """Convert points and their descriptions into a dictionary. Parameters ---------- points : list of list List of points, where each point is a list of coordinates. description_list : list of str or None List of descriptions corresponding to the points. If None, numeric labels are assigned. Returns ------- dict Dictionary where keys are descriptions and values are points. """ pt_dict = {} j = 1 for i, point in enumerate(points): pt_description = description_list[i] if pt_description is None: pt_description_sanitized = f"{j}" j += 1 else: pt_description_sanitized = re.sub(r"[\r\n,]+", "", pt_description.strip()) pt_dict[pt_description_sanitized] = point return pt_dict