Skip to content

Iterators API reference

ImageProcessingIterator

ngio.iterators.ImageProcessingIterator

ImageProcessingIterator(
    input_image: Image,
    output_image: Image,
    input_channel_selection: ChannelSlicingInputType = None,
    output_channel_selection: ChannelSlicingInputType = None,
    axes_order: Sequence[str] | None = None,
    input_transforms: Sequence[TransformProtocol]
    | None = None,
    output_transforms: Sequence[TransformProtocol]
    | None = None,
)

Bases: AbstractIteratorBuilder[ndarray, Array]

Base class for iterators over ROIs.

Initialize the iterator with a ROI table and input/output images.

Parameters:

  • input_image (Image) –

    The input image to be used as input for the segmentation.

  • output_image (Image) –

    The image where the ROIs will be written.

  • input_channel_selection (ChannelSlicingInputType, default: None ) –

    Optional selection of channels to use for the input image.

  • output_channel_selection (ChannelSlicingInputType, default: None ) –

    Optional selection of channels to use for the output image.

  • axes_order (Sequence[str] | None, default: None ) –

    Optional axes order for the segmentation.

  • input_transforms (Sequence[TransformProtocol] | None, default: None ) –

    Optional transforms to apply to the input image.

  • output_transforms (Sequence[TransformProtocol] | None, default: None ) –

    Optional transforms to apply to the output label.

Source code in src/ngio/iterators/_image_processing.py
def __init__(
    self,
    input_image: Image,
    output_image: Image,
    input_channel_selection: ChannelSlicingInputType = None,
    output_channel_selection: ChannelSlicingInputType = None,
    axes_order: Sequence[str] | None = None,
    input_transforms: Sequence[TransformProtocol] | None = None,
    output_transforms: Sequence[TransformProtocol] | None = None,
) -> None:
    """Initialize the iterator with a ROI table and input/output images.

    Args:
        input_image (Image): The input image to be used as input for the
            segmentation.
        output_image (Image): The image where the ROIs will be written.
        input_channel_selection (ChannelSlicingInputType): Optional
            selection of channels to use for the input image.
        output_channel_selection (ChannelSlicingInputType): Optional
            selection of channels to use for the output image.
        axes_order (Sequence[str] | None): Optional axes order for the
            segmentation.
        input_transforms (Sequence[TransformProtocol] | None): Optional
            transforms to apply to the input image.
        output_transforms (Sequence[TransformProtocol] | None): Optional
            transforms to apply to the output label.
    """
    self._input = input_image
    self._output = output_image
    self._ref_image = input_image
    self._rois = input_image.build_image_roi_table(name=None).rois()

    # Set iteration parameters
    self._input_slicing_kwargs = add_channel_selection_to_slicing_dict(
        image=self._input,
        channel_selection=input_channel_selection,
        slicing_dict={},
    )
    self._output_slicing_kwargs = add_channel_selection_to_slicing_dict(
        image=self._output,
        channel_selection=output_channel_selection,
        slicing_dict={},
    )
    self._input_channel_selection = input_channel_selection
    self._output_channel_selection = output_channel_selection
    self._axes_order = axes_order
    self._input_transforms = input_transforms
    self._output_transforms = output_transforms

    self._input.require_dimensions_match(self._output, allow_singleton=True)

rois property

rois: list[Roi]

Get the list of ROIs for the iterator.

ref_image property

ref_image: AbstractImage

Get the reference image for the iterator.

grid

grid(
    size_x: int | None = None,
    size_y: int | None = None,
    size_z: int | None = None,
    size_t: int | None = None,
    stride_x: int | None = None,
    stride_y: int | None = None,
    stride_z: int | None = None,
    stride_t: int | None = None,
    base_name: str = "",
) -> Self

Create a grid of ROIs based on the input image dimensions.

Source code in src/ngio/iterators/_abstract_iterator.py
def grid(
    self,
    size_x: int | None = None,
    size_y: int | None = None,
    size_z: int | None = None,
    size_t: int | None = None,
    stride_x: int | None = None,
    stride_y: int | None = None,
    stride_z: int | None = None,
    stride_t: int | None = None,
    base_name: str = "",
) -> Self:
    """Create a grid of ROIs based on the input image dimensions."""
    rois = grid(
        rois=self.rois,
        ref_image=self.ref_image,
        size_x=size_x,
        size_y=size_y,
        size_z=size_z,
        size_t=size_t,
        stride_x=stride_x,
        stride_y=stride_y,
        stride_z=stride_z,
        stride_t=stride_t,
        base_name=base_name,
    )
    return self._new_from_rois(rois)

by_yx

by_yx() -> Self

Return a new iterator that iterates over ROIs by YX coordinates.

Source code in src/ngio/iterators/_abstract_iterator.py
def by_yx(self) -> Self:
    """Return a new iterator that iterates over ROIs by YX coordinates."""
    rois = by_yx(self.rois, self.ref_image)
    return self._new_from_rois(rois)

by_zyx

by_zyx(strict: bool = True) -> Self

Return a new iterator that iterates over ROIs by ZYX coordinates.

Parameters:

  • strict (bool, default: True ) –

    If True, only iterate over ZYX if a Z axis is present and not of size 1.

Source code in src/ngio/iterators/_abstract_iterator.py
def by_zyx(self, strict: bool = True) -> Self:
    """Return a new iterator that iterates over ROIs by ZYX coordinates.

    Args:
        strict (bool): If True, only iterate over ZYX if a Z axis
            is present and not of size 1.

    """
    rois = by_zyx(self.rois, self.ref_image, strict=strict)
    return self._new_from_rois(rois)

by_chunks

by_chunks(overlap_xy: int = 0, overlap_z: int = 0) -> Self

Return a new iterator that iterates over ROIs by chunks.

Parameters:

  • overlap_xy (int, default: 0 ) –

    Overlap in XY dimensions.

  • overlap_z (int, default: 0 ) –

    Overlap in Z dimension.

Returns:

  • SegmentationIterator ( Self ) –

    A new iterator with chunked ROIs.

Source code in src/ngio/iterators/_abstract_iterator.py
def by_chunks(self, overlap_xy: int = 0, overlap_z: int = 0) -> Self:
    """Return a new iterator that iterates over ROIs by chunks.

    Args:
        overlap_xy (int): Overlap in XY dimensions.
        overlap_z (int): Overlap in Z dimension.

    Returns:
        SegmentationIterator: A new iterator with chunked ROIs.
    """
    rois = by_chunks(
        self.rois, self.ref_image, overlap_xy=overlap_xy, overlap_z=overlap_z
    )
    return self._new_from_rois(rois)

product

product(other: list[Roi] | GenericRoiTable) -> Self

Cartesian product of the current ROIs with an arbitrary list of ROIs.

Source code in src/ngio/iterators/_abstract_iterator.py
def product(self, other: list[Roi] | GenericRoiTable) -> Self:
    """Cartesian product of the current ROIs with an arbitrary list of ROIs."""
    if isinstance(other, GenericRoiTable):
        other = other.rois()
    rois = rois_product(self.rois, other)
    return self._new_from_rois(rois)

iter

iter(
    lazy: Literal[True],
    data_mode: Literal["numpy"],
    iterator_mode: Literal["readwrite"],
) -> Generator[
    tuple[
        DataGetterProtocol[NumpyPipeType],
        DataSetterProtocol[NumpyPipeType],
    ]
]
iter(
    lazy: Literal[True],
    data_mode: Literal["numpy"],
    iterator_mode: Literal["readonly"] = ...,
) -> Generator[DataGetterProtocol[NumpyPipeType]]
iter(
    lazy: Literal[True],
    data_mode: Literal["dask"],
    iterator_mode: Literal["readwrite"],
) -> Generator[
    tuple[
        DataGetterProtocol[DaskPipeType],
        DataSetterProtocol[DaskPipeType],
    ]
]
iter(
    lazy: Literal[True],
    data_mode: Literal["dask"],
    iterator_mode: Literal["readonly"] = ...,
) -> Generator[DataGetterProtocol[DaskPipeType]]
iter(
    lazy: Literal[False],
    data_mode: Literal["numpy"],
    iterator_mode: Literal["readwrite"],
) -> Generator[
    tuple[NumpyPipeType, DataSetterProtocol[NumpyPipeType]]
]
iter(
    lazy: Literal[False],
    data_mode: Literal["numpy"],
    iterator_mode: Literal["readonly"] = ...,
) -> Generator[NumpyPipeType]
iter(
    lazy: Literal[False],
    data_mode: Literal["dask"],
    iterator_mode: Literal["readwrite"],
) -> Generator[
    tuple[DaskPipeType, DataSetterProtocol[DaskPipeType]]
]
iter(
    lazy: Literal[False],
    data_mode: Literal["dask"],
    iterator_mode: Literal["readonly"] = ...,
) -> Generator[DaskPipeType]
iter(
    lazy: bool = False,
    data_mode: Literal["numpy", "dask"] = "dask",
    iterator_mode: Literal[
        "readwrite", "readonly"
    ] = "readwrite",
) -> Generator

Create an iterator over the pixels of the ROIs.

Source code in src/ngio/iterators/_abstract_iterator.py
def iter(
    self,
    lazy: bool = False,
    data_mode: Literal["numpy", "dask"] = "dask",
    iterator_mode: Literal["readwrite", "readonly"] = "readwrite",
) -> Generator:
    """Create an iterator over the pixels of the ROIs."""
    if data_mode == "numpy":
        getters = self._numpy_getters_generator()
        setters = self._numpy_setters_generator()
    elif data_mode == "dask":
        getters = self._dask_getters_generator()
        setters = self._dask_setters_generator()
    else:
        raise NgioValueError(f"Invalid mode: {data_mode}")

    if iterator_mode == "readonly":
        if lazy:
            return getters
        else:
            return (getter() for getter in getters)
    if lazy:
        return self._read_and_write_generator(getters, setters)
    else:
        gen = self._read_and_write_generator(getters, setters)
        return ((getter(), setter) for getter, setter in gen)

iter_as_numpy

iter_as_numpy()

Create an iterator over the pixels of the ROIs.

Source code in src/ngio/iterators/_abstract_iterator.py
def iter_as_numpy(
    self,
):
    """Create an iterator over the pixels of the ROIs."""
    return self.iter(lazy=False, data_mode="numpy", iterator_mode="readwrite")

iter_as_dask

iter_as_dask()

Create an iterator over the pixels of the ROIs.

Source code in src/ngio/iterators/_abstract_iterator.py
def iter_as_dask(
    self,
):
    """Create an iterator over the pixels of the ROIs."""
    return self.iter(lazy=False, data_mode="dask", iterator_mode="readwrite")

map_as_numpy

map_as_numpy(
    func: Callable[[NumpyPipeType], NumpyPipeType],
    mapper: MapperProtocol[NumpyPipeType] | None = None,
) -> None

Apply a transformation function to the ROI pixels.

Source code in src/ngio/iterators/_abstract_iterator.py
def map_as_numpy(
    self,
    func: Callable[[NumpyPipeType], NumpyPipeType],
    mapper: MapperProtocol[NumpyPipeType] | None = None,
) -> None:
    """Apply a transformation function to the ROI pixels."""
    if mapper is None:
        _mapper = BasicMapper[NumpyPipeType]()
    else:
        _mapper = mapper

    _mapper(
        func=func,
        getters=self._numpy_getters_generator(),
        setters=self._numpy_setters_generator(),
    )
    self.post_consolidate()

map_as_dask

map_as_dask(
    func: Callable[[DaskPipeType], DaskPipeType],
    mapper: MapperProtocol[DaskPipeType] | None = None,
) -> None

Apply a transformation function to the ROI pixels.

Source code in src/ngio/iterators/_abstract_iterator.py
def map_as_dask(
    self,
    func: Callable[[DaskPipeType], DaskPipeType],
    mapper: MapperProtocol[DaskPipeType] | None = None,
) -> None:
    """Apply a transformation function to the ROI pixels."""
    if mapper is None:
        _mapper = BasicMapper[DaskPipeType]()
    else:
        _mapper = mapper

    _mapper(
        func=func,
        getters=self._dask_getters_generator(),
        setters=self._dask_setters_generator(),
    )
    self.post_consolidate()

check_if_regions_overlap

check_if_regions_overlap() -> bool

Check if any of the ROIs overlap logically.

If two ROIs cover the same pixel, they are considered to overlap. This does not consider chunking or other storage details.

Returns:

  • bool ( bool ) –

    True if any ROIs overlap. False otherwise.

Source code in src/ngio/iterators/_abstract_iterator.py
def check_if_regions_overlap(self) -> bool:
    """Check if any of the ROIs overlap logically.

    If two ROIs cover the same pixel, they are considered to overlap.
    This does not consider chunking or other storage details.

    Returns:
        bool: True if any ROIs overlap. False otherwise.
    """
    if len(self.rois) < 2:
        # Less than 2 ROIs cannot overlap
        return False

    slicing_tuples = (
        g.slicing_ops.normalized_slicing_tuple
        for g in self._numpy_getters_generator()
    )
    x = check_if_regions_overlap(slicing_tuples)
    return x

require_no_regions_overlap

require_no_regions_overlap() -> None

Ensure that the Iterator's ROIs do not overlap.

Source code in src/ngio/iterators/_abstract_iterator.py
def require_no_regions_overlap(self) -> None:
    """Ensure that the Iterator's ROIs do not overlap."""
    if self.check_if_regions_overlap():
        raise NgioValueError("Some rois overlap.")

check_if_chunks_overlap

check_if_chunks_overlap() -> bool

Check if any of the ROIs overlap in terms of chunks.

If two ROIs cover the same chunk, they are considered to overlap in chunks. This does not consider pixel-level overlaps.

Returns:

  • bool ( bool ) –

    True if any ROIs overlap in chunks, False otherwise.

Source code in src/ngio/iterators/_abstract_iterator.py
def check_if_chunks_overlap(self) -> bool:
    """Check if any of the ROIs overlap in terms of chunks.

    If two ROIs cover the same chunk, they are considered to overlap in chunks.
    This does not consider pixel-level overlaps.

    Returns:
        bool: True if any ROIs overlap in chunks, False otherwise.
    """
    from ngio.io_pipes._ops_slices_utils import check_if_chunks_overlap

    if len(self.rois) < 2:
        # Less than 2 ROIs cannot overlap
        return False

    slicing_tuples = (
        g.slicing_ops.normalized_slicing_tuple
        for g in self._numpy_getters_generator()
    )
    shape = self.ref_image.shape
    chunks = self.ref_image.chunks
    return check_if_chunks_overlap(slicing_tuples, shape, chunks)

require_no_chunks_overlap

require_no_chunks_overlap() -> None

Ensure that the ROIs do not overlap in terms of chunks.

Source code in src/ngio/iterators/_abstract_iterator.py
def require_no_chunks_overlap(self) -> None:
    """Ensure that the ROIs do not overlap in terms of chunks."""
    if self.check_if_chunks_overlap():
        raise NgioValueError("Some rois overlap in chunks.")

get_init_kwargs

get_init_kwargs() -> dict

Return the initialization arguments for the iterator.

Source code in src/ngio/iterators/_image_processing.py
def get_init_kwargs(self) -> dict:
    """Return the initialization arguments for the iterator."""
    return {
        "input_image": self._input,
        "output_image": self._output,
        "input_channel_selection": self._input_channel_selection,
        "output_channel_selection": self._output_channel_selection,
        "axes_order": self._axes_order,
        "input_transforms": self._input_transforms,
        "output_transforms": self._output_transforms,
    }

build_numpy_getter

build_numpy_getter(roi: Roi) -> DataGetterProtocol[ndarray]
Source code in src/ngio/iterators/_image_processing.py
def build_numpy_getter(self, roi: Roi) -> DataGetterProtocol[np.ndarray]:
    return NumpyRoiGetter(
        zarr_array=self._input.zarr_array,
        dimensions=self._input.dimensions,
        roi=roi,
        axes_order=self._axes_order,
        transforms=self._input_transforms,
        slicing_dict=self._input_slicing_kwargs,
    )

build_numpy_setter

build_numpy_setter(roi: Roi) -> DataSetterProtocol[ndarray]
Source code in src/ngio/iterators/_image_processing.py
def build_numpy_setter(self, roi: Roi) -> DataSetterProtocol[np.ndarray]:
    return NumpyRoiSetter(
        zarr_array=self._output.zarr_array,
        dimensions=self._output.dimensions,
        roi=roi,
        axes_order=self._axes_order,
        transforms=self._output_transforms,
        slicing_dict=self._output_slicing_kwargs,
    )

build_dask_getter

build_dask_getter(roi: Roi) -> DataGetterProtocol[Array]
Source code in src/ngio/iterators/_image_processing.py
def build_dask_getter(self, roi: Roi) -> DataGetterProtocol[da.Array]:
    return DaskRoiGetter(
        zarr_array=self._input.zarr_array,
        dimensions=self._input.dimensions,
        roi=roi,
        axes_order=self._axes_order,
        transforms=self._input_transforms,
        slicing_dict=self._input_slicing_kwargs,
    )

build_dask_setter

build_dask_setter(roi: Roi) -> DataSetterProtocol[Array]
Source code in src/ngio/iterators/_image_processing.py
def build_dask_setter(self, roi: Roi) -> DataSetterProtocol[da.Array]:
    return DaskRoiSetter(
        zarr_array=self._output.zarr_array,
        dimensions=self._output.dimensions,
        roi=roi,
        axes_order=self._axes_order,
        transforms=self._output_transforms,
        slicing_dict=self._output_slicing_kwargs,
    )

post_consolidate

post_consolidate()
Source code in src/ngio/iterators/_image_processing.py
def post_consolidate(self):
    self._output.consolidate()

SegmentationIterator

ngio.iterators.SegmentationIterator

SegmentationIterator(
    input_image: Image,
    output_label: Label,
    channel_selection: ChannelSlicingInputType = None,
    axes_order: Sequence[str] | None = None,
    input_transforms: Sequence[TransformProtocol]
    | None = None,
    output_transforms: Sequence[TransformProtocol]
    | None = None,
)

Bases: AbstractIteratorBuilder[ndarray, Array]

Base class for iterators over ROIs.

Initialize the iterator with a ROI table and input/output images.

Parameters:

  • input_image (Image) –

    The input image to be used as input for the segmentation.

  • output_label (Label) –

    The label image where the ROIs will be written.

  • channel_selection (ChannelSlicingInputType, default: None ) –

    Optional selection of channels to use for the segmentation.

  • axes_order (Sequence[str] | None, default: None ) –

    Optional axes order for the segmentation.

  • input_transforms (Sequence[TransformProtocol] | None, default: None ) –

    Optional transforms to apply to the input image.

  • output_transforms (Sequence[TransformProtocol] | None, default: None ) –

    Optional transforms to apply to the output label.

Source code in src/ngio/iterators/_segmentation.py
def __init__(
    self,
    input_image: Image,
    output_label: Label,
    channel_selection: ChannelSlicingInputType = None,
    axes_order: Sequence[str] | None = None,
    input_transforms: Sequence[TransformProtocol] | None = None,
    output_transforms: Sequence[TransformProtocol] | None = None,
) -> None:
    """Initialize the iterator with a ROI table and input/output images.

    Args:
        input_image (Image): The input image to be used as input for the
            segmentation.
        output_label (Label): The label image where the ROIs will be written.
        channel_selection (ChannelSlicingInputType): Optional
            selection of channels to use for the segmentation.
        axes_order (Sequence[str] | None): Optional axes order for the
            segmentation.
        input_transforms (Sequence[TransformProtocol] | None): Optional
            transforms to apply to the input image.
        output_transforms (Sequence[TransformProtocol] | None): Optional
            transforms to apply to the output label.
    """
    self._input = input_image
    self._output = output_label
    self._ref_image = input_image
    self._rois = input_image.build_image_roi_table(name=None).rois()

    # Set iteration parameters
    self._input_slicing_kwargs = add_channel_selection_to_slicing_dict(
        image=self._input, channel_selection=channel_selection, slicing_dict={}
    )
    self._channel_selection = channel_selection
    self._axes_order = axes_order
    self._input_transforms = input_transforms
    self._output_transforms = output_transforms

    self._input.require_dimensions_match(self._output, allow_singleton=False)

rois property

rois: list[Roi]

Get the list of ROIs for the iterator.

ref_image property

ref_image: AbstractImage

Get the reference image for the iterator.

grid

grid(
    size_x: int | None = None,
    size_y: int | None = None,
    size_z: int | None = None,
    size_t: int | None = None,
    stride_x: int | None = None,
    stride_y: int | None = None,
    stride_z: int | None = None,
    stride_t: int | None = None,
    base_name: str = "",
) -> Self

Create a grid of ROIs based on the input image dimensions.

Source code in src/ngio/iterators/_abstract_iterator.py
def grid(
    self,
    size_x: int | None = None,
    size_y: int | None = None,
    size_z: int | None = None,
    size_t: int | None = None,
    stride_x: int | None = None,
    stride_y: int | None = None,
    stride_z: int | None = None,
    stride_t: int | None = None,
    base_name: str = "",
) -> Self:
    """Create a grid of ROIs based on the input image dimensions."""
    rois = grid(
        rois=self.rois,
        ref_image=self.ref_image,
        size_x=size_x,
        size_y=size_y,
        size_z=size_z,
        size_t=size_t,
        stride_x=stride_x,
        stride_y=stride_y,
        stride_z=stride_z,
        stride_t=stride_t,
        base_name=base_name,
    )
    return self._new_from_rois(rois)

by_yx

by_yx() -> Self

Return a new iterator that iterates over ROIs by YX coordinates.

Source code in src/ngio/iterators/_abstract_iterator.py
def by_yx(self) -> Self:
    """Return a new iterator that iterates over ROIs by YX coordinates."""
    rois = by_yx(self.rois, self.ref_image)
    return self._new_from_rois(rois)

by_zyx

by_zyx(strict: bool = True) -> Self

Return a new iterator that iterates over ROIs by ZYX coordinates.

Parameters:

  • strict (bool, default: True ) –

    If True, only iterate over ZYX if a Z axis is present and not of size 1.

Source code in src/ngio/iterators/_abstract_iterator.py
def by_zyx(self, strict: bool = True) -> Self:
    """Return a new iterator that iterates over ROIs by ZYX coordinates.

    Args:
        strict (bool): If True, only iterate over ZYX if a Z axis
            is present and not of size 1.

    """
    rois = by_zyx(self.rois, self.ref_image, strict=strict)
    return self._new_from_rois(rois)

by_chunks

by_chunks(overlap_xy: int = 0, overlap_z: int = 0) -> Self

Return a new iterator that iterates over ROIs by chunks.

Parameters:

  • overlap_xy (int, default: 0 ) –

    Overlap in XY dimensions.

  • overlap_z (int, default: 0 ) –

    Overlap in Z dimension.

Returns:

  • SegmentationIterator ( Self ) –

    A new iterator with chunked ROIs.

Source code in src/ngio/iterators/_abstract_iterator.py
def by_chunks(self, overlap_xy: int = 0, overlap_z: int = 0) -> Self:
    """Return a new iterator that iterates over ROIs by chunks.

    Args:
        overlap_xy (int): Overlap in XY dimensions.
        overlap_z (int): Overlap in Z dimension.

    Returns:
        SegmentationIterator: A new iterator with chunked ROIs.
    """
    rois = by_chunks(
        self.rois, self.ref_image, overlap_xy=overlap_xy, overlap_z=overlap_z
    )
    return self._new_from_rois(rois)

product

product(other: list[Roi] | GenericRoiTable) -> Self

Cartesian product of the current ROIs with an arbitrary list of ROIs.

Source code in src/ngio/iterators/_abstract_iterator.py
def product(self, other: list[Roi] | GenericRoiTable) -> Self:
    """Cartesian product of the current ROIs with an arbitrary list of ROIs."""
    if isinstance(other, GenericRoiTable):
        other = other.rois()
    rois = rois_product(self.rois, other)
    return self._new_from_rois(rois)

iter

iter(
    lazy: Literal[True],
    data_mode: Literal["numpy"],
    iterator_mode: Literal["readwrite"],
) -> Generator[
    tuple[
        DataGetterProtocol[NumpyPipeType],
        DataSetterProtocol[NumpyPipeType],
    ]
]
iter(
    lazy: Literal[True],
    data_mode: Literal["numpy"],
    iterator_mode: Literal["readonly"] = ...,
) -> Generator[DataGetterProtocol[NumpyPipeType]]
iter(
    lazy: Literal[True],
    data_mode: Literal["dask"],
    iterator_mode: Literal["readwrite"],
) -> Generator[
    tuple[
        DataGetterProtocol[DaskPipeType],
        DataSetterProtocol[DaskPipeType],
    ]
]
iter(
    lazy: Literal[True],
    data_mode: Literal["dask"],
    iterator_mode: Literal["readonly"] = ...,
) -> Generator[DataGetterProtocol[DaskPipeType]]
iter(
    lazy: Literal[False],
    data_mode: Literal["numpy"],
    iterator_mode: Literal["readwrite"],
) -> Generator[
    tuple[NumpyPipeType, DataSetterProtocol[NumpyPipeType]]
]
iter(
    lazy: Literal[False],
    data_mode: Literal["numpy"],
    iterator_mode: Literal["readonly"] = ...,
) -> Generator[NumpyPipeType]
iter(
    lazy: Literal[False],
    data_mode: Literal["dask"],
    iterator_mode: Literal["readwrite"],
) -> Generator[
    tuple[DaskPipeType, DataSetterProtocol[DaskPipeType]]
]
iter(
    lazy: Literal[False],
    data_mode: Literal["dask"],
    iterator_mode: Literal["readonly"] = ...,
) -> Generator[DaskPipeType]
iter(
    lazy: bool = False,
    data_mode: Literal["numpy", "dask"] = "dask",
    iterator_mode: Literal[
        "readwrite", "readonly"
    ] = "readwrite",
) -> Generator

Create an iterator over the pixels of the ROIs.

Source code in src/ngio/iterators/_abstract_iterator.py
def iter(
    self,
    lazy: bool = False,
    data_mode: Literal["numpy", "dask"] = "dask",
    iterator_mode: Literal["readwrite", "readonly"] = "readwrite",
) -> Generator:
    """Create an iterator over the pixels of the ROIs."""
    if data_mode == "numpy":
        getters = self._numpy_getters_generator()
        setters = self._numpy_setters_generator()
    elif data_mode == "dask":
        getters = self._dask_getters_generator()
        setters = self._dask_setters_generator()
    else:
        raise NgioValueError(f"Invalid mode: {data_mode}")

    if iterator_mode == "readonly":
        if lazy:
            return getters
        else:
            return (getter() for getter in getters)
    if lazy:
        return self._read_and_write_generator(getters, setters)
    else:
        gen = self._read_and_write_generator(getters, setters)
        return ((getter(), setter) for getter, setter in gen)

iter_as_numpy

iter_as_numpy()

Create an iterator over the pixels of the ROIs.

Source code in src/ngio/iterators/_abstract_iterator.py
def iter_as_numpy(
    self,
):
    """Create an iterator over the pixels of the ROIs."""
    return self.iter(lazy=False, data_mode="numpy", iterator_mode="readwrite")

iter_as_dask

iter_as_dask()

Create an iterator over the pixels of the ROIs.

Source code in src/ngio/iterators/_abstract_iterator.py
def iter_as_dask(
    self,
):
    """Create an iterator over the pixels of the ROIs."""
    return self.iter(lazy=False, data_mode="dask", iterator_mode="readwrite")

map_as_numpy

map_as_numpy(
    func: Callable[[NumpyPipeType], NumpyPipeType],
    mapper: MapperProtocol[NumpyPipeType] | None = None,
) -> None

Apply a transformation function to the ROI pixels.

Source code in src/ngio/iterators/_abstract_iterator.py
def map_as_numpy(
    self,
    func: Callable[[NumpyPipeType], NumpyPipeType],
    mapper: MapperProtocol[NumpyPipeType] | None = None,
) -> None:
    """Apply a transformation function to the ROI pixels."""
    if mapper is None:
        _mapper = BasicMapper[NumpyPipeType]()
    else:
        _mapper = mapper

    _mapper(
        func=func,
        getters=self._numpy_getters_generator(),
        setters=self._numpy_setters_generator(),
    )
    self.post_consolidate()

map_as_dask

map_as_dask(
    func: Callable[[DaskPipeType], DaskPipeType],
    mapper: MapperProtocol[DaskPipeType] | None = None,
) -> None

Apply a transformation function to the ROI pixels.

Source code in src/ngio/iterators/_abstract_iterator.py
def map_as_dask(
    self,
    func: Callable[[DaskPipeType], DaskPipeType],
    mapper: MapperProtocol[DaskPipeType] | None = None,
) -> None:
    """Apply a transformation function to the ROI pixels."""
    if mapper is None:
        _mapper = BasicMapper[DaskPipeType]()
    else:
        _mapper = mapper

    _mapper(
        func=func,
        getters=self._dask_getters_generator(),
        setters=self._dask_setters_generator(),
    )
    self.post_consolidate()

check_if_regions_overlap

check_if_regions_overlap() -> bool

Check if any of the ROIs overlap logically.

If two ROIs cover the same pixel, they are considered to overlap. This does not consider chunking or other storage details.

Returns:

  • bool ( bool ) –

    True if any ROIs overlap. False otherwise.

Source code in src/ngio/iterators/_abstract_iterator.py
def check_if_regions_overlap(self) -> bool:
    """Check if any of the ROIs overlap logically.

    If two ROIs cover the same pixel, they are considered to overlap.
    This does not consider chunking or other storage details.

    Returns:
        bool: True if any ROIs overlap. False otherwise.
    """
    if len(self.rois) < 2:
        # Less than 2 ROIs cannot overlap
        return False

    slicing_tuples = (
        g.slicing_ops.normalized_slicing_tuple
        for g in self._numpy_getters_generator()
    )
    x = check_if_regions_overlap(slicing_tuples)
    return x

require_no_regions_overlap

require_no_regions_overlap() -> None

Ensure that the Iterator's ROIs do not overlap.

Source code in src/ngio/iterators/_abstract_iterator.py
def require_no_regions_overlap(self) -> None:
    """Ensure that the Iterator's ROIs do not overlap."""
    if self.check_if_regions_overlap():
        raise NgioValueError("Some rois overlap.")

check_if_chunks_overlap

check_if_chunks_overlap() -> bool

Check if any of the ROIs overlap in terms of chunks.

If two ROIs cover the same chunk, they are considered to overlap in chunks. This does not consider pixel-level overlaps.

Returns:

  • bool ( bool ) –

    True if any ROIs overlap in chunks, False otherwise.

Source code in src/ngio/iterators/_abstract_iterator.py
def check_if_chunks_overlap(self) -> bool:
    """Check if any of the ROIs overlap in terms of chunks.

    If two ROIs cover the same chunk, they are considered to overlap in chunks.
    This does not consider pixel-level overlaps.

    Returns:
        bool: True if any ROIs overlap in chunks, False otherwise.
    """
    from ngio.io_pipes._ops_slices_utils import check_if_chunks_overlap

    if len(self.rois) < 2:
        # Less than 2 ROIs cannot overlap
        return False

    slicing_tuples = (
        g.slicing_ops.normalized_slicing_tuple
        for g in self._numpy_getters_generator()
    )
    shape = self.ref_image.shape
    chunks = self.ref_image.chunks
    return check_if_chunks_overlap(slicing_tuples, shape, chunks)

require_no_chunks_overlap

require_no_chunks_overlap() -> None

Ensure that the ROIs do not overlap in terms of chunks.

Source code in src/ngio/iterators/_abstract_iterator.py
def require_no_chunks_overlap(self) -> None:
    """Ensure that the ROIs do not overlap in terms of chunks."""
    if self.check_if_chunks_overlap():
        raise NgioValueError("Some rois overlap in chunks.")

get_init_kwargs

get_init_kwargs() -> dict

Return the initialization arguments for the iterator.

Source code in src/ngio/iterators/_segmentation.py
def get_init_kwargs(self) -> dict:
    """Return the initialization arguments for the iterator."""
    return {
        "input_image": self._input,
        "output_label": self._output,
        "channel_selection": self._channel_selection,
        "axes_order": self._axes_order,
        "input_transforms": self._input_transforms,
        "output_transforms": self._output_transforms,
    }

build_numpy_getter

build_numpy_getter(roi: Roi) -> DataGetterProtocol[ndarray]
Source code in src/ngio/iterators/_segmentation.py
def build_numpy_getter(self, roi: Roi) -> DataGetterProtocol[np.ndarray]:
    return NumpyRoiGetter(
        zarr_array=self._input.zarr_array,
        dimensions=self._input.dimensions,
        roi=roi,
        axes_order=self._axes_order,
        transforms=self._input_transforms,
        slicing_dict=self._input_slicing_kwargs,
    )

build_numpy_setter

build_numpy_setter(roi: Roi) -> DataSetterProtocol[ndarray]
Source code in src/ngio/iterators/_segmentation.py
def build_numpy_setter(self, roi: Roi) -> DataSetterProtocol[np.ndarray]:
    return NumpyRoiSetter(
        zarr_array=self._output.zarr_array,
        dimensions=self._output.dimensions,
        roi=roi,
        axes_order=self._axes_order,
        transforms=self._output_transforms,
        remove_channel_selection=True,
    )

build_dask_getter

build_dask_getter(roi: Roi) -> DataGetterProtocol[Array]
Source code in src/ngio/iterators/_segmentation.py
def build_dask_getter(self, roi: Roi) -> DataGetterProtocol[da.Array]:
    return DaskRoiGetter(
        zarr_array=self._input.zarr_array,
        dimensions=self._input.dimensions,
        roi=roi,
        axes_order=self._axes_order,
        transforms=self._input_transforms,
        slicing_dict=self._input_slicing_kwargs,
    )

build_dask_setter

build_dask_setter(roi: Roi) -> DataSetterProtocol[Array]
Source code in src/ngio/iterators/_segmentation.py
def build_dask_setter(self, roi: Roi) -> DataSetterProtocol[da.Array]:
    return DaskRoiSetter(
        zarr_array=self._output.zarr_array,
        dimensions=self._output.dimensions,
        roi=roi,
        axes_order=self._axes_order,
        transforms=self._output_transforms,
        remove_channel_selection=True,
    )

post_consolidate

post_consolidate()
Source code in src/ngio/iterators/_segmentation.py
def post_consolidate(self):
    self._output.consolidate()

MaskedSegmentationIterator

ngio.iterators.MaskedSegmentationIterator

MaskedSegmentationIterator(
    input_image: MaskedImage,
    output_label: Label,
    channel_selection: ChannelSlicingInputType = None,
    axes_order: Sequence[str] | None = None,
    input_transforms: Sequence[TransformProtocol]
    | None = None,
    output_transforms: Sequence[TransformProtocol]
    | None = None,
)

Bases: SegmentationIterator

Base class for iterators over ROIs.

Initialize the iterator with a ROI table and input/output images.

Parameters:

  • input_image (MaskedImage) –

    The input image to be used as input for the segmentation.

  • output_label (Label) –

    The label image where the ROIs will be written.

  • channel_selection (ChannelSlicingInputType, default: None ) –

    Optional selection of channels to use for the segmentation.

  • axes_order (Sequence[str] | None, default: None ) –

    Optional axes order for the segmentation.

  • input_transforms (Sequence[TransformProtocol] | None, default: None ) –

    Optional transforms to apply to the input image.

  • output_transforms (Sequence[TransformProtocol] | None, default: None ) –

    Optional transforms to apply to the output label.

Source code in src/ngio/iterators/_segmentation.py
def __init__(
    self,
    input_image: MaskedImage,
    output_label: Label,
    channel_selection: ChannelSlicingInputType = None,
    axes_order: Sequence[str] | None = None,
    input_transforms: Sequence[TransformProtocol] | None = None,
    output_transforms: Sequence[TransformProtocol] | None = None,
) -> None:
    """Initialize the iterator with a ROI table and input/output images.

    Args:
        input_image (MaskedImage): The input image to be used as input for the
            segmentation.
        output_label (Label): The label image where the ROIs will be written.
        channel_selection (ChannelSlicingInputType): Optional
            selection of channels to use for the segmentation.
        axes_order (Sequence[str] | None): Optional axes order for the
            segmentation.
        input_transforms (Sequence[TransformProtocol] | None): Optional
            transforms to apply to the input image.
        output_transforms (Sequence[TransformProtocol] | None): Optional
            transforms to apply to the output label.
    """
    self._input = input_image
    self._output = output_label

    self._ref_image = input_image
    self._set_rois(input_image._masking_roi_table.rois())

    # Set iteration parameters
    self._input_slicing_kwargs = add_channel_selection_to_slicing_dict(
        image=self._input, channel_selection=channel_selection, slicing_dict={}
    )
    self._channel_selection = channel_selection
    self._axes_order = axes_order
    self._input_transforms = input_transforms
    self._output_transforms = output_transforms

rois property

rois: list[Roi]

Get the list of ROIs for the iterator.

ref_image property

ref_image: AbstractImage

Get the reference image for the iterator.

grid

grid(
    size_x: int | None = None,
    size_y: int | None = None,
    size_z: int | None = None,
    size_t: int | None = None,
    stride_x: int | None = None,
    stride_y: int | None = None,
    stride_z: int | None = None,
    stride_t: int | None = None,
    base_name: str = "",
) -> Self

Create a grid of ROIs based on the input image dimensions.

Source code in src/ngio/iterators/_abstract_iterator.py
def grid(
    self,
    size_x: int | None = None,
    size_y: int | None = None,
    size_z: int | None = None,
    size_t: int | None = None,
    stride_x: int | None = None,
    stride_y: int | None = None,
    stride_z: int | None = None,
    stride_t: int | None = None,
    base_name: str = "",
) -> Self:
    """Create a grid of ROIs based on the input image dimensions."""
    rois = grid(
        rois=self.rois,
        ref_image=self.ref_image,
        size_x=size_x,
        size_y=size_y,
        size_z=size_z,
        size_t=size_t,
        stride_x=stride_x,
        stride_y=stride_y,
        stride_z=stride_z,
        stride_t=stride_t,
        base_name=base_name,
    )
    return self._new_from_rois(rois)

by_yx

by_yx() -> Self

Return a new iterator that iterates over ROIs by YX coordinates.

Source code in src/ngio/iterators/_abstract_iterator.py
def by_yx(self) -> Self:
    """Return a new iterator that iterates over ROIs by YX coordinates."""
    rois = by_yx(self.rois, self.ref_image)
    return self._new_from_rois(rois)

by_zyx

by_zyx(strict: bool = True) -> Self

Return a new iterator that iterates over ROIs by ZYX coordinates.

Parameters:

  • strict (bool, default: True ) –

    If True, only iterate over ZYX if a Z axis is present and not of size 1.

Source code in src/ngio/iterators/_abstract_iterator.py
def by_zyx(self, strict: bool = True) -> Self:
    """Return a new iterator that iterates over ROIs by ZYX coordinates.

    Args:
        strict (bool): If True, only iterate over ZYX if a Z axis
            is present and not of size 1.

    """
    rois = by_zyx(self.rois, self.ref_image, strict=strict)
    return self._new_from_rois(rois)

by_chunks

by_chunks(overlap_xy: int = 0, overlap_z: int = 0) -> Self

Return a new iterator that iterates over ROIs by chunks.

Parameters:

  • overlap_xy (int, default: 0 ) –

    Overlap in XY dimensions.

  • overlap_z (int, default: 0 ) –

    Overlap in Z dimension.

Returns:

  • SegmentationIterator ( Self ) –

    A new iterator with chunked ROIs.

Source code in src/ngio/iterators/_abstract_iterator.py
def by_chunks(self, overlap_xy: int = 0, overlap_z: int = 0) -> Self:
    """Return a new iterator that iterates over ROIs by chunks.

    Args:
        overlap_xy (int): Overlap in XY dimensions.
        overlap_z (int): Overlap in Z dimension.

    Returns:
        SegmentationIterator: A new iterator with chunked ROIs.
    """
    rois = by_chunks(
        self.rois, self.ref_image, overlap_xy=overlap_xy, overlap_z=overlap_z
    )
    return self._new_from_rois(rois)

product

product(other: list[Roi] | GenericRoiTable) -> Self

Cartesian product of the current ROIs with an arbitrary list of ROIs.

Source code in src/ngio/iterators/_abstract_iterator.py
def product(self, other: list[Roi] | GenericRoiTable) -> Self:
    """Cartesian product of the current ROIs with an arbitrary list of ROIs."""
    if isinstance(other, GenericRoiTable):
        other = other.rois()
    rois = rois_product(self.rois, other)
    return self._new_from_rois(rois)

iter

iter(
    lazy: Literal[True],
    data_mode: Literal["numpy"],
    iterator_mode: Literal["readwrite"],
) -> Generator[
    tuple[
        DataGetterProtocol[NumpyPipeType],
        DataSetterProtocol[NumpyPipeType],
    ]
]
iter(
    lazy: Literal[True],
    data_mode: Literal["numpy"],
    iterator_mode: Literal["readonly"] = ...,
) -> Generator[DataGetterProtocol[NumpyPipeType]]
iter(
    lazy: Literal[True],
    data_mode: Literal["dask"],
    iterator_mode: Literal["readwrite"],
) -> Generator[
    tuple[
        DataGetterProtocol[DaskPipeType],
        DataSetterProtocol[DaskPipeType],
    ]
]
iter(
    lazy: Literal[True],
    data_mode: Literal["dask"],
    iterator_mode: Literal["readonly"] = ...,
) -> Generator[DataGetterProtocol[DaskPipeType]]
iter(
    lazy: Literal[False],
    data_mode: Literal["numpy"],
    iterator_mode: Literal["readwrite"],
) -> Generator[
    tuple[NumpyPipeType, DataSetterProtocol[NumpyPipeType]]
]
iter(
    lazy: Literal[False],
    data_mode: Literal["numpy"],
    iterator_mode: Literal["readonly"] = ...,
) -> Generator[NumpyPipeType]
iter(
    lazy: Literal[False],
    data_mode: Literal["dask"],
    iterator_mode: Literal["readwrite"],
) -> Generator[
    tuple[DaskPipeType, DataSetterProtocol[DaskPipeType]]
]
iter(
    lazy: Literal[False],
    data_mode: Literal["dask"],
    iterator_mode: Literal["readonly"] = ...,
) -> Generator[DaskPipeType]
iter(
    lazy: bool = False,
    data_mode: Literal["numpy", "dask"] = "dask",
    iterator_mode: Literal[
        "readwrite", "readonly"
    ] = "readwrite",
) -> Generator

Create an iterator over the pixels of the ROIs.

Source code in src/ngio/iterators/_abstract_iterator.py
def iter(
    self,
    lazy: bool = False,
    data_mode: Literal["numpy", "dask"] = "dask",
    iterator_mode: Literal["readwrite", "readonly"] = "readwrite",
) -> Generator:
    """Create an iterator over the pixels of the ROIs."""
    if data_mode == "numpy":
        getters = self._numpy_getters_generator()
        setters = self._numpy_setters_generator()
    elif data_mode == "dask":
        getters = self._dask_getters_generator()
        setters = self._dask_setters_generator()
    else:
        raise NgioValueError(f"Invalid mode: {data_mode}")

    if iterator_mode == "readonly":
        if lazy:
            return getters
        else:
            return (getter() for getter in getters)
    if lazy:
        return self._read_and_write_generator(getters, setters)
    else:
        gen = self._read_and_write_generator(getters, setters)
        return ((getter(), setter) for getter, setter in gen)

iter_as_numpy

iter_as_numpy()

Create an iterator over the pixels of the ROIs.

Source code in src/ngio/iterators/_abstract_iterator.py
def iter_as_numpy(
    self,
):
    """Create an iterator over the pixels of the ROIs."""
    return self.iter(lazy=False, data_mode="numpy", iterator_mode="readwrite")

iter_as_dask

iter_as_dask()

Create an iterator over the pixels of the ROIs.

Source code in src/ngio/iterators/_abstract_iterator.py
def iter_as_dask(
    self,
):
    """Create an iterator over the pixels of the ROIs."""
    return self.iter(lazy=False, data_mode="dask", iterator_mode="readwrite")

map_as_numpy

map_as_numpy(
    func: Callable[[NumpyPipeType], NumpyPipeType],
    mapper: MapperProtocol[NumpyPipeType] | None = None,
) -> None

Apply a transformation function to the ROI pixels.

Source code in src/ngio/iterators/_abstract_iterator.py
def map_as_numpy(
    self,
    func: Callable[[NumpyPipeType], NumpyPipeType],
    mapper: MapperProtocol[NumpyPipeType] | None = None,
) -> None:
    """Apply a transformation function to the ROI pixels."""
    if mapper is None:
        _mapper = BasicMapper[NumpyPipeType]()
    else:
        _mapper = mapper

    _mapper(
        func=func,
        getters=self._numpy_getters_generator(),
        setters=self._numpy_setters_generator(),
    )
    self.post_consolidate()

map_as_dask

map_as_dask(
    func: Callable[[DaskPipeType], DaskPipeType],
    mapper: MapperProtocol[DaskPipeType] | None = None,
) -> None

Apply a transformation function to the ROI pixels.

Source code in src/ngio/iterators/_abstract_iterator.py
def map_as_dask(
    self,
    func: Callable[[DaskPipeType], DaskPipeType],
    mapper: MapperProtocol[DaskPipeType] | None = None,
) -> None:
    """Apply a transformation function to the ROI pixels."""
    if mapper is None:
        _mapper = BasicMapper[DaskPipeType]()
    else:
        _mapper = mapper

    _mapper(
        func=func,
        getters=self._dask_getters_generator(),
        setters=self._dask_setters_generator(),
    )
    self.post_consolidate()

check_if_regions_overlap

check_if_regions_overlap() -> bool

Check if any of the ROIs overlap logically.

If two ROIs cover the same pixel, they are considered to overlap. This does not consider chunking or other storage details.

Returns:

  • bool ( bool ) –

    True if any ROIs overlap. False otherwise.

Source code in src/ngio/iterators/_abstract_iterator.py
def check_if_regions_overlap(self) -> bool:
    """Check if any of the ROIs overlap logically.

    If two ROIs cover the same pixel, they are considered to overlap.
    This does not consider chunking or other storage details.

    Returns:
        bool: True if any ROIs overlap. False otherwise.
    """
    if len(self.rois) < 2:
        # Less than 2 ROIs cannot overlap
        return False

    slicing_tuples = (
        g.slicing_ops.normalized_slicing_tuple
        for g in self._numpy_getters_generator()
    )
    x = check_if_regions_overlap(slicing_tuples)
    return x

require_no_regions_overlap

require_no_regions_overlap() -> None

Ensure that the Iterator's ROIs do not overlap.

Source code in src/ngio/iterators/_abstract_iterator.py
def require_no_regions_overlap(self) -> None:
    """Ensure that the Iterator's ROIs do not overlap."""
    if self.check_if_regions_overlap():
        raise NgioValueError("Some rois overlap.")

check_if_chunks_overlap

check_if_chunks_overlap() -> bool

Check if any of the ROIs overlap in terms of chunks.

If two ROIs cover the same chunk, they are considered to overlap in chunks. This does not consider pixel-level overlaps.

Returns:

  • bool ( bool ) –

    True if any ROIs overlap in chunks, False otherwise.

Source code in src/ngio/iterators/_abstract_iterator.py
def check_if_chunks_overlap(self) -> bool:
    """Check if any of the ROIs overlap in terms of chunks.

    If two ROIs cover the same chunk, they are considered to overlap in chunks.
    This does not consider pixel-level overlaps.

    Returns:
        bool: True if any ROIs overlap in chunks, False otherwise.
    """
    from ngio.io_pipes._ops_slices_utils import check_if_chunks_overlap

    if len(self.rois) < 2:
        # Less than 2 ROIs cannot overlap
        return False

    slicing_tuples = (
        g.slicing_ops.normalized_slicing_tuple
        for g in self._numpy_getters_generator()
    )
    shape = self.ref_image.shape
    chunks = self.ref_image.chunks
    return check_if_chunks_overlap(slicing_tuples, shape, chunks)

require_no_chunks_overlap

require_no_chunks_overlap() -> None

Ensure that the ROIs do not overlap in terms of chunks.

Source code in src/ngio/iterators/_abstract_iterator.py
def require_no_chunks_overlap(self) -> None:
    """Ensure that the ROIs do not overlap in terms of chunks."""
    if self.check_if_chunks_overlap():
        raise NgioValueError("Some rois overlap in chunks.")

get_init_kwargs

get_init_kwargs() -> dict

Return the initialization arguments for the iterator.

Source code in src/ngio/iterators/_segmentation.py
def get_init_kwargs(self) -> dict:
    """Return the initialization arguments for the iterator."""
    return {
        "input_image": self._input,
        "output_label": self._output,
        "channel_selection": self._channel_selection,
        "axes_order": self._axes_order,
        "input_transforms": self._input_transforms,
        "output_transforms": self._output_transforms,
    }

build_numpy_getter

build_numpy_getter(roi: Roi)
Source code in src/ngio/iterators/_segmentation.py
def build_numpy_getter(self, roi: Roi):
    return NumpyGetterMasked(
        zarr_array=self._input.zarr_array,
        dimensions=self._input.dimensions,
        roi=roi,
        label_zarr_array=self._input._label.zarr_array,
        label_dimensions=self._input._label.dimensions,
        axes_order=self._axes_order,
        transforms=self._input_transforms,
        slicing_dict=self._input_slicing_kwargs,
    )

build_numpy_setter

build_numpy_setter(roi: Roi)
Source code in src/ngio/iterators/_segmentation.py
def build_numpy_setter(self, roi: Roi):
    return NumpySetterMasked(
        roi=roi,
        zarr_array=self._output.zarr_array,
        dimensions=self._output.dimensions,
        label_zarr_array=self._input._label.zarr_array,
        label_dimensions=self._input._label.dimensions,
        axes_order=self._axes_order,
        transforms=self._output_transforms,
        remove_channel_selection=True,
    )

build_dask_getter

build_dask_getter(roi: Roi)
Source code in src/ngio/iterators/_segmentation.py
def build_dask_getter(self, roi: Roi):
    return DaskGetterMasked(
        roi=roi,
        zarr_array=self._input.zarr_array,
        dimensions=self._input.dimensions,
        label_zarr_array=self._input._label.zarr_array,
        label_dimensions=self._input._label.dimensions,
        axes_order=self._axes_order,
        transforms=self._input_transforms,
        slicing_dict=self._input_slicing_kwargs,
    )

build_dask_setter

build_dask_setter(roi: Roi)
Source code in src/ngio/iterators/_segmentation.py
def build_dask_setter(self, roi: Roi):
    return DaskSetterMasked(
        roi=roi,
        zarr_array=self._output.zarr_array,
        dimensions=self._output.dimensions,
        label_zarr_array=self._input._label.zarr_array,
        label_dimensions=self._input._label.dimensions,
        axes_order=self._axes_order,
        transforms=self._output_transforms,
        remove_channel_selection=True,
    )

post_consolidate

post_consolidate()
Source code in src/ngio/iterators/_segmentation.py
def post_consolidate(self):
    self._output.consolidate()

FeatureExtractorIterator

ngio.iterators.FeatureExtractorIterator

FeatureExtractorIterator(
    input_image: Image,
    input_label: Label,
    channel_selection: ChannelSlicingInputType = None,
    axes_order: Sequence[str] | None = None,
    input_transforms: Sequence[TransformProtocol]
    | None = None,
    label_transforms: Sequence[TransformProtocol]
    | None = None,
)

Bases: AbstractIteratorBuilder[NumpyPipeType, DaskPipeType]

Base class for iterators over ROIs.

Initialize the iterator with a ROI table and input/output images.

Parameters:

  • input_image (Image) –

    The input image to be used as input for the segmentation.

  • input_label (Label) –

    The input label with the segmentation masks.

  • channel_selection (ChannelSlicingInputType, default: None ) –

    Optional selection of channels to use for the segmentation.

  • axes_order (Sequence[str] | None, default: None ) –

    Optional axes order for the segmentation.

  • input_transforms (Sequence[TransformProtocol] | None, default: None ) –

    Optional transforms to apply to the input image.

  • label_transforms (Sequence[TransformProtocol] | None, default: None ) –

    Optional transforms to apply to the output label.

Source code in src/ngio/iterators/_feature.py
def __init__(
    self,
    input_image: Image,
    input_label: Label,
    channel_selection: ChannelSlicingInputType = None,
    axes_order: Sequence[str] | None = None,
    input_transforms: Sequence[TransformProtocol] | None = None,
    label_transforms: Sequence[TransformProtocol] | None = None,
) -> None:
    """Initialize the iterator with a ROI table and input/output images.

    Args:
        input_image (Image): The input image to be used as input for the
            segmentation.
        input_label (Label): The input label with the segmentation masks.
        channel_selection (ChannelSlicingInputType): Optional
            selection of channels to use for the segmentation.
        axes_order (Sequence[str] | None): Optional axes order for the
            segmentation.
        input_transforms (Sequence[TransformProtocol] | None): Optional
            transforms to apply to the input image.
        label_transforms (Sequence[TransformProtocol] | None): Optional
            transforms to apply to the output label.
    """
    self._input = input_image
    self._input_label = input_label
    self._ref_image = input_image
    self._rois = input_image.build_image_roi_table(name=None).rois()

    # Set iteration parameters
    self._input_slicing_kwargs = add_channel_selection_to_slicing_dict(
        image=self._input, channel_selection=channel_selection, slicing_dict={}
    )
    self._channel_selection = channel_selection
    self._axes_order = axes_order
    self._input_transforms = input_transforms
    self._label_transforms = label_transforms

    self._input.require_axes_match(self._input_label)
    self._input.require_rescalable(self._input_label)

rois property

rois: list[Roi]

Get the list of ROIs for the iterator.

ref_image property

ref_image: AbstractImage

Get the reference image for the iterator.

grid

grid(
    size_x: int | None = None,
    size_y: int | None = None,
    size_z: int | None = None,
    size_t: int | None = None,
    stride_x: int | None = None,
    stride_y: int | None = None,
    stride_z: int | None = None,
    stride_t: int | None = None,
    base_name: str = "",
) -> Self

Create a grid of ROIs based on the input image dimensions.

Source code in src/ngio/iterators/_abstract_iterator.py
def grid(
    self,
    size_x: int | None = None,
    size_y: int | None = None,
    size_z: int | None = None,
    size_t: int | None = None,
    stride_x: int | None = None,
    stride_y: int | None = None,
    stride_z: int | None = None,
    stride_t: int | None = None,
    base_name: str = "",
) -> Self:
    """Create a grid of ROIs based on the input image dimensions."""
    rois = grid(
        rois=self.rois,
        ref_image=self.ref_image,
        size_x=size_x,
        size_y=size_y,
        size_z=size_z,
        size_t=size_t,
        stride_x=stride_x,
        stride_y=stride_y,
        stride_z=stride_z,
        stride_t=stride_t,
        base_name=base_name,
    )
    return self._new_from_rois(rois)

by_yx

by_yx() -> Self

Return a new iterator that iterates over ROIs by YX coordinates.

Source code in src/ngio/iterators/_abstract_iterator.py
def by_yx(self) -> Self:
    """Return a new iterator that iterates over ROIs by YX coordinates."""
    rois = by_yx(self.rois, self.ref_image)
    return self._new_from_rois(rois)

by_zyx

by_zyx(strict: bool = True) -> Self

Return a new iterator that iterates over ROIs by ZYX coordinates.

Parameters:

  • strict (bool, default: True ) –

    If True, only iterate over ZYX if a Z axis is present and not of size 1.

Source code in src/ngio/iterators/_abstract_iterator.py
def by_zyx(self, strict: bool = True) -> Self:
    """Return a new iterator that iterates over ROIs by ZYX coordinates.

    Args:
        strict (bool): If True, only iterate over ZYX if a Z axis
            is present and not of size 1.

    """
    rois = by_zyx(self.rois, self.ref_image, strict=strict)
    return self._new_from_rois(rois)

by_chunks

by_chunks(overlap_xy: int = 0, overlap_z: int = 0) -> Self

Return a new iterator that iterates over ROIs by chunks.

Parameters:

  • overlap_xy (int, default: 0 ) –

    Overlap in XY dimensions.

  • overlap_z (int, default: 0 ) –

    Overlap in Z dimension.

Returns:

  • SegmentationIterator ( Self ) –

    A new iterator with chunked ROIs.

Source code in src/ngio/iterators/_abstract_iterator.py
def by_chunks(self, overlap_xy: int = 0, overlap_z: int = 0) -> Self:
    """Return a new iterator that iterates over ROIs by chunks.

    Args:
        overlap_xy (int): Overlap in XY dimensions.
        overlap_z (int): Overlap in Z dimension.

    Returns:
        SegmentationIterator: A new iterator with chunked ROIs.
    """
    rois = by_chunks(
        self.rois, self.ref_image, overlap_xy=overlap_xy, overlap_z=overlap_z
    )
    return self._new_from_rois(rois)

product

product(other: list[Roi] | GenericRoiTable) -> Self

Cartesian product of the current ROIs with an arbitrary list of ROIs.

Source code in src/ngio/iterators/_abstract_iterator.py
def product(self, other: list[Roi] | GenericRoiTable) -> Self:
    """Cartesian product of the current ROIs with an arbitrary list of ROIs."""
    if isinstance(other, GenericRoiTable):
        other = other.rois()
    rois = rois_product(self.rois, other)
    return self._new_from_rois(rois)

iter

iter(
    lazy: Literal[True],
    data_mode: Literal["numpy"],
    iterator_mode: Literal["readwrite"],
) -> Generator[
    tuple[
        DataGetterProtocol[NumpyPipeType],
        DataSetterProtocol[NumpyPipeType],
    ]
]
iter(
    lazy: Literal[True],
    data_mode: Literal["numpy"],
    iterator_mode: Literal["readonly"] = ...,
) -> Generator[DataGetterProtocol[NumpyPipeType]]
iter(
    lazy: Literal[True],
    data_mode: Literal["dask"],
    iterator_mode: Literal["readwrite"],
) -> Generator[
    tuple[
        DataGetterProtocol[DaskPipeType],
        DataSetterProtocol[DaskPipeType],
    ]
]
iter(
    lazy: Literal[True],
    data_mode: Literal["dask"],
    iterator_mode: Literal["readonly"] = ...,
) -> Generator[DataGetterProtocol[DaskPipeType]]
iter(
    lazy: Literal[False],
    data_mode: Literal["numpy"],
    iterator_mode: Literal["readwrite"],
) -> Generator[
    tuple[NumpyPipeType, DataSetterProtocol[NumpyPipeType]]
]
iter(
    lazy: Literal[False],
    data_mode: Literal["numpy"],
    iterator_mode: Literal["readonly"] = ...,
) -> Generator[NumpyPipeType]
iter(
    lazy: Literal[False],
    data_mode: Literal["dask"],
    iterator_mode: Literal["readwrite"],
) -> Generator[
    tuple[DaskPipeType, DataSetterProtocol[DaskPipeType]]
]
iter(
    lazy: Literal[False],
    data_mode: Literal["dask"],
    iterator_mode: Literal["readonly"] = ...,
) -> Generator[DaskPipeType]
iter(
    lazy: bool = False,
    data_mode: Literal["numpy", "dask"] = "dask",
    iterator_mode: Literal[
        "readwrite", "readonly"
    ] = "readwrite",
) -> Generator

Create an iterator over the pixels of the ROIs.

Source code in src/ngio/iterators/_abstract_iterator.py
def iter(
    self,
    lazy: bool = False,
    data_mode: Literal["numpy", "dask"] = "dask",
    iterator_mode: Literal["readwrite", "readonly"] = "readwrite",
) -> Generator:
    """Create an iterator over the pixels of the ROIs."""
    if data_mode == "numpy":
        getters = self._numpy_getters_generator()
        setters = self._numpy_setters_generator()
    elif data_mode == "dask":
        getters = self._dask_getters_generator()
        setters = self._dask_setters_generator()
    else:
        raise NgioValueError(f"Invalid mode: {data_mode}")

    if iterator_mode == "readonly":
        if lazy:
            return getters
        else:
            return (getter() for getter in getters)
    if lazy:
        return self._read_and_write_generator(getters, setters)
    else:
        gen = self._read_and_write_generator(getters, setters)
        return ((getter(), setter) for getter, setter in gen)

map_as_numpy

map_as_numpy(
    func: Callable[[NumpyPipeType], NumpyPipeType],
    mapper: MapperProtocol[NumpyPipeType] | None = None,
) -> None

Apply a transformation function to the ROI pixels.

Source code in src/ngio/iterators/_abstract_iterator.py
def map_as_numpy(
    self,
    func: Callable[[NumpyPipeType], NumpyPipeType],
    mapper: MapperProtocol[NumpyPipeType] | None = None,
) -> None:
    """Apply a transformation function to the ROI pixels."""
    if mapper is None:
        _mapper = BasicMapper[NumpyPipeType]()
    else:
        _mapper = mapper

    _mapper(
        func=func,
        getters=self._numpy_getters_generator(),
        setters=self._numpy_setters_generator(),
    )
    self.post_consolidate()

map_as_dask

map_as_dask(
    func: Callable[[DaskPipeType], DaskPipeType],
    mapper: MapperProtocol[DaskPipeType] | None = None,
) -> None

Apply a transformation function to the ROI pixels.

Source code in src/ngio/iterators/_abstract_iterator.py
def map_as_dask(
    self,
    func: Callable[[DaskPipeType], DaskPipeType],
    mapper: MapperProtocol[DaskPipeType] | None = None,
) -> None:
    """Apply a transformation function to the ROI pixels."""
    if mapper is None:
        _mapper = BasicMapper[DaskPipeType]()
    else:
        _mapper = mapper

    _mapper(
        func=func,
        getters=self._dask_getters_generator(),
        setters=self._dask_setters_generator(),
    )
    self.post_consolidate()

check_if_regions_overlap

check_if_regions_overlap() -> bool

Check if any of the ROIs overlap logically.

If two ROIs cover the same pixel, they are considered to overlap. This does not consider chunking or other storage details.

Returns:

  • bool ( bool ) –

    True if any ROIs overlap. False otherwise.

Source code in src/ngio/iterators/_abstract_iterator.py
def check_if_regions_overlap(self) -> bool:
    """Check if any of the ROIs overlap logically.

    If two ROIs cover the same pixel, they are considered to overlap.
    This does not consider chunking or other storage details.

    Returns:
        bool: True if any ROIs overlap. False otherwise.
    """
    if len(self.rois) < 2:
        # Less than 2 ROIs cannot overlap
        return False

    slicing_tuples = (
        g.slicing_ops.normalized_slicing_tuple
        for g in self._numpy_getters_generator()
    )
    x = check_if_regions_overlap(slicing_tuples)
    return x

require_no_regions_overlap

require_no_regions_overlap() -> None

Ensure that the Iterator's ROIs do not overlap.

Source code in src/ngio/iterators/_abstract_iterator.py
def require_no_regions_overlap(self) -> None:
    """Ensure that the Iterator's ROIs do not overlap."""
    if self.check_if_regions_overlap():
        raise NgioValueError("Some rois overlap.")

check_if_chunks_overlap

check_if_chunks_overlap() -> bool

Check if any of the ROIs overlap in terms of chunks.

If two ROIs cover the same chunk, they are considered to overlap in chunks. This does not consider pixel-level overlaps.

Returns:

  • bool ( bool ) –

    True if any ROIs overlap in chunks, False otherwise.

Source code in src/ngio/iterators/_abstract_iterator.py
def check_if_chunks_overlap(self) -> bool:
    """Check if any of the ROIs overlap in terms of chunks.

    If two ROIs cover the same chunk, they are considered to overlap in chunks.
    This does not consider pixel-level overlaps.

    Returns:
        bool: True if any ROIs overlap in chunks, False otherwise.
    """
    from ngio.io_pipes._ops_slices_utils import check_if_chunks_overlap

    if len(self.rois) < 2:
        # Less than 2 ROIs cannot overlap
        return False

    slicing_tuples = (
        g.slicing_ops.normalized_slicing_tuple
        for g in self._numpy_getters_generator()
    )
    shape = self.ref_image.shape
    chunks = self.ref_image.chunks
    return check_if_chunks_overlap(slicing_tuples, shape, chunks)

require_no_chunks_overlap

require_no_chunks_overlap() -> None

Ensure that the ROIs do not overlap in terms of chunks.

Source code in src/ngio/iterators/_abstract_iterator.py
def require_no_chunks_overlap(self) -> None:
    """Ensure that the ROIs do not overlap in terms of chunks."""
    if self.check_if_chunks_overlap():
        raise NgioValueError("Some rois overlap in chunks.")

get_init_kwargs

get_init_kwargs() -> dict

Return the initialization arguments for the iterator.

Source code in src/ngio/iterators/_feature.py
def get_init_kwargs(self) -> dict:
    """Return the initialization arguments for the iterator."""
    return {
        "input_image": self._input,
        "input_label": self._input_label,
        "channel_selection": self._channel_selection,
        "axes_order": self._axes_order,
        "input_transforms": self._input_transforms,
        "label_transforms": self._label_transforms,
    }

build_numpy_getter

build_numpy_getter(roi: Roi) -> NumpyFeatureGetter
Source code in src/ngio/iterators/_feature.py
def build_numpy_getter(self, roi: Roi) -> NumpyFeatureGetter:
    data_getter = NumpyRoiGetter(
        zarr_array=self._input.zarr_array,
        dimensions=self._input.dimensions,
        axes_order=self._axes_order,
        transforms=self._input_transforms,
        roi=roi,
        slicing_dict=self._input_slicing_kwargs,
    )
    label_getter = NumpyRoiGetter(
        zarr_array=self._input_label.zarr_array,
        dimensions=self._input_label.dimensions,
        axes_order=self._axes_order,
        transforms=self._label_transforms,
        roi=roi,
        remove_channel_selection=True,
    )
    return NumpyFeatureGetter(data_getter, label_getter)

build_dask_getter

build_dask_getter(roi: Roi) -> DaskFeatureGetter
Source code in src/ngio/iterators/_feature.py
def build_dask_getter(self, roi: Roi) -> DaskFeatureGetter:
    data_getter = DaskRoiGetter(
        zarr_array=self._input.zarr_array,
        dimensions=self._input.dimensions,
        axes_order=self._axes_order,
        transforms=self._input_transforms,
        roi=roi,
        slicing_dict=self._input_slicing_kwargs,
    )
    label_getter = DaskRoiGetter(
        zarr_array=self._input_label.zarr_array,
        dimensions=self._input_label.dimensions,
        axes_order=self._axes_order,
        transforms=self._label_transforms,
        roi=roi,
        remove_channel_selection=True,
    )
    return DaskFeatureGetter(data_getter, label_getter)

build_numpy_setter

build_numpy_setter(roi: Roi) -> None
Source code in src/ngio/iterators/_feature.py
def build_numpy_setter(self, roi: Roi) -> None:
    return None

build_dask_setter

build_dask_setter(roi: Roi) -> None
Source code in src/ngio/iterators/_feature.py
def build_dask_setter(self, roi: Roi) -> None:
    return None

post_consolidate

post_consolidate()
Source code in src/ngio/iterators/_feature.py
def post_consolidate(self):
    pass

iter_as_numpy

iter_as_numpy()

Create an iterator over the pixels of the ROIs.

Source code in src/ngio/iterators/_feature.py
def iter_as_numpy(self):  # type: ignore[override]
    """Create an iterator over the pixels of the ROIs."""
    return self.iter(lazy=False, data_mode="numpy", iterator_mode="readonly")

iter_as_dask

iter_as_dask()

Create an iterator over the pixels of the ROIs.

Source code in src/ngio/iterators/_feature.py
def iter_as_dask(self):  # type: ignore[override]
    """Create an iterator over the pixels of the ROIs."""
    return self.iter(lazy=False, data_mode="dask", iterator_mode="readonly")