bioimage_py.downsample

Block-wise downsampling of a source.

Downsampling wraps the input in a ~bioimage_py.wrapper.ResizedSource at the downscaled target shape and copies it block-wise into the output, reusing the copy machinery. Because the wrapper resamples on read, this is exactly a block-wise copy of the resized source.

 1"""Block-wise downsampling of a source.
 2
 3Downsampling wraps the input in a :class:`~bioimage_py.wrapper.ResizedSource` at the downscaled
 4target shape and copies it block-wise into the output, reusing the copy machinery. Because the
 5wrapper resamples on read, this is exactly a block-wise copy of the resized source.
 6"""
 7from __future__ import annotations
 8
 9from numbers import Integral
10from typing import Optional, Sequence, Tuple, Union
11
12from .copy import _copy_source
13from .runner.config import RunnerConfig
14from .sources import SourceLike, as_source
15from .util import downscale_shape
16from .wrapper import ResizedSource
17
18__all__ = ["downsample"]
19
20# A downscaling factor: a single int (isotropic) or a per-axis sequence of ints.
21ScaleFactor = Union[int, Sequence[int]]
22
23
24def downsample(
25    input: SourceLike,
26    scale_factor: ScaleFactor,
27    output: Optional[SourceLike] = None,
28    *,
29    order: int = 0,
30    anti_aliasing: bool = False,
31    block_shape: Optional[Tuple[int, ...]] = None,
32    job_type: str = "local",
33    job_config: Optional[RunnerConfig] = None,
34    num_workers: int = 1,
35    mask: Optional[SourceLike] = None,
36    block_ids: Optional[Sequence[int]] = None,
37    resume_from: Optional[str] = None,
38) -> SourceLike:
39    """Downsample a source by an integer factor, block-wise.
40
41    The input is wrapped in a :class:`~bioimage_py.wrapper.ResizedSource` at the downscaled shape
42    (computed with :func:`~bioimage_py.util.downscale_shape`, ceil mode) and copied into the output.
43
44    The defaults (``order=0`` nearest, ``anti_aliasing=False``) are label-safe — they preserve the
45    input values and are appropriate for segmentations. For intensity / image data pass ``order=1``
46    (or higher) and ``anti_aliasing=True`` for a smooth, alias-free downsample.
47
48    Args:
49        input: The input data to downsample (a numpy/zarr/n5 array or a `Source`). 2D or 3D.
50        scale_factor: The downscaling factor: a single int (isotropic) or a per-axis sequence of
51            ints. Each factor must be ``>= 1`` (1 leaves that axis unchanged).
52        output: The output array to write into. Optional for local execution — a numpy array of the
53            downscaled shape and the input dtype is allocated and returned if omitted; **required**
54            for distributed execution, where it (and the input) must be file-backed (zarr/n5).
55        order: The interpolation order (0 to 5). Use ``0`` (nearest) for label data.
56        anti_aliasing: Whether to Gaussian pre-smooth before sampling to avoid aliasing.
57            Recommended for image data; leave ``False`` for labels.
58        block_shape: Shape of the processing blocks (in the downscaled output space). Defaults to
59            the resized source's chunk shape; required for unchunked data.
60        job_type: Execution backend: one of ``"local"``, ``"subprocess"`` or ``"slurm"``.
61        job_config: Backend configuration (a `RunnerConfig` / `SlurmConfig`).
62        num_workers: Number of parallel workers (threads for ``local``, tasks for distributed
63            backends).
64        mask: Optional binary mask in the downscaled output space; only voxels within the mask are
65            written (out-of-mask output voxels are left unchanged).
66        block_ids: Restrict processing to these block ids (in the downscaled output space), e.g. to
67            re-run previously failed blocks into the existing ``output``. Mutually exclusive with
68            ``resume_from``.
69        resume_from: Distributed only; the preserved temp folder of a failed run to resume (see
70            ``runner.run``); the missing blocks are written into ``output``. Mutually exclusive
71            with ``block_ids``.
72
73    Returns:
74        The output array (the provided ``output``, or a newly allocated numpy array).
75    """
76    src = as_source(input)
77    ndim = src.ndim
78    if isinstance(scale_factor, Integral):
79        factors: Tuple[int, ...] = (int(scale_factor),) * ndim
80    else:
81        factors = tuple(int(f) for f in scale_factor)
82        if len(factors) != ndim:
83            raise ValueError(
84                f"scale_factor {scale_factor} does not match the input dimensionality {ndim}."
85            )
86    if any(f < 1 for f in factors):
87        raise ValueError(
88            f"downsample requires scale factors >= 1, got {factors}; "
89            "use a ResizedSource directly to upsample."
90        )
91
92    target_shape = downscale_shape(src.shape, factors)
93    wrapped = ResizedSource(src, target_shape, order=order, anti_aliasing=anti_aliasing)
94    return _copy_source(wrapped, output, block_shape=block_shape, job_type=job_type,
95                        job_config=job_config, num_workers=num_workers, mask=mask, name="downsample",
96                        block_ids=block_ids, resume_from=resume_from)
def downsample( input: 'SourceLike', scale_factor: Union[int, Sequence[int]], output: 'Optional[SourceLike]' = None, *, order: int = 0, anti_aliasing: bool = False, block_shape: Optional[Tuple[int, ...]] = None, job_type: str = 'local', job_config: Optional[bioimage_py.runner.RunnerConfig] = None, num_workers: int = 1, mask: 'Optional[SourceLike]' = None, block_ids: Optional[Sequence[int]] = None, resume_from: Optional[str] = None) -> 'SourceLike':
25def downsample(
26    input: SourceLike,
27    scale_factor: ScaleFactor,
28    output: Optional[SourceLike] = None,
29    *,
30    order: int = 0,
31    anti_aliasing: bool = False,
32    block_shape: Optional[Tuple[int, ...]] = None,
33    job_type: str = "local",
34    job_config: Optional[RunnerConfig] = None,
35    num_workers: int = 1,
36    mask: Optional[SourceLike] = None,
37    block_ids: Optional[Sequence[int]] = None,
38    resume_from: Optional[str] = None,
39) -> SourceLike:
40    """Downsample a source by an integer factor, block-wise.
41
42    The input is wrapped in a :class:`~bioimage_py.wrapper.ResizedSource` at the downscaled shape
43    (computed with :func:`~bioimage_py.util.downscale_shape`, ceil mode) and copied into the output.
44
45    The defaults (``order=0`` nearest, ``anti_aliasing=False``) are label-safe — they preserve the
46    input values and are appropriate for segmentations. For intensity / image data pass ``order=1``
47    (or higher) and ``anti_aliasing=True`` for a smooth, alias-free downsample.
48
49    Args:
50        input: The input data to downsample (a numpy/zarr/n5 array or a `Source`). 2D or 3D.
51        scale_factor: The downscaling factor: a single int (isotropic) or a per-axis sequence of
52            ints. Each factor must be ``>= 1`` (1 leaves that axis unchanged).
53        output: The output array to write into. Optional for local execution — a numpy array of the
54            downscaled shape and the input dtype is allocated and returned if omitted; **required**
55            for distributed execution, where it (and the input) must be file-backed (zarr/n5).
56        order: The interpolation order (0 to 5). Use ``0`` (nearest) for label data.
57        anti_aliasing: Whether to Gaussian pre-smooth before sampling to avoid aliasing.
58            Recommended for image data; leave ``False`` for labels.
59        block_shape: Shape of the processing blocks (in the downscaled output space). Defaults to
60            the resized source's chunk shape; required for unchunked data.
61        job_type: Execution backend: one of ``"local"``, ``"subprocess"`` or ``"slurm"``.
62        job_config: Backend configuration (a `RunnerConfig` / `SlurmConfig`).
63        num_workers: Number of parallel workers (threads for ``local``, tasks for distributed
64            backends).
65        mask: Optional binary mask in the downscaled output space; only voxels within the mask are
66            written (out-of-mask output voxels are left unchanged).
67        block_ids: Restrict processing to these block ids (in the downscaled output space), e.g. to
68            re-run previously failed blocks into the existing ``output``. Mutually exclusive with
69            ``resume_from``.
70        resume_from: Distributed only; the preserved temp folder of a failed run to resume (see
71            ``runner.run``); the missing blocks are written into ``output``. Mutually exclusive
72            with ``block_ids``.
73
74    Returns:
75        The output array (the provided ``output``, or a newly allocated numpy array).
76    """
77    src = as_source(input)
78    ndim = src.ndim
79    if isinstance(scale_factor, Integral):
80        factors: Tuple[int, ...] = (int(scale_factor),) * ndim
81    else:
82        factors = tuple(int(f) for f in scale_factor)
83        if len(factors) != ndim:
84            raise ValueError(
85                f"scale_factor {scale_factor} does not match the input dimensionality {ndim}."
86            )
87    if any(f < 1 for f in factors):
88        raise ValueError(
89            f"downsample requires scale factors >= 1, got {factors}; "
90            "use a ResizedSource directly to upsample."
91        )
92
93    target_shape = downscale_shape(src.shape, factors)
94    wrapped = ResizedSource(src, target_shape, order=order, anti_aliasing=anti_aliasing)
95    return _copy_source(wrapped, output, block_shape=block_shape, job_type=job_type,
96                        job_config=job_config, num_workers=num_workers, mask=mask, name="downsample",
97                        block_ids=block_ids, resume_from=resume_from)

Downsample a source by an integer factor, block-wise.

The input is wrapped in a ~bioimage_py.wrapper.ResizedSource at the downscaled shape (computed with ~bioimage_py.util.downscale_shape(), ceil mode) and copied into the output.

The defaults (order=0 nearest, anti_aliasing=False) are label-safe — they preserve the input values and are appropriate for segmentations. For intensity / image data pass order=1 (or higher) and anti_aliasing=True for a smooth, alias-free downsample.

Args: input: The input data to downsample (a numpy/zarr/n5 array or a Source). 2D or 3D. scale_factor: The downscaling factor: a single int (isotropic) or a per-axis sequence of ints. Each factor must be >= 1 (1 leaves that axis unchanged). output: The output array to write into. Optional for local execution — a numpy array of the downscaled shape and the input dtype is allocated and returned if omitted; required for distributed execution, where it (and the input) must be file-backed (zarr/n5). order: The interpolation order (0 to 5). Use 0 (nearest) for label data. anti_aliasing: Whether to Gaussian pre-smooth before sampling to avoid aliasing. Recommended for image data; leave False for labels. block_shape: Shape of the processing blocks (in the downscaled output space). Defaults to the resized source's chunk shape; required for unchunked data. job_type: Execution backend: one of "local", "subprocess" or "slurm". job_config: Backend configuration (a RunnerConfig / SlurmConfig). num_workers: Number of parallel workers (threads for local, tasks for distributed backends). mask: Optional binary mask in the downscaled output space; only voxels within the mask are written (out-of-mask output voxels are left unchanged). block_ids: Restrict processing to these block ids (in the downscaled output space), e.g. to re-run previously failed blocks into the existing output. Mutually exclusive with resume_from. resume_from: Distributed only; the preserved temp folder of a failed run to resume (see runner.run); the missing blocks are written into output. Mutually exclusive with block_ids.

Returns: The output array (the provided output, or a newly allocated numpy array).