Skip to content

core ¤

bioimageio.core --- core functionality for BioImage.IO resources

The main focus on this library is to provide functionality to run prediction with BioImage.IO models, including standardized pre- and postprocessing operations. The BioImage.IO models (and other resources) are described by---and can be loaded with---the bioimageio.spec package.

See predict and predict_many for straight-forward model inference and create_prediction_pipeline for finer control of the inference process.

Other notable bioimageio.core functionalities include: - Testing BioImage.IO resources beyond format validation, e.g. by generating model outputs from test inputs. See test_model or for arbitrary resource types test_description. - Extending available model weight formats by converting existing ones, see add_weights. - Creating and manipulating Samples consisting of tensors with associated statistics. - Computing statistics on datasets (represented as sequences of samples), see compute_dataset_measures.

Modules:

Name Description
__main__
axis
backends
block
block_meta
cli

bioimageio CLI

commands

These functions are used in the bioimageio command line interface

common
dataset
digest_spec
io
prediction
proc_ops
proc_setup
remote_backends
sample
stat_calculators
stat_measures
tensor
utils
weight_converters

Classes:

Name Description
Axis
BlockMeta

Block meta data of a sample member (a tensor in a sample)

IntermediatePrediction

Represents an intermediate prediction of a sample with blocking, including the predicted sample so far and the last predicted block.

PredictionPipeline

Represents model computation including preprocessing and postprocessing

RemotePredictionPipeline

Abstract base class for fully remote prediction pipelines.

Sample

A dataset sample.

SampleBlock

A block of a dataset sample

SampleBlockMeta

Meta data of a dataset sample block

SampleSerializer
Settings

environment variables for bioimageio.spec and bioimageio.core

Tensor

A wrapper around an xr.DataArray for better integration with bioimageio.spec

Functions:

Name Description
add_weights

Convert model weights to other formats and add them to the model description

build_description

build a bioimage.io resource description from an RDF's content.

compute_dataset_measures

compute all dataset measures for the given dataset

compute_measures

compute all measures for the given dataset

compute_sample_measures

compute all sample measures for the given sample

create_model_adapter

Creates model adapter for model_descritption

create_prediction_pipeline

Creates prediction pipeline which includes:

create_remote_prediction_pipeline

Create a RemotePredictionPipeline for the given model_description.

dump_description

Converts a resource to a dictionary containing only simple types that can directly be serialzed to YAML.

enable_determinism

Seed and configure ML frameworks for maximum reproducibility.

load_dataset_description

same as load_description, but addtionally ensures that the loaded

load_description

load a bioimage.io resource description

load_description_and_test

Test a bioimage.io resource dynamically,

load_description_and_validate_format_only

same as load_description, but only return the validation summary.

load_model_description

same as load_description, but addtionally ensures that the loaded

predict

Run prediction for a single set of input(s) with a bioimage.io model

predict_many

Run prediction for a multiple sets of inputs with a bioimage.io model

save_bioimageio_package

Package a bioimageio resource as a zip file.

save_bioimageio_package_as_folder

Write the content of a bioimage.io resource package to a folder.

save_bioimageio_yaml_only

write the metadata of a resource description (rd) to file

test_description

Test a bioimage.io resource dynamically,

test_model

Test model inference

validate_format

Validate a dictionary holding a bioimageio description.

Attributes:

Name Type Description
AxisId TypeAlias

An axis identifier, e.g. 'batch', 'channel', 'z', 'y', 'x'

MemberId

ID of a Sample member, see bioimageio.core.sample.Sample

Stat TypeAlias
ValidationSummary
__version__
load_model

alias of load_model_description

load_resource

alias of load_description

settings

parsed environment variables for bioimageio.spec and bioimageio.core

test_resource

alias of test_description

ValidationSummary module-attribute ¤

ValidationSummary = summary.ValidationSummary

__version__ module-attribute ¤

__version__ = '0.11.0'

load_model module-attribute ¤

alias of load_model_description

load_resource module-attribute ¤

load_resource = load_description

alias of load_description

settings module-attribute ¤

settings = Settings()

parsed environment variables for bioimageio.spec and bioimageio.core

test_resource module-attribute ¤

test_resource = test_description

alias of test_description

Axis dataclass ¤

Axis(id: AxisId, type: Literal['batch', 'channel', 'index', 'space', 'time'])

Methods:

Name Description
__post_init__
create

Attributes:

Name Type Description
id AxisId
type Literal['batch', 'channel', 'index', 'space', 'time']

id instance-attribute ¤

id: AxisId

type instance-attribute ¤

type: Literal['batch', 'channel', 'index', 'space', 'time']

__post_init__ ¤

__post_init__()
Source code in src/bioimageio/core/axis.py
69
70
71
72
73
def __post_init__(self):
    if self.type == "batch":
        self.id = AxisId("batch")
    elif self.type == "channel":
        self.id = AxisId("channel")

create classmethod ¤

create(axis: AxisLike) -> Axis
Source code in src/bioimageio/core/axis.py
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
@classmethod
def create(cls, axis: AxisLike) -> Axis:
    if isinstance(axis, cls):
        return axis

    if isinstance(axis, (AxisId, str)):
        axis_id = axis
        axis_type = _guess_axis_type(str(axis))
    else:
        if hasattr(axis, "type"):
            axis_type = axis.type
        else:
            axis_type = _guess_axis_type(str(axis))

        if hasattr(axis, "id"):
            axis_id = axis.id
        else:
            axis_id = axis

    return Axis(id=AxisId(axis_id), type=axis_type)

BlockMeta ¤

Block meta data of a sample member (a tensor in a sample)

Figure for illustration: The first 2d block (dashed) of a sample member (bold). The inner slice (thin) is expanded by a halo in both dimensions on both sides. The outer slice reaches from the sample member origin (0, 0) to the right halo point.

first block (at the sample origin)
┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─┐
╷ halo(left)                         ╷
╷         padding outside the sample ╷
╷  (0, 0)┏━━━━━━━━━━━━━━━━━┯━━━━━━━━━┯━━━➔
╷        ┃                 │         ╷  sample member
╷        ┃      inner      │  outer  ╷
╷        ┃      region     │  region ╷
╷        ┃      /slice     │  /slice ╷
╷        ┃                 │         ╷
╷        ┣─────────────────┘         ╷
╷        ┃   outer region/slice      ╷
╷        ┃               halo(right) ╷
└ ─ ─ ─ ─┃─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─┘
         ⬇

Note: - Inner and outer slices are specified in sample member coordinates. - The outer_slice of a block at the sample edge may overlap by more than the halo with the neighboring block (the inner slices will not overlap though).

Methods:

Name Description
__post_init__
get_transformed

Attributes:

Name Type Description
block_index BlockIndex

the i-th block of the sample

blocks_in_sample TotalNumberOfBlocks

total number of blocks in the sample

dims Collection[AxisId]
halo PerAxisAnno[Halo]

halo enlarging the inner region to the block's sizes

inner_shape PerAxis[int]

axis lengths of the inner region (without halo)

inner_slice PerAxisAnno[SliceInfo]

inner region (without halo) wrt the sample

inner_slice_wo_overlap PerAxis[SliceInfo]

subslice of the inner slice, such that all inner_slice_wo_overlap can be

local_slice PerAxis[SliceInfo]

inner slice wrt the block, not the sample

outer_slice PerAxis[SliceInfo]

slice of the outer block (without padding) wrt the sample

padding PerAxis[PadWidth]

padding to realize the halo at the sample edge

sample_shape PerAxisAnno[int]

the axis sizes of the whole (unblocked) sample

shape PerAxis[int]

axis lengths of the block

tagged_shape PerAxis[int]

alias for shape

block_index instance-attribute ¤

block_index: BlockIndex

the i-th block of the sample

blocks_in_sample instance-attribute ¤

blocks_in_sample: TotalNumberOfBlocks

total number of blocks in the sample

dims property ¤

dims: Collection[AxisId]

halo instance-attribute ¤

halo: PerAxisAnno[Halo]

halo enlarging the inner region to the block's sizes

inner_shape cached property ¤

inner_shape: PerAxis[int]

axis lengths of the inner region (without halo)

inner_slice instance-attribute ¤

inner_slice: PerAxisAnno[SliceInfo]

inner region (without halo) wrt the sample

inner_slice_wo_overlap property ¤

inner_slice_wo_overlap: PerAxis[SliceInfo]

subslice of the inner slice, such that all inner_slice_wo_overlap can be stiched together trivially to form the original sample.

This can also be used to calculate statistics without overrepresenting block edge regions.

local_slice cached property ¤

local_slice: PerAxis[SliceInfo]

inner slice wrt the block, not the sample

outer_slice cached property ¤

outer_slice: PerAxis[SliceInfo]

slice of the outer block (without padding) wrt the sample

padding cached property ¤

padding: PerAxis[PadWidth]

padding to realize the halo at the sample edge where we cannot simply enlarge the inner slice

sample_shape instance-attribute ¤

sample_shape: PerAxisAnno[int]

the axis sizes of the whole (unblocked) sample

shape cached property ¤

shape: PerAxis[int]

axis lengths of the block

tagged_shape property ¤

tagged_shape: PerAxis[int]

alias for shape

__post_init__ ¤

__post_init__()
Source code in src/bioimageio/core/block_meta.py
199
200
201
202
203
204
205
206
207
208
209
210
211
def __post_init__(self):
    assert all(a in self.sample_shape for a in self.inner_slice), (
        "block has axes not present in sample"
    )

    assert all(a in self.inner_slice for a in self.halo), (
        "halo has axes not present in block"
    )

    if any(s > self.sample_shape[a] for a, s in self.shape.items()):
        logger.warning(
            "block {} larger than sample {}", self.shape, self.sample_shape
        )

get_transformed ¤

get_transformed(new_axes: PerAxis[Union[LinearAxisTransform, int]]) -> Self
Source code in src/bioimageio/core/block_meta.py
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
def get_transformed(
    self, new_axes: PerAxis[Union[LinearAxisTransform, int]]
) -> Self:
    return self.__class__(
        sample_shape={
            a: (
                trf
                if isinstance(trf, int)
                else trf.compute(self.sample_shape[trf.axis])
            )
            for a, trf in new_axes.items()
        },
        inner_slice={
            a: (
                SliceInfo(0, trf)
                if isinstance(trf, int)
                else SliceInfo(
                    trf.compute(self.inner_slice[trf.axis].start),
                    trf.compute(self.inner_slice[trf.axis].stop),
                )
            )
            for a, trf in new_axes.items()
        },
        halo={
            a: (
                Halo(0, 0)
                if isinstance(trf, int)
                else Halo(self.halo[trf.axis].left, self.halo[trf.axis].right)
            )
            for a, trf in new_axes.items()
        },
        block_index=self.block_index,
        blocks_in_sample=self.blocks_in_sample,
    )

IntermediatePrediction ¤

Bases: NamedTuple


              flowchart TD
              bioimageio.core.IntermediatePrediction[IntermediatePrediction]

              

              click bioimageio.core.IntermediatePrediction href "" "bioimageio.core.IntermediatePrediction"
            

Represents an intermediate prediction of a sample with blocking, including the predicted sample so far and the last predicted block.

The final IntermediatePrediction in a sequence holds the complete predicted (and postprocessed if applicable) sample.

Attributes:

Name Type Description
last_block SampleBlock
sample Sample

last_block instance-attribute ¤

last_block: SampleBlock

sample instance-attribute ¤

sample: Sample

PredictionPipeline ¤

PredictionPipeline(*, name: str, model_description: AnyModelDescr, preprocessing: List[Processing], postprocessing: List[Processing], model_adapter: ModelAdapter, default_blocksize_parameter: BlocksizeParameter = 10, default_batch_size: int = 1, preceding_prediction_pipelines: Optional[Sequence[Union[PredictionPipeline, RemotePredictionPipeline]]] = None)

Bases: _PredictionPipelineBase


              flowchart TD
              bioimageio.core.PredictionPipeline[PredictionPipeline]
              bioimageio.core._prediction_pipeline._PredictionPipelineBase[_PredictionPipelineBase]

                              bioimageio.core._prediction_pipeline._PredictionPipelineBase --> bioimageio.core.PredictionPipeline
                


              click bioimageio.core.PredictionPipeline href "" "bioimageio.core.PredictionPipeline"
              click bioimageio.core._prediction_pipeline._PredictionPipelineBase href "" "bioimageio.core._prediction_pipeline._PredictionPipelineBase"
            

Represents model computation including preprocessing and postprocessing Note: Ideally use the PredictionPipeline in a with statement (as a context manager).

Methods:

Name Description
__enter__
__exit__
apply_postprocessing

apply postprocessing in-place, also may updates samples stats

apply_preprocessing

Apply preprocessing in-place, also may updates sample stats

close

Permanently close the prediction pipeline and free any device memory in use.

get_output_sample_id
load

Prepare prediction pipeline for use.

predict_sample_block

Predict a single sample block.

predict_sample_with_blocking

Predict a sample by predicting sample blocks.

predict_sample_with_blocking_yield_intermediates

Predict sample by predicting sample blocks and yield intermediate predictions if no samplewise postprocessing is included.

predict_sample_with_fixed_blocking

Predict sample with given input_block_shape.

predict_sample_with_fixed_blocking_yield_intermediates

Predict sample by predicting sample blocks of input_block_shape and yield intermediate predictions if no samplewise postprocessing is included.

predict_sample_without_blocking

Predict a whole sample at once.

raise_for_non_blockwise_postprocessing

Raises:

raise_for_non_blockwise_preprocessing

Raises:

unload

Free any device memory in use.

Attributes:

Name Type Description
has_non_blockwise_postprocessing bool

True if any postprocessing operators in the pipeline are not applicable blockwise.

has_non_blockwise_preprocessing bool

True if any preprocessing operators in the pipeline are not applicable blockwise.

input_ids Sequence[MemberId]
model_descr AnyModelDescr
model_description AnyModelDescr
name
output_ids Sequence[MemberId]
pad_mode
Source code in src/bioimageio/core/_prediction_pipeline.py
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
def __init__(
    self,
    *,
    name: str,
    model_description: AnyModelDescr,
    preprocessing: List[Processing],
    postprocessing: List[Processing],
    model_adapter: ModelAdapter,
    default_blocksize_parameter: BlocksizeParameter = 10,
    default_batch_size: int = 1,
    preceding_prediction_pipelines: Optional[
        Sequence[Union["PredictionPipeline", "RemotePredictionPipeline"]]
    ] = None,
) -> None:
    """Consider using `create_prediction_pipeline` to create a `PredictionPipeline` with sensible defaults."""
    super().__init__(
        model_descr=model_description,
        default_blocksize_parameter=default_blocksize_parameter,
        default_batch_size=default_batch_size,
        preceding_prediction_pipelines=preceding_prediction_pipelines,
    )

    if model_description.run_mode:
        warnings.warn(
            f"Not yet implemented inference for run mode '{model_description.run_mode.name}'"
        )

    self.name = name
    # split preprocessing into samplewise and blockwise. samplewise preprocessing is all preprocessing up to including the last samplewise operator, blockwise preprocessing are the remaining blockwise operators.
    # I.e. some samplewise preprocessing may be a blockwise op (at some point followed by a samplewise op).
    self._samplewise_preprocessing: List[
        Union[SamplewiseOperator, BlockwiseOperator]
    ] = []
    self._blockwise_preprocessing: List[BlockwiseOperator] = []
    for op in preprocessing[::-1]:
        if isinstance(op, BlockwiseOperator) and not self._samplewise_preprocessing:
            self._blockwise_preprocessing.insert(0, op)
        else:
            self._samplewise_preprocessing.insert(0, op)
    # split postprocessing analougly, but here we start blockwise and switch to samplewise at the first samplewise operator.
    self._blockwise_postprocessing: List[BlockwiseOperator] = []
    self._samplewise_postprocessing: List[
        Union[BlockwiseOperator, SamplewiseOperator]
    ] = []
    for op in postprocessing:
        if (
            isinstance(op, BlockwiseOperator)
            and not self._samplewise_postprocessing
        ):
            self._blockwise_postprocessing.append(op)
        else:
            self._samplewise_postprocessing.append(op)

    self._adapter = model_adapter

has_non_blockwise_postprocessing property ¤

has_non_blockwise_postprocessing: bool

True if any postprocessing operators in the pipeline are not applicable blockwise.

has_non_blockwise_preprocessing property ¤

has_non_blockwise_preprocessing: bool

True if any preprocessing operators in the pipeline are not applicable blockwise.

input_ids property ¤

input_ids: Sequence[MemberId]

model_descr property ¤

model_descr: AnyModelDescr

model_description property ¤

model_description: AnyModelDescr

name instance-attribute ¤

name = name

output_ids property ¤

output_ids: Sequence[MemberId]

pad_mode instance-attribute ¤

pad_mode = {} if isinstance(model_descr, v0_4.ModelDescr) else {(descr.id): (descr.pad or v0_5.SymmetricPadding()) for descr in (model_descr.inputs)}

__enter__ ¤

__enter__()
Source code in src/bioimageio/core/_prediction_pipeline.py
496
497
498
def __enter__(self):
    self.load()
    return self

__exit__ ¤

__exit__(exc_type, exc_val, exc_tb)
Source code in src/bioimageio/core/_prediction_pipeline.py
500
501
502
def __exit__(self, exc_type, exc_val, exc_tb):  # type: ignore
    self.unload()
    return False

apply_postprocessing ¤

apply_postprocessing(sample: Union[Sample, SampleBlock]) -> None

apply postprocessing in-place, also may updates samples stats

Source code in src/bioimageio/core/_prediction_pipeline.py
779
780
781
782
783
784
785
def apply_postprocessing(self, sample: Union[Sample, SampleBlock]) -> None:
    """apply postprocessing in-place, also may updates samples stats"""
    self._apply_blockwise_postprocessing(sample)
    if isinstance(sample, Sample):
        self._apply_samplewise_postprocessing(sample)
    else:
        self.raise_for_non_blockwise_postprocessing()

apply_preprocessing ¤

apply_preprocessing(sample: Union[Sample, SampleBlock]) -> None

Apply preprocessing in-place, also may updates sample stats

Source code in src/bioimageio/core/_prediction_pipeline.py
748
749
750
751
752
753
754
755
756
def apply_preprocessing(self, sample: Union[Sample, SampleBlock]) -> None:
    """Apply preprocessing in-place, also may updates sample stats"""

    if isinstance(sample, Sample):
        self._apply_samplewise_preprocessing(sample)
    else:
        self.raise_for_non_blockwise_preprocessing()

    self._apply_blockwise_preprocessing(sample)

close ¤

close()

Permanently close the prediction pipeline and free any device memory in use. This makes the prediction pipeline unusable afterwards.

Source code in src/bioimageio/core/_prediction_pipeline.py
805
806
807
808
def close(self):
    """Permanently close the prediction pipeline and free any device memory in use.
    This makes the prediction pipeline unusable afterwards."""
    self.unload()

get_output_sample_id ¤

get_output_sample_id(input_sample_id: SampleId)
Source code in src/bioimageio/core/_prediction_pipeline.py
613
614
615
616
617
618
619
def get_output_sample_id(self, input_sample_id: SampleId):
    warnings.warn(
        "`PredictionPipeline.get_output_sample_id()` is deprecated and will be"
        + " removed soon. Output sample id is equal to input sample id, hence this"
        + " function is not needed."
    )
    return input_sample_id

load ¤

load()

Prepare prediction pipeline for use.

Reusable model adapters may be loaded and unloaded multiple times, but currently not all model adapters cleanly unload and reload.

Note

For some model adapters loading is currently part of the constructor making them unusable after unloading.

Source code in src/bioimageio/core/_prediction_pipeline.py
787
788
789
790
791
792
793
794
795
796
def load(self):
    """Prepare prediction pipeline for use.

    Reusable model adapters may be loaded and unloaded multiple times, but currently not all model adapters
    cleanly unload and reload.

    Note:
        For some model adapters loading is currently part of the constructor making them unusable after unloading.
    """
    self._adapter.load()

predict_sample_block ¤

predict_sample_block(sample_block: SampleBlock, skip_preprocessing: bool = False, skip_postprocessing: bool = False) -> SampleBlock

Predict a single sample block.

Note that this does not apply samplewise preprocessing or postprocessing steps, but only blockwise ones.

Parameters:

Name Type Description Default

sample_block ¤

SampleBlock

The sample block to predict on.

required

skip_preprocessing ¤

bool

If True, skip blockwise preprocessing steps.

False

skip_postprocessing ¤

bool

If True, skip blockwise postprocessing steps.

False
Source code in src/bioimageio/core/_prediction_pipeline.py
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
def predict_sample_block(
    self,
    sample_block: SampleBlock,
    skip_preprocessing: bool = False,
    skip_postprocessing: bool = False,
) -> SampleBlock:
    if isinstance(self._model_descr, v0_4.ModelDescr):
        raise NotImplementedError(
            f"predict_sample_block not implemented for model {self._model_descr.format_version}"
        )
    else:
        assert self._block_transform is not None

    if not skip_preprocessing:
        self._apply_blockwise_preprocessing(sample_block)

    output_meta = sample_block.get_transformed_meta(self._block_transform)
    local_output = self._adapter.forward(sample_block.members)

    output = output_meta.with_data(
        {k: v for k, v in local_output.items() if v is not None},
        stat=sample_block.stat,
    )
    if not skip_postprocessing:
        self._apply_blockwise_postprocessing(output)

    return output

predict_sample_with_blocking ¤

predict_sample_with_blocking(sample: Sample, skip_preprocessing: bool = False, skip_postprocessing: bool = False, ns: Optional[Union[v0_5.ParameterizedSize_N, Mapping[Tuple[MemberId, AxisId], v0_5.ParameterizedSize_N]]] = None, batch_size: Optional[int] = None) -> Sample

Predict a sample by predicting sample blocks.

Note: For fixed/known blocksizes use predict_sample_with_fixed_blocking.

Parameters:

Name Type Description Default

sample ¤

Sample

The sample to predict on.

required

skip_preprocessing ¤

bool

If True, skip all preprocessing steps.

False

skip_postprocessing ¤

bool

If True, skip all postprocessing steps.

False

ns ¤

Optional[Union[v0_5.ParameterizedSize_N, Mapping[Tuple[MemberId, AxisId], v0_5.ParameterizedSize_N]]]

Block size parameter(s) allows scaling the model's default input block size. Blocksize parameters are only applied to parameterized input axes, all other axis sizes are fixed/derived or (for output axes) data dependent. Unapplicable blocksize parameters are ignored.

None

batch_size ¤

Optional[int]

Batch size to use for prediction.

None
Source code in src/bioimageio/core/_prediction_pipeline.py
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
def predict_sample_with_blocking(
    self,
    sample: Sample,
    skip_preprocessing: bool = False,
    skip_postprocessing: bool = False,
    ns: Optional[
        Union[
            v0_5.ParameterizedSize_N,
            Mapping[Tuple[MemberId, AxisId], v0_5.ParameterizedSize_N],
        ]
    ] = None,
    batch_size: Optional[int] = None,
) -> Sample:
    output = None
    for output in self.predict_sample_with_blocking_yield_intermediates(
        sample,
        skip_preprocessing=skip_preprocessing,
        skip_postprocessing=skip_postprocessing,
        ns=ns,
        batch_size=batch_size,
    )[1]:
        pass

    assert output is not None, (
        "No blocks were predicted, cannot return final sample."
    )
    return output.sample

predict_sample_with_blocking_yield_intermediates ¤

predict_sample_with_blocking_yield_intermediates(sample: Sample, skip_preprocessing: bool = False, skip_postprocessing: bool = False, ns: Optional[Union[v0_5.ParameterizedSize_N, Mapping[Tuple[MemberId, AxisId], v0_5.ParameterizedSize_N]]] = None, batch_size: Optional[int] = None) -> Tuple[int, Iterable[IntermediatePrediction]]

Predict sample by predicting sample blocks and yield intermediate predictions if no samplewise postprocessing is included. Also yields intermediate predictions if there are preceding prediction pipelines (model inputs depend on another model's outputs). For preceding prediction pipelines ns and batch_size are shared, but pre- and postprocessing are never skipped in preceding pipelines.

Returns:

Type Description
Tuple[int, Iterable[IntermediatePrediction]]

Tuple of number of prediction steps and an iterator of predicted intermediate samples with the last predicted block, All samples, but the last one, are intermediate samples with more and more blocks predicted. In case samplewise postprocessing needs to be applied, no intermediate results are yielded, but only the final sample after all blocks are predicted and postprocessed. In case of preceding prediction pipelines (model inputs depend on another model's outputs), intermediate results initially do not include the final output tensors at all.

Source code in src/bioimageio/core/_prediction_pipeline.py
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
def predict_sample_with_blocking_yield_intermediates(
    self,
    sample: Sample,
    skip_preprocessing: bool = False,
    skip_postprocessing: bool = False,
    ns: Optional[
        Union[
            v0_5.ParameterizedSize_N,
            Mapping[Tuple[MemberId, AxisId], v0_5.ParameterizedSize_N],
        ]
    ] = None,
    batch_size: Optional[int] = None,
) -> Tuple[int, Iterable[IntermediatePrediction]]:
    """Predict `sample` by predicting sample blocks and yield intermediate predictions if no samplewise postprocessing is included.
    Also yields intermediate predictions if there are preceding prediction pipelines (model inputs depend on another model's outputs).
    For preceding prediction pipelines `ns` and `batch_size` are shared, but pre- and postprocessing are never skipped in preceding pipelines.

    Returns:
        Tuple of number of prediction steps and an iterator of predicted intermediate samples with the last predicted block,
        All samples, but the last one, are intermediate samples with more and more blocks predicted.
        In case samplewise postprocessing needs to be applied, no intermediate results are yielded, but only the final sample after all blocks are predicted and postprocessed.
        In case of preceding prediction pipelines (model inputs depend on another model's outputs), intermediate results initially do not include the final output tensors at all.
    """

    total_prediction_steps = 0
    iterable_intermediates = ()
    for pp in self._get_preceding_prediction_pipelines_for_sample(sample):
        pp_steps, pp_intermediates = (
            pp.predict_sample_with_blocking_yield_intermediates(
                sample,
                ns=ns,
                batch_size=batch_size,
                skip_preprocessing=False,
                skip_postprocessing=False,
            )
        )
        total_prediction_steps += pp_steps
        iterable_intermediates = chain(iterable_intermediates, pp_intermediates)

    if isinstance(self._model_descr, v0_4.ModelDescr):
        raise NotImplementedError(
            "`predict_sample_with_blocking` not implemented for v0_4.ModelDescr"
            + f" {self._model_descr.name}."
            + " Consider using `predict_sample_with_fixed_blocking`"
        )

    ns = ns or self._default_blocksize_parameter
    if isinstance(ns, int):
        ns = {
            (ipt.id, a.id): ns
            for ipt in self._model_descr.inputs
            for a in ipt.axes
            if isinstance(a.size, v0_5.ParameterizedSize)
        }
    input_block_shape = self._model_descr.get_tensor_sizes(
        ns, batch_size or self._default_batch_size
    ).inputs

    steps, intermediates = (
        self._predict_sample_with_fixed_blocking_yield_intermediates_impl(
            sample,
            input_block_shape=input_block_shape,
            skip_preprocessing=skip_preprocessing,
            skip_postprocessing=skip_postprocessing,
        )
    )
    total_prediction_steps += steps
    iterable_intermediates = chain(iterable_intermediates, intermediates)
    return total_prediction_steps, iterable_intermediates

predict_sample_with_fixed_blocking ¤

predict_sample_with_fixed_blocking(sample: Sample, input_block_shape: PerMember[PerAxis[int]], skip_preprocessing: bool = False, skip_postprocessing: bool = False) -> Sample

Predict sample with given input_block_shape.

Note
  • input_block_shape is expected to be a valid input shape for the model.
  • Use predict_sample_with_blocking if you want to control block sizes via generic block size parameters rather than fixed block shapes.

Parameters:

Name Type Description Default

sample ¤

Sample

The sample to predict on.

required

input_block_shape ¤

PerMember[PerAxis[int]]

Mapping of input member id to mapping of axis id to block size for that axis.

required

skip_preprocessing ¤

bool

If True, skip all preprocessing steps.

False

skip_postprocessing ¤

bool

If True, skip all postprocessing steps.

False
Source code in src/bioimageio/core/_prediction_pipeline.py
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
def predict_sample_with_fixed_blocking(
    self,
    sample: Sample,
    input_block_shape: PerMember[PerAxis[int]],
    skip_preprocessing: bool = False,
    skip_postprocessing: bool = False,
) -> Sample:
    """Predict `sample` with given `input_block_shape`.

    Note:
        - `input_block_shape` is expected to be a valid input shape for the model.
        - Use `predict_sample_with_blocking` if you want to control block sizes via generic block size parameters rather than fixed block shapes.

    Args:
        sample: The sample to predict on.
        input_block_shape: Mapping of input member id to mapping of axis id to block size for that axis.
        skip_preprocessing: If `True`, skip all preprocessing steps.
        skip_postprocessing: If `True`, skip all postprocessing steps.
    """
    intermediate = None
    for (
        intermediate
    ) in self._predict_sample_with_fixed_blocking_yield_intermediates_impl(
        sample,
        input_block_shape=input_block_shape,
        skip_preprocessing=skip_preprocessing,
        skip_postprocessing=skip_postprocessing,
    )[1]:
        pass

    assert intermediate is not None, (
        "No blocks were predicted, cannot return final sample."
    )
    return intermediate.sample

predict_sample_with_fixed_blocking_yield_intermediates ¤

predict_sample_with_fixed_blocking_yield_intermediates(sample: Sample, input_block_shape: PerMember[PerAxis[int]], *, skip_preprocessing: bool = False, skip_postprocessing: bool = False, fill_value: float = float('nan')) -> Tuple[int, Iterable[IntermediatePrediction]]

Predict sample by predicting sample blocks of input_block_shape and yield intermediate predictions if no samplewise postprocessing is included. Also yields intermediate predictions if there are preceding prediction pipelines (model inputs depend on another model's outputs). For preceding prediction pipelines input_block_shape and fill_value are shared, but pre- and postprocessing are never skipped in preceding pipelines.

Returns:

Type Description
Tuple[int, Iterable[IntermediatePrediction]]

Tuple of number of prediction steps and an iterator of predicted intermediate samples with the last predicted block, All samples, but the last one, are intermediate samples with more and more blocks predicted. In case samplewise postprocessing needs to be applied, no intermediate results are yielded, but only the final sample after all blocks are predicted and postprocessed. In case of preceding prediction pipelines (model inputs depend on another model's outputs), intermediate results initially do not include the final output tensors at all.

Source code in src/bioimageio/core/_prediction_pipeline.py
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
def predict_sample_with_fixed_blocking_yield_intermediates(
    self,
    sample: Sample,
    input_block_shape: PerMember[PerAxis[int]],
    *,
    skip_preprocessing: bool = False,
    skip_postprocessing: bool = False,
    fill_value: float = float("nan"),
) -> Tuple[int, Iterable[IntermediatePrediction]]:
    """Predict `sample` by predicting sample blocks of `input_block_shape` and yield intermediate predictions if no samplewise postprocessing is included.
    Also yields intermediate predictions if there are preceding prediction pipelines (model inputs depend on another model's outputs).
    For preceding prediction pipelines `input_block_shape` and `fill_value` are shared, but pre- and postprocessing are never skipped in preceding pipelines.

    Returns:
        Tuple of number of prediction steps and an iterator of predicted intermediate samples with the last predicted block,
        All samples, but the last one, are intermediate samples with more and more blocks predicted.
        In case samplewise postprocessing needs to be applied, no intermediate results are yielded, but only the final sample after all blocks are predicted and postprocessed.
        In case of preceding prediction pipelines (model inputs depend on another model's outputs), intermediate results initially do not include the final output tensors at all.
    """
    total_prediction_steps = 0
    iterable_intermediates = ()
    for pp in self._get_preceding_prediction_pipelines_for_sample(sample):
        pp_steps, pp_intermediates = (
            pp._predict_sample_with_fixed_blocking_yield_intermediates_impl(
                sample,
                input_block_shape=input_block_shape,
                skip_preprocessing=False,
                skip_postprocessing=False,
                fill_value=fill_value,
            )
        )
        total_prediction_steps += pp_steps
        iterable_intermediates = chain(iterable_intermediates, pp_intermediates)

    pp_steps, pp_intermediates = (
        self._predict_sample_with_fixed_blocking_yield_intermediates_impl(
            sample,
            input_block_shape=input_block_shape,
            skip_preprocessing=skip_preprocessing,
            skip_postprocessing=skip_postprocessing,
            fill_value=fill_value,
        )
    )
    total_prediction_steps += pp_steps
    iterable_intermediates = chain(iterable_intermediates, pp_intermediates)
    return total_prediction_steps, iterable_intermediates

predict_sample_without_blocking ¤

predict_sample_without_blocking(sample: Sample, skip_preprocessing: bool = False, skip_postprocessing: bool = False, skip_input_padding: bool = False, skip_output_cropping: bool = False) -> Sample

Predict a whole sample at once.

Note

The sample's tensor shapes have to match the model's input tensor description. If that is not the case, consider predict_sample_with_blocking

Parameters:

Name Type Description Default

sample ¤

Sample

input sample

required

skip_preprocessing ¤

bool

if True, skip all preprocessing steps (except for any preceding prediction pipeline).

False

skip_postprocessing ¤

bool

if True, skip all postprocessing steps (except for any preceding prediction pipeline).

False

skip_input_padding ¤

bool

if True, skip padding the input sample according to the model's (optional) output halos.

False

skip_output_cropping ¤

bool

if True, skip cropping any output halos from the model output.

False
Source code in src/bioimageio/core/_prediction_pipeline.py
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
def predict_sample_without_blocking(
    self,
    sample: Sample,
    skip_preprocessing: bool = False,
    skip_postprocessing: bool = False,
    skip_input_padding: bool = False,
    skip_output_cropping: bool = False,
) -> Sample:
    """Predict a whole sample at once.

    Note:
        The sample's tensor shapes have to match the model's input tensor description.
        If that is not the case, consider `predict_sample_with_blocking`

    Args:
        sample: input sample
        skip_preprocessing: if `True`, skip all preprocessing steps (except for any preceding prediction pipeline).
        skip_postprocessing: if `True`, skip all postprocessing steps (except for any preceding prediction pipeline).
        skip_input_padding: if `True`, skip padding the input sample according to the model's (optional) output halos.
        skip_output_cropping: if `True`, skip cropping any output halos from the model output.
    """
    for pp in self._get_preceding_prediction_pipelines_for_sample(sample):
        sample = pp._predict_sample_without_blocking_impl(
            sample,
            skip_input_padding=skip_input_padding,
            skip_output_cropping=skip_output_cropping,
        )

    return self._predict_sample_without_blocking_impl(
        sample,
        skip_preprocessing=skip_preprocessing,
        skip_postprocessing=skip_postprocessing,
        skip_input_padding=skip_input_padding,
        skip_output_cropping=skip_output_cropping,
    )

raise_for_non_blockwise_postprocessing ¤

raise_for_non_blockwise_postprocessing()

Raises:

Type Description
NotImplementedError

if there are any non-blockwise postprocessing operators in the pipeline

Source code in src/bioimageio/core/_prediction_pipeline.py
537
538
539
540
541
542
def raise_for_non_blockwise_postprocessing(self):
    """
    Raises:
        NotImplementedError: if there are any non-blockwise postprocessing operators in the pipeline
    """
    self._raise_for_non_blockwise_processing("postprocessing")

raise_for_non_blockwise_preprocessing ¤

raise_for_non_blockwise_preprocessing()

Raises:

Type Description
NotImplementedError

if there are any non-blockwise preprocessing operators in the pipeline

Source code in src/bioimageio/core/_prediction_pipeline.py
530
531
532
533
534
535
def raise_for_non_blockwise_preprocessing(self):
    """
    Raises:
        NotImplementedError: if there are any non-blockwise preprocessing operators in the pipeline
    """
    self._raise_for_non_blockwise_processing("preprocessing")

unload ¤

unload()

Free any device memory in use.

Note

Currently prediction pipeline becomes unusable after unloading.

Source code in src/bioimageio/core/_prediction_pipeline.py
798
799
800
801
802
803
def unload(self):
    """Free any device memory in use.

    Note:
        Currently prediction pipeline becomes unusable after unloading."""
    self._adapter.unload()

RemotePredictionPipeline ¤

RemotePredictionPipeline(model_descr: AnyModelDescr, *, server: str, default_blocksize_parameter: BlocksizeParameter, default_batch_size: int, preceding_prediction_pipelines: Optional[Sequence[Union[PredictionPipeline, RemotePredictionPipeline]]] = None)

Bases: _PredictionPipelineBase


              flowchart TD
              bioimageio.core.RemotePredictionPipeline[RemotePredictionPipeline]
              bioimageio.core._prediction_pipeline._PredictionPipelineBase[_PredictionPipelineBase]

                              bioimageio.core._prediction_pipeline._PredictionPipelineBase --> bioimageio.core.RemotePredictionPipeline
                


              click bioimageio.core.RemotePredictionPipeline href "" "bioimageio.core.RemotePredictionPipeline"
              click bioimageio.core._prediction_pipeline._PredictionPipelineBase href "" "bioimageio.core._prediction_pipeline._PredictionPipelineBase"
            

Abstract base class for fully remote prediction pipelines.

A ("local") PredictionPipeline may also use a RemoteModelAdapter for remote model inference, but it may

still apply local preprocessing and postprocessing steps. In contrast, a RemotePredictionPipeline is designed for the case where all steps including preprocessing and postprocessing are performed remotely.

Methods:

Name Description
predict_sample_block

Predict a single sample block.

predict_sample_with_blocking

Predict a sample by predicting sample blocks.

predict_sample_with_blocking_yield_intermediates

Predict sample by predicting sample blocks and yield intermediate predictions if no samplewise postprocessing is included.

predict_sample_with_fixed_blocking

Predict sample with given input_block_shape.

predict_sample_with_fixed_blocking_yield_intermediates

Predict sample by predicting sample blocks of input_block_shape and yield intermediate predictions if no samplewise postprocessing is included.

predict_sample_without_blocking

Predict a whole sample at once.

Attributes:

Name Type Description
input_ids Sequence[MemberId]
model_descr AnyModelDescr
model_description AnyModelDescr
output_ids Sequence[MemberId]
pad_mode
server str
Source code in src/bioimageio/core/_prediction_pipeline.py
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
def __init__(
    self,
    model_descr: AnyModelDescr,
    *,
    server: str,
    default_blocksize_parameter: BlocksizeParameter,
    default_batch_size: int,
    preceding_prediction_pipelines: Optional[
        Sequence[Union["PredictionPipeline", "RemotePredictionPipeline"]]
    ] = None,
) -> None:
    super().__init__(
        model_descr,
        default_blocksize_parameter=default_blocksize_parameter,
        default_batch_size=default_batch_size,
        preceding_prediction_pipelines=preceding_prediction_pipelines,
    )
    self._server = server

input_ids property ¤

input_ids: Sequence[MemberId]

model_descr property ¤

model_descr: AnyModelDescr

model_description property ¤

model_description: AnyModelDescr

output_ids property ¤

output_ids: Sequence[MemberId]

pad_mode instance-attribute ¤

pad_mode = {} if isinstance(model_descr, v0_4.ModelDescr) else {(descr.id): (descr.pad or v0_5.SymmetricPadding()) for descr in (model_descr.inputs)}

server property ¤

server: str

predict_sample_block abstractmethod ¤

predict_sample_block(sample_block: SampleBlock, skip_preprocessing: bool = False, skip_postprocessing: bool = False) -> SampleBlock

Predict a single sample block.

Note that this does not apply samplewise preprocessing or postprocessing steps, but only blockwise ones.

Parameters:

Name Type Description Default

sample_block ¤

SampleBlock

The sample block to predict on.

required

skip_preprocessing ¤

bool

If True, skip blockwise preprocessing steps.

False

skip_postprocessing ¤

bool

If True, skip blockwise postprocessing steps.

False
Source code in src/bioimageio/core/_prediction_pipeline.py
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
@abstractmethod
def predict_sample_block(
    self,
    sample_block: SampleBlock,
    skip_preprocessing: bool = False,
    skip_postprocessing: bool = False,
) -> SampleBlock:
    """Predict a single sample block.

    Note that this does not apply samplewise preprocessing or postprocessing steps, but only blockwise ones.

    Args:
        sample_block: The sample block to predict on.
        skip_preprocessing: If `True`, skip blockwise preprocessing steps.
        skip_postprocessing: If `True`, skip blockwise postprocessing steps.
    """

predict_sample_with_blocking ¤

predict_sample_with_blocking(sample: Sample, skip_preprocessing: bool = False, skip_postprocessing: bool = False, ns: Optional[Union[v0_5.ParameterizedSize_N, Mapping[Tuple[MemberId, AxisId], v0_5.ParameterizedSize_N]]] = None, batch_size: Optional[int] = None) -> Sample

Predict a sample by predicting sample blocks.

Note: For fixed/known blocksizes use predict_sample_with_fixed_blocking.

Parameters:

Name Type Description Default

sample ¤

Sample

The sample to predict on.

required

skip_preprocessing ¤

bool

If True, skip all preprocessing steps.

False

skip_postprocessing ¤

bool

If True, skip all postprocessing steps.

False

ns ¤

Optional[Union[v0_5.ParameterizedSize_N, Mapping[Tuple[MemberId, AxisId], v0_5.ParameterizedSize_N]]]

Block size parameter(s) allows scaling the model's default input block size. Blocksize parameters are only applied to parameterized input axes, all other axis sizes are fixed/derived or (for output axes) data dependent. Unapplicable blocksize parameters are ignored.

None

batch_size ¤

Optional[int]

Batch size to use for prediction.

None
Source code in src/bioimageio/core/_prediction_pipeline.py
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
def predict_sample_with_blocking(
    self,
    sample: Sample,
    skip_preprocessing: bool = False,
    skip_postprocessing: bool = False,
    ns: Optional[
        Union[
            v0_5.ParameterizedSize_N,
            Mapping[Tuple[MemberId, AxisId], v0_5.ParameterizedSize_N],
        ]
    ] = None,
    batch_size: Optional[int] = None,
) -> Sample:
    """Predict a sample by predicting sample blocks.

    Note: For fixed/known blocksizes use `predict_sample_with_fixed_blocking`.

    Args:
        sample: The sample to predict on.
        skip_preprocessing: If `True`, skip all preprocessing steps.
        skip_postprocessing: If `True`, skip all postprocessing steps.
        ns: Block size parameter(s) allows scaling the model's default input block size.
          Blocksize parameters are only applied to parameterized input axes, all other axis sizes are fixed/derived or (for output axes) data dependent.
          Unapplicable blocksize parameters are ignored.
        batch_size: Batch size to use for prediction.
    """

    output = None
    for output in self.predict_sample_with_blocking_yield_intermediates(
        sample,
        skip_preprocessing=skip_preprocessing,
        skip_postprocessing=skip_postprocessing,
        ns=ns,
        batch_size=batch_size,
    )[1]:
        pass

    assert output is not None, (
        "No blocks were predicted, cannot return final sample."
    )
    return output.sample

predict_sample_with_blocking_yield_intermediates ¤

predict_sample_with_blocking_yield_intermediates(sample: Sample, skip_preprocessing: bool = False, skip_postprocessing: bool = False, ns: Optional[Union[v0_5.ParameterizedSize_N, Mapping[Tuple[MemberId, AxisId], v0_5.ParameterizedSize_N]]] = None, batch_size: Optional[int] = None) -> Tuple[int, Iterable[IntermediatePrediction]]

Predict sample by predicting sample blocks and yield intermediate predictions if no samplewise postprocessing is included. Also yields intermediate predictions if there are preceding prediction pipelines (model inputs depend on another model's outputs). For preceding prediction pipelines ns and batch_size are shared, but pre- and postprocessing are never skipped in preceding pipelines.

Returns:

Type Description
Tuple[int, Iterable[IntermediatePrediction]]

Tuple of number of prediction steps and an iterator of predicted intermediate samples with the last predicted block, All samples, but the last one, are intermediate samples with more and more blocks predicted. In case samplewise postprocessing needs to be applied, no intermediate results are yielded, but only the final sample after all blocks are predicted and postprocessed. In case of preceding prediction pipelines (model inputs depend on another model's outputs), intermediate results initially do not include the final output tensors at all.

Source code in src/bioimageio/core/_prediction_pipeline.py
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
def predict_sample_with_blocking_yield_intermediates(
    self,
    sample: Sample,
    skip_preprocessing: bool = False,
    skip_postprocessing: bool = False,
    ns: Optional[
        Union[
            v0_5.ParameterizedSize_N,
            Mapping[Tuple[MemberId, AxisId], v0_5.ParameterizedSize_N],
        ]
    ] = None,
    batch_size: Optional[int] = None,
) -> Tuple[int, Iterable[IntermediatePrediction]]:
    """Predict `sample` by predicting sample blocks and yield intermediate predictions if no samplewise postprocessing is included.
    Also yields intermediate predictions if there are preceding prediction pipelines (model inputs depend on another model's outputs).
    For preceding prediction pipelines `ns` and `batch_size` are shared, but pre- and postprocessing are never skipped in preceding pipelines.

    Returns:
        Tuple of number of prediction steps and an iterator of predicted intermediate samples with the last predicted block,
        All samples, but the last one, are intermediate samples with more and more blocks predicted.
        In case samplewise postprocessing needs to be applied, no intermediate results are yielded, but only the final sample after all blocks are predicted and postprocessed.
        In case of preceding prediction pipelines (model inputs depend on another model's outputs), intermediate results initially do not include the final output tensors at all.
    """

    total_prediction_steps = 0
    iterable_intermediates = ()
    for pp in self._get_preceding_prediction_pipelines_for_sample(sample):
        pp_steps, pp_intermediates = (
            pp.predict_sample_with_blocking_yield_intermediates(
                sample,
                ns=ns,
                batch_size=batch_size,
                skip_preprocessing=False,
                skip_postprocessing=False,
            )
        )
        total_prediction_steps += pp_steps
        iterable_intermediates = chain(iterable_intermediates, pp_intermediates)

    if isinstance(self._model_descr, v0_4.ModelDescr):
        raise NotImplementedError(
            "`predict_sample_with_blocking` not implemented for v0_4.ModelDescr"
            + f" {self._model_descr.name}."
            + " Consider using `predict_sample_with_fixed_blocking`"
        )

    ns = ns or self._default_blocksize_parameter
    if isinstance(ns, int):
        ns = {
            (ipt.id, a.id): ns
            for ipt in self._model_descr.inputs
            for a in ipt.axes
            if isinstance(a.size, v0_5.ParameterizedSize)
        }
    input_block_shape = self._model_descr.get_tensor_sizes(
        ns, batch_size or self._default_batch_size
    ).inputs

    steps, intermediates = (
        self._predict_sample_with_fixed_blocking_yield_intermediates_impl(
            sample,
            input_block_shape=input_block_shape,
            skip_preprocessing=skip_preprocessing,
            skip_postprocessing=skip_postprocessing,
        )
    )
    total_prediction_steps += steps
    iterable_intermediates = chain(iterable_intermediates, intermediates)
    return total_prediction_steps, iterable_intermediates

predict_sample_with_fixed_blocking ¤

predict_sample_with_fixed_blocking(sample: Sample, input_block_shape: PerMember[PerAxis[int]], skip_preprocessing: bool = False, skip_postprocessing: bool = False) -> Sample

Predict sample with given input_block_shape.

Note
  • input_block_shape is expected to be a valid input shape for the model.
  • Use predict_sample_with_blocking if you want to control block sizes via generic block size parameters rather than fixed block shapes.

Parameters:

Name Type Description Default

sample ¤

Sample

The sample to predict on.

required

input_block_shape ¤

PerMember[PerAxis[int]]

Mapping of input member id to mapping of axis id to block size for that axis.

required

skip_preprocessing ¤

bool

If True, skip all preprocessing steps.

False

skip_postprocessing ¤

bool

If True, skip all postprocessing steps.

False
Source code in src/bioimageio/core/_prediction_pipeline.py
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
def predict_sample_with_fixed_blocking(
    self,
    sample: Sample,
    input_block_shape: PerMember[PerAxis[int]],
    skip_preprocessing: bool = False,
    skip_postprocessing: bool = False,
) -> Sample:
    """Predict `sample` with given `input_block_shape`.

    Note:
        - `input_block_shape` is expected to be a valid input shape for the model.
        - Use `predict_sample_with_blocking` if you want to control block sizes via generic block size parameters rather than fixed block shapes.

    Args:
        sample: The sample to predict on.
        input_block_shape: Mapping of input member id to mapping of axis id to block size for that axis.
        skip_preprocessing: If `True`, skip all preprocessing steps.
        skip_postprocessing: If `True`, skip all postprocessing steps.
    """
    intermediate = None
    for (
        intermediate
    ) in self._predict_sample_with_fixed_blocking_yield_intermediates_impl(
        sample,
        input_block_shape=input_block_shape,
        skip_preprocessing=skip_preprocessing,
        skip_postprocessing=skip_postprocessing,
    )[1]:
        pass

    assert intermediate is not None, (
        "No blocks were predicted, cannot return final sample."
    )
    return intermediate.sample

predict_sample_with_fixed_blocking_yield_intermediates ¤

predict_sample_with_fixed_blocking_yield_intermediates(sample: Sample, input_block_shape: PerMember[PerAxis[int]], *, skip_preprocessing: bool = False, skip_postprocessing: bool = False, fill_value: float = float('nan')) -> Tuple[int, Iterable[IntermediatePrediction]]

Predict sample by predicting sample blocks of input_block_shape and yield intermediate predictions if no samplewise postprocessing is included. Also yields intermediate predictions if there are preceding prediction pipelines (model inputs depend on another model's outputs). For preceding prediction pipelines input_block_shape and fill_value are shared, but pre- and postprocessing are never skipped in preceding pipelines.

Returns:

Type Description
Tuple[int, Iterable[IntermediatePrediction]]

Tuple of number of prediction steps and an iterator of predicted intermediate samples with the last predicted block, All samples, but the last one, are intermediate samples with more and more blocks predicted. In case samplewise postprocessing needs to be applied, no intermediate results are yielded, but only the final sample after all blocks are predicted and postprocessed. In case of preceding prediction pipelines (model inputs depend on another model's outputs), intermediate results initially do not include the final output tensors at all.

Source code in src/bioimageio/core/_prediction_pipeline.py
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
def predict_sample_with_fixed_blocking_yield_intermediates(
    self,
    sample: Sample,
    input_block_shape: PerMember[PerAxis[int]],
    *,
    skip_preprocessing: bool = False,
    skip_postprocessing: bool = False,
    fill_value: float = float("nan"),
) -> Tuple[int, Iterable[IntermediatePrediction]]:
    """Predict `sample` by predicting sample blocks of `input_block_shape` and yield intermediate predictions if no samplewise postprocessing is included.
    Also yields intermediate predictions if there are preceding prediction pipelines (model inputs depend on another model's outputs).
    For preceding prediction pipelines `input_block_shape` and `fill_value` are shared, but pre- and postprocessing are never skipped in preceding pipelines.

    Returns:
        Tuple of number of prediction steps and an iterator of predicted intermediate samples with the last predicted block,
        All samples, but the last one, are intermediate samples with more and more blocks predicted.
        In case samplewise postprocessing needs to be applied, no intermediate results are yielded, but only the final sample after all blocks are predicted and postprocessed.
        In case of preceding prediction pipelines (model inputs depend on another model's outputs), intermediate results initially do not include the final output tensors at all.
    """
    total_prediction_steps = 0
    iterable_intermediates = ()
    for pp in self._get_preceding_prediction_pipelines_for_sample(sample):
        pp_steps, pp_intermediates = (
            pp._predict_sample_with_fixed_blocking_yield_intermediates_impl(
                sample,
                input_block_shape=input_block_shape,
                skip_preprocessing=False,
                skip_postprocessing=False,
                fill_value=fill_value,
            )
        )
        total_prediction_steps += pp_steps
        iterable_intermediates = chain(iterable_intermediates, pp_intermediates)

    pp_steps, pp_intermediates = (
        self._predict_sample_with_fixed_blocking_yield_intermediates_impl(
            sample,
            input_block_shape=input_block_shape,
            skip_preprocessing=skip_preprocessing,
            skip_postprocessing=skip_postprocessing,
            fill_value=fill_value,
        )
    )
    total_prediction_steps += pp_steps
    iterable_intermediates = chain(iterable_intermediates, pp_intermediates)
    return total_prediction_steps, iterable_intermediates

predict_sample_without_blocking ¤

predict_sample_without_blocking(sample: Sample, skip_preprocessing: bool = False, skip_postprocessing: bool = False, skip_input_padding: bool = False, skip_output_cropping: bool = False) -> Sample

Predict a whole sample at once.

Note

The sample's tensor shapes have to match the model's input tensor description. If that is not the case, consider predict_sample_with_blocking

Parameters:

Name Type Description Default

sample ¤

Sample

input sample

required

skip_preprocessing ¤

bool

if True, skip all preprocessing steps (except for any preceding prediction pipeline).

False

skip_postprocessing ¤

bool

if True, skip all postprocessing steps (except for any preceding prediction pipeline).

False

skip_input_padding ¤

bool

if True, skip padding the input sample according to the model's (optional) output halos.

False

skip_output_cropping ¤

bool

if True, skip cropping any output halos from the model output.

False
Source code in src/bioimageio/core/_prediction_pipeline.py
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
def predict_sample_without_blocking(
    self,
    sample: Sample,
    skip_preprocessing: bool = False,
    skip_postprocessing: bool = False,
    skip_input_padding: bool = False,
    skip_output_cropping: bool = False,
) -> Sample:
    """Predict a whole sample at once.

    Note:
        The sample's tensor shapes have to match the model's input tensor description.
        If that is not the case, consider `predict_sample_with_blocking`

    Args:
        sample: input sample
        skip_preprocessing: if `True`, skip all preprocessing steps (except for any preceding prediction pipeline).
        skip_postprocessing: if `True`, skip all postprocessing steps (except for any preceding prediction pipeline).
        skip_input_padding: if `True`, skip padding the input sample according to the model's (optional) output halos.
        skip_output_cropping: if `True`, skip cropping any output halos from the model output.
    """
    for pp in self._get_preceding_prediction_pipelines_for_sample(sample):
        sample = pp._predict_sample_without_blocking_impl(
            sample,
            skip_input_padding=skip_input_padding,
            skip_output_cropping=skip_output_cropping,
        )

    return self._predict_sample_without_blocking_impl(
        sample,
        skip_preprocessing=skip_preprocessing,
        skip_postprocessing=skip_postprocessing,
        skip_input_padding=skip_input_padding,
        skip_output_cropping=skip_output_cropping,
    )

Sample dataclass ¤

Sample(members: Dict[MemberId, Tensor], stat: Stat, id: SampleId)

A dataset sample.

A Sample has members, which allows to combine multiple tensors into a single sample. For example a Sample from a dataset with masked images may contain a MemberId("raw") and MemberId("mask") image.

Methods:

Name Description
__getitem__
as_arrays

Return sample as dictionary of arrays.

as_single_block
assign_batch_multi_index

Return a new sample with the batch multi-index assigned to all sample members.

from_blocks

Create a Sample from an iterable of SampleBlocks.

from_blocks_yield_intermediates

Create a Sample from an iterable of SampleBlocks, yielding the intermediate sample after each block.

pad

Convenience method to pad sample members.

set_block

Set values of block.

split_into_blocks
transpose

Return a new sample with transposed sample members.

unstack_batch_multi_index

Unstack the batch multi-index of all sample members.

Attributes:

Name Type Description
batch_multi_index Optional['pd.MultiIndex']

Return the batch multi-index of the sample, if it has one.

id SampleId

Identifies the Sample within the dataset -- typically a number or a string.

members Dict[MemberId, Tensor]

The sample's tensors

shape PerMember[PerAxis[int]]
stat Stat

Sample and dataset statistics

batch_multi_index property ¤

batch_multi_index: Optional['pd.MultiIndex']

Return the batch multi-index of the sample, if it has one.

Returns:

Type Description
Optional['pd.MultiIndex']

The batch multi-index of the sample, or None if the sample does not have a batch dimension.

id instance-attribute ¤

Identifies the Sample within the dataset -- typically a number or a string.

members instance-attribute ¤

members: Dict[MemberId, Tensor]

The sample's tensors

shape property ¤

shape: PerMember[PerAxis[int]]

stat instance-attribute ¤

stat: Stat

Sample and dataset statistics

__getitem__ ¤

__getitem__(key: PerMember[Union[SliceInfo, slice, int, PerAxis[Union[SliceInfo, slice, int]], Tensor, xr.DataArray]]) -> Self
Source code in src/bioimageio/core/sample.py
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
def __getitem__(
    self,
    key: PerMember[
        Union[
            SliceInfo,
            slice,
            int,
            PerAxis[Union[SliceInfo, slice, int]],
            Tensor,
            xr.DataArray,
        ]
    ],
) -> Self:
    return self.__class__(
        members={m: t[key[m]] for m, t in self.members.items() if m in key},
        stat=self.stat,
        id=self.id,
    )

as_arrays ¤

as_arrays() -> Dict[MemberId, NDArray[Any]]

Return sample as dictionary of arrays.

Source code in src/bioimageio/core/sample.py
137
138
139
def as_arrays(self) -> Dict[MemberId, NDArray[Any]]:
    """Return sample as dictionary of arrays."""
    return {m: t.to_numpy() for m, t in self.members.items()}

as_single_block ¤

as_single_block(halo: Optional[PerMember[PerAxis[Halo]]] = None)
Source code in src/bioimageio/core/sample.py
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
def as_single_block(self, halo: Optional[PerMember[PerAxis[Halo]]] = None):
    if halo is None:
        halo = {}
    return SampleBlockWithOrigin(
        sample_shape=self.shape,
        sample_id=self.id,
        blocks={
            m: Block(
                sample_shape=self.shape[m],
                data=data,
                inner_slice={
                    a: SliceInfo(0, s) for a, s in data.tagged_shape.items()
                },
                halo=halo.get(m, {}),
                block_index=0,
                blocks_in_sample=1,
            )
            for m, data in self.members.items()
        },
        stat=self.stat,
        origin=self,
        block_index=0,
        blocks_in_sample=1,
    )

assign_batch_multi_index ¤

assign_batch_multi_index(multi_index: 'pd.MultiIndex') -> Self

Return a new sample with the batch multi-index assigned to all sample members.

Raises:

Type Description
ValueError

If not all sample members have a batch dimension.

Source code in src/bioimageio/core/sample.py
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
def assign_batch_multi_index(self, multi_index: "pd.MultiIndex") -> Self:
    """Return a new sample with the batch multi-index assigned to all sample members.

    Raises:
        ValueError: If not all sample members have a batch dimension.
    """
    if len(
        no_batch := [
            m for m, t in self.members.items() if AxisId("batch") not in t.dims
        ]
    ) == len(self.members):
        raise ValueError(f"No member has a batch dimension: {no_batch}")

    return self.__class__(
        members={
            m: t
            if AxisId("batch") not in t.dims
            else t.assign_batch_multi_index(multi_index)
            for m, t in self.members.items()
        },
        stat=dict(self.stat),
        id=self.id,
    )

from_blocks classmethod ¤

from_blocks(sample_blocks: Iterable[SampleBlock], *, fill_value: float = float('nan')) -> Self

Create a Sample from an iterable of SampleBlocks.

Note

All sample blocks must have the same sample_id.

Parameters:

Name Type Description Default

sample_blocks ¤

Iterable[SampleBlock]

The blocks to create the sample from.

required

fill_value ¤

float

The value to fill missing values with (default: nan).

float('nan')
Source code in src/bioimageio/core/sample.py
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
@classmethod
def from_blocks(
    cls,
    sample_blocks: Iterable[SampleBlock],
    *,
    fill_value: float = float("nan"),
) -> Self:
    """Create a `Sample` from an iterable of `SampleBlock`s.

    Note:
        All sample blocks must have the same `sample_id`.

    Args:
        sample_blocks: The blocks to create the sample from.
        fill_value: The value to fill missing values with (default: `nan`).
    """
    output = None
    for output in cls.from_blocks_yield_intermediates(
        sample_blocks, fill_value=fill_value
    ):
        pass

    if output is None:
        raise ValueError("no sample blocks provided")

    return output

from_blocks_yield_intermediates classmethod ¤

from_blocks_yield_intermediates(sample_blocks: Iterable[SampleBlock], *, fill_value: float = float('nan'))

Create a Sample from an iterable of SampleBlocks, yielding the intermediate sample after each block.

Parameters:

Name Type Description Default

sample_blocks ¤

Iterable[SampleBlock]

The blocks to create the sample from.

required

fill_value ¤

float

The value to fill missing values with (default: nan).

float('nan')
Source code in src/bioimageio/core/sample.py
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
@classmethod
def from_blocks_yield_intermediates(
    cls,
    sample_blocks: Iterable[SampleBlock],
    *,
    fill_value: float = float("nan"),
):
    """Create a `Sample` from an iterable of `SampleBlock`s, yielding the intermediate sample after each block.

    Args:
        sample_blocks: The blocks to create the sample from.
        fill_value: The value to fill missing values with (default: `nan`).
    """
    output = cls(members={}, stat={}, id=None)
    for sample_block in sample_blocks:
        if output.id is None:
            output.id = sample_block.sample_id
        else:
            assert output.id == sample_block.sample_id, (
                "sample id changed between sample blocks"
            )

        output.stat = sample_block.stat

        for m, block in sample_block.blocks.items():
            if m not in output.members:
                if -1 in block.sample_shape.values():
                    raise NotImplementedError(
                        "merging blocks with data dependent axis not yet implemented"
                    )

                output.members[m] = Tensor(
                    np.full(
                        tuple(block.sample_shape[a] for a in block.data.dims),
                        fill_value,
                        dtype=block.data.dtype,
                    ),
                    dims=block.data.dims,
                )

            output.members[m][block.inner_slice] = block.inner_data
        yield output

    yield output

pad ¤

pad(pad_width: PerMember[PerAxis[Union[int, PadWidthLike]]], mode: Union[PerMember[PadMode], PadMode]) -> Self

Convenience method to pad sample members.

Source code in src/bioimageio/core/sample.py
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
def pad(
    self,
    pad_width: PerMember[PerAxis[Union[int, PadWidthLike]]],
    mode: Union[PerMember[PadMode], PadMode],
) -> Self:
    """Convenience method to pad sample members."""
    default_mode = "symmetric"
    if isinstance(mode, collections.abc.Mapping):
        mode_per_member = mode
    else:
        mode_per_member: Mapping[MemberId, PadMode] = {}
        default_mode = mode

    return self.__class__(
        members={
            m: t.pad(
                pad_width=pad_width.get(m, {}),
                mode=mode_per_member.get(m, default_mode),
            )
            for m, t in self.members.items()
        },
        stat=self.stat,
        id=self.id,
    )

set_block ¤

set_block(block: SampleBlock) -> None

Set values of block.

Note
  • Updates only existing sample members (extra block members are ignored)
  • Ignores missing block members (i.e. members in the sample but not in the block are not modified)
Source code in src/bioimageio/core/sample.py
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
def set_block(self, block: SampleBlock) -> None:
    """Set values of `block`.

    Note:
        - Updates only existing sample members (extra block members are ignored)
        - Ignores missing block members (i.e. members in the sample but not in the block are not modified)

    Raises:
        ValueError if block and sample members do not overlap at all.
    """
    no_overlap = True
    for m in self.members:
        if m not in block.blocks:
            continue
        b = block.blocks[m]
        self.members[m][b.inner_slice] = b.inner_data
        no_overlap = False

    if no_overlap:
        raise ValueError(
            f"block with members {list(block.blocks)} does not overlap with sample members {list(self.members)}"
        )

split_into_blocks ¤

split_into_blocks(block_shapes: PerMember[PerAxis[int]], halo: PerMember[PerAxis[HaloLike]], pad_mode: Union[PadMode, PerMember[PadMode]], broadcast: bool = False) -> Tuple[TotalNumberOfBlocks, Iterable[SampleBlockWithOrigin]]
Source code in src/bioimageio/core/sample.py
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
def split_into_blocks(
    self,
    block_shapes: PerMember[PerAxis[int]],
    halo: PerMember[PerAxis[HaloLike]],
    pad_mode: Union[PadMode, PerMember[PadMode]],
    broadcast: bool = False,
) -> Tuple[TotalNumberOfBlocks, Iterable[SampleBlockWithOrigin]]:
    assert not (missing := [m for m in block_shapes if m not in self.members]), (
        f"`block_shapes` specified for unknown members: {missing}"
    )
    assert not (missing := [m for m in halo if m not in block_shapes]), (
        f"`halo` specified for members without `block_shape`: {missing}"
    )

    n_blocks, blocks = split_multiple_shapes_into_blocks(
        shapes=self.shape,
        block_shapes=block_shapes,
        halo=halo,
        broadcast=broadcast,
    )
    return n_blocks, sample_block_generator(blocks, origin=self, pad_mode=pad_mode)

transpose ¤

transpose(axes: PerMember[Sequence[AxisId]], *, extra_dims: Literal['raise', 'squeeze', 'stack', 'squeeze_or_stack'] = 'raise', missing_dims: Literal['raise', 'expand', 'unstack', 'unstack_or_expand'] = 'raise') -> Self

Return a new sample with transposed sample members.

Raises:

Type Description
ValueError

If not all batch dimensions have the same length after transposition (and possibly stacking/unstacking extra dimensions).

Source code in src/bioimageio/core/sample.py
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
def transpose(
    self,
    axes: PerMember[Sequence[AxisId]],
    *,
    extra_dims: Literal["raise", "squeeze", "stack", "squeeze_or_stack"] = "raise",
    missing_dims: Literal[
        "raise", "expand", "unstack", "unstack_or_expand"
    ] = "raise",
) -> Self:
    """Return a new sample with transposed sample members.

    Raises:
        ValueError: If not all batch dimensions have the same length after transposition (and possibly stacking/unstacking extra dimensions).

    """
    if any((unknown := [m not in self.members for m in axes])):
        raise ValueError(f"Axes specified for unknown members: {unknown}")

    members = {
        m: t
        if m not in axes
        else t.transpose(
            axes=axes[m],
            extra_dims=extra_dims,
            missing_dims=missing_dims,
        )
        for m, t in self.members.items()
    }

    if (
        len(
            (
                batch_lengths := {
                    t.sizes[AxisId("batch")]
                    for t in members.values()
                    if AxisId("batch") in t.dims
                }
            )
        )
        > 1
    ):
        raise ValueError(
            f"Transposed sample members have incompatible batch lengths: {batch_lengths}."
        )

    return self.__class__(members=members, stat=dict(self.stat), id=self.id)

unstack_batch_multi_index ¤

unstack_batch_multi_index(*, errors: Literal['raise', 'ignore'] = 'raise') -> Self

Unstack the batch multi-index of all sample members.

Parameters:

Name Type Description Default

errors ¤

Literal['raise', 'ignore']

Whether to raise an error if a member does not have a batch multi-index. Default is "raise".

'raise'

Returns:

Type Description
Self

A new Sample with unstacked batch multi-index for all members.

Source code in src/bioimageio/core/sample.py
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
def unstack_batch_multi_index(
    self, *, errors: Literal["raise", "ignore"] = "raise"
) -> Self:
    """Unstack the batch multi-index of all sample members.

    Args:
        errors: Whether to raise an error if a member does not have a batch multi-index. Default is "raise".

    Returns:
        A new `Sample` with unstacked batch multi-index for all members.
    """
    if (
        len(
            no_batch := [
                m for m, t in self.members.items() if AxisId("batch") not in t.dims
            ]
        )
        == len(self.members)
        and errors == "raise"
    ):
        raise ValueError(f"No member has a batch dimension: {no_batch}")

    members = {
        m: t
        if AxisId("batch") not in t.dims
        else t.unstack_batch_multi_index(errors=errors)
        for m, t in self.members.items()
    }
    if (
        len(
            batch_lengths := {
                t.sizes.get(AxisId("batch"))
                for t in members.values()
                if AxisId("batch") in t.dims
            }
        )
        > 1
    ):
        raise ValueError(
            f"Different batch lengths after unstacking: {batch_lengths}"
        )

    stat: Stat = {
        k: v.unstack_batch_multi_index(errors="ignore")
        if isinstance(v, Tensor)
        else float(v)
        for k, v in self.stat.items()
    }
    return self.__class__(
        members=members,
        stat=stat,
        id=self.id,
    )

SampleBlock dataclass ¤

SampleBlock(blocks: Dict[MemberId, Block], stat: Stat)

Bases: SampleBlockBase[Block]


              flowchart TD
              bioimageio.core.SampleBlock[SampleBlock]
              bioimageio.core.sample.SampleBlockBase[SampleBlockBase]

                              bioimageio.core.sample.SampleBlockBase --> bioimageio.core.SampleBlock
                


              click bioimageio.core.SampleBlock href "" "bioimageio.core.SampleBlock"
              click bioimageio.core.sample.SampleBlockBase href "" "bioimageio.core.sample.SampleBlockBase"
            

A block of a dataset sample

Methods:

Name Description
as_sample

Convert this sample block to a Sample with the shape of this block.

from_meta
get_meta
get_transformed_meta

Attributes:

Name Type Description
block_index BlockIndex

the n-th block of the sample

blocks Dict[MemberId, Block]

Individual tensor blocks comprising this sample block

blocks_in_sample TotalNumberOfBlocks

total number of blocks in the sample

inner_shape PerMember[PerAxis[int]]
members PerMember[Tensor]

the sample block's tensors

sample_id SampleId

identifier for the sample within its dataset

sample_shape PerMemberAnno[PerAxis[int]]

the sample shape this block represents a part of

shape PerMember[PerAxis[int]]
stat Stat

computed statistics

block_index instance-attribute ¤

block_index: BlockIndex

the n-th block of the sample

blocks instance-attribute ¤

blocks: Dict[MemberId, Block]

Individual tensor blocks comprising this sample block

blocks_in_sample instance-attribute ¤

blocks_in_sample: TotalNumberOfBlocks

total number of blocks in the sample

inner_shape property ¤

inner_shape: PerMember[PerAxis[int]]

members property ¤

members: PerMember[Tensor]

the sample block's tensors

sample_id instance-attribute ¤

sample_id: SampleId

identifier for the sample within its dataset

sample_shape instance-attribute ¤

sample_shape: PerMemberAnno[PerAxis[int]]

the sample shape this block represents a part of

shape property ¤

shape: PerMember[PerAxis[int]]

stat instance-attribute ¤

stat: Stat

computed statistics

as_sample ¤

as_sample() -> Sample

Convert this sample block to a Sample with the shape of this block.

Note

If you want to convert one or more sample block to a sample with the shape of the original, whole sample, use Sample.from_blocks() instead.

Source code in src/bioimageio/core/sample.py
591
592
593
594
595
596
597
598
599
600
601
602
def as_sample(self) -> Sample:
    """Convert this sample block to a `Sample` with the shape of this block.

    Note:
        If you want to convert one or more sample block to a sample with the shape of the original, whole sample,
        use `Sample.from_blocks()` instead.
    """
    return Sample(
        members=dict(self.members),
        stat=dict(self.stat),
        id=self.sample_id,
    )

from_meta classmethod ¤

from_meta(meta: SampleBlockMeta, data: PerMember[Tensor], stat: Stat) -> Self
Source code in src/bioimageio/core/sample.py
567
568
569
570
571
572
573
574
575
576
577
578
579
580
@classmethod
def from_meta(
    cls, meta: SampleBlockMeta, data: PerMember[Tensor], stat: Stat
) -> Self:
    return cls(
        sample_shape=meta.sample_shape,
        sample_id=meta.sample_id,
        blocks={
            m: Block.from_meta(b, data=data[m]) for m, b in meta.blocks.items()
        },
        stat=stat,
        block_index=meta.block_index,
        blocks_in_sample=meta.blocks_in_sample,
    )

get_meta ¤

get_meta() -> SampleBlockMeta
Source code in src/bioimageio/core/sample.py
582
583
584
585
586
587
588
589
def get_meta(self) -> SampleBlockMeta:
    return SampleBlockMeta(
        sample_id=self.sample_id,
        blocks={m: b.get_meta() for m, b in self.blocks.items()},
        sample_shape=self.sample_shape,
        block_index=self.block_index,
        blocks_in_sample=self.blocks_in_sample,
    )

get_transformed_meta ¤

get_transformed_meta(new_axes: PerMember[PerAxis[Union[LinearSampleAxisTransform, int]]]) -> SampleBlockMeta
Source code in src/bioimageio/core/sample.py
556
557
558
559
560
561
562
563
564
565
def get_transformed_meta(
    self, new_axes: PerMember[PerAxis[Union[LinearSampleAxisTransform, int]]]
) -> SampleBlockMeta:
    return SampleBlockMeta(
        sample_id=self.sample_id,
        blocks=dict(self.blocks),
        sample_shape=self.sample_shape,
        block_index=self.block_index,
        blocks_in_sample=self.blocks_in_sample,
    ).get_transformed(new_axes)

SampleBlockMeta ¤

Bases: SampleBlockBase[BlockMeta]


              flowchart TD
              bioimageio.core.SampleBlockMeta[SampleBlockMeta]
              bioimageio.core.sample.SampleBlockBase[SampleBlockBase]

                              bioimageio.core.sample.SampleBlockBase --> bioimageio.core.SampleBlockMeta
                


              click bioimageio.core.SampleBlockMeta href "" "bioimageio.core.SampleBlockMeta"
              click bioimageio.core.sample.SampleBlockBase href "" "bioimageio.core.sample.SampleBlockBase"
            

Meta data of a dataset sample block

Methods:

Name Description
get_transformed
with_data

Attributes:

Name Type Description
block_index BlockIndex

the n-th block of the sample

blocks PerMemberAnno[BlockT]

Individual tensor blocks comprising this sample block

blocks_in_sample TotalNumberOfBlocks

total number of blocks in the sample

inner_shape PerMember[PerAxis[int]]
sample_id SampleId

identifier for the sample within its dataset

sample_shape PerMemberAnno[PerAxis[int]]

the sample shape this block represents a part of

shape PerMember[PerAxis[int]]

block_index instance-attribute ¤

block_index: BlockIndex

the n-th block of the sample

blocks instance-attribute ¤

blocks: PerMemberAnno[BlockT]

Individual tensor blocks comprising this sample block

blocks_in_sample instance-attribute ¤

blocks_in_sample: TotalNumberOfBlocks

total number of blocks in the sample

inner_shape property ¤

inner_shape: PerMember[PerAxis[int]]

sample_id instance-attribute ¤

sample_id: SampleId

identifier for the sample within its dataset

sample_shape instance-attribute ¤

sample_shape: PerMemberAnno[PerAxis[int]]

the sample shape this block represents a part of

shape property ¤

shape: PerMember[PerAxis[int]]

get_transformed ¤

get_transformed(new_axes: PerMember[PerAxis[Union[LinearSampleAxisTransform, int]]]) -> Self
Source code in src/bioimageio/core/sample.py
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
def get_transformed(
    self, new_axes: PerMember[PerAxis[Union[LinearSampleAxisTransform, int]]]
) -> Self:
    sample_shape = {
        m: {
            a: (
                trf
                if isinstance(trf, int)
                else trf.compute(self.sample_shape[trf.member][trf.axis])
            )
            for a, trf in new_axes[m].items()
        }
        for m in new_axes
    }

    def get_member_halo(m: MemberId, round: Callable[[float], int]):
        return {
            a: (
                Halo(0, 0)
                if isinstance(trf, int)
                or trf.axis not in self.blocks[trf.member].halo
                else Halo(
                    round(self.blocks[trf.member].halo[trf.axis].left * trf.scale),
                    round(self.blocks[trf.member].halo[trf.axis].right * trf.scale),
                )
            )
            for a, trf in new_axes[m].items()
        }

    halo: Dict[MemberId, Dict[AxisId, Halo]] = {}
    for m in new_axes:
        halo[m] = get_member_halo(m, floor)
        if halo[m] != get_member_halo(m, ceil):
            raise ValueError(
                f"failed to unambiguously scale halo {halo[m]} with {new_axes[m]}"
                + f" for {m}."
            )

    inner_slice = {
        m: {
            a: (
                SliceInfo(0, trf)
                if isinstance(trf, int)
                else SliceInfo(
                    trf.compute(
                        self.blocks[trf.member].inner_slice[trf.axis].start
                    ),
                    trf.compute(self.blocks[trf.member].inner_slice[trf.axis].stop),
                )
            )
            for a, trf in new_axes[m].items()
        }
        for m in new_axes
    }
    return self.__class__(
        blocks={
            m: BlockMeta(
                sample_shape=sample_shape[m],
                inner_slice=inner_slice[m],
                halo=halo[m],
                block_index=self.block_index,
                blocks_in_sample=self.blocks_in_sample,
            )
            for m in new_axes
        },
        sample_shape=sample_shape,
        sample_id=self.sample_id,
        block_index=self.block_index,
        blocks_in_sample=self.blocks_in_sample,
    )

with_data ¤

with_data(data: PerMember[Tensor], *, stat: Stat) -> SampleBlock
Source code in src/bioimageio/core/sample.py
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
def with_data(self, data: PerMember[Tensor], *, stat: Stat) -> SampleBlock:
    return SampleBlock(
        sample_shape={
            m: {
                a: data[m].tagged_shape[a] if s == -1 else s
                for a, s in member_shape.items()
            }
            for m, member_shape in self.sample_shape.items()
        },
        sample_id=self.sample_id,
        blocks={
            m: Block.from_meta(b, data=data[m]) for m, b in self.blocks.items()
        },
        stat=stat,
        block_index=self.block_index,
        blocks_in_sample=self.blocks_in_sample,
    )

SampleSerializer ¤

Bases: ABC, Generic[SerializedSampleBlockType]


              flowchart TD
              bioimageio.core.SampleSerializer[SampleSerializer]

              

              click bioimageio.core.SampleSerializer href "" "bioimageio.core.SampleSerializer"
            

Methods:

Name Description
deserialize_sample
deserialize_sample_block

Deserialize a sample block into a new sample or merge it into output_sample if provided.

serialize_sample

Serialize a sample as a single block

serialize_sample_block
serialize_sample_blockwise

Split a sample into blocks according to the model's input specifications and blocksize_parameter and serialize each block.

serialize_sample_with_fixed_blocking

deserialize_sample classmethod ¤

deserialize_sample(serialized: Iterable[SerializedSampleBlockType], fill_value: float = float('nan')) -> Sample
Source code in src/bioimageio/core/_sample_serializer.py
29
30
31
32
33
34
35
36
37
@classmethod
def deserialize_sample(
    cls,
    serialized: Iterable[SerializedSampleBlockType],
    fill_value: float = float("nan"),
) -> Sample:
    return Sample.from_blocks(
        (cls.deserialize_sample_block(s) for s in serialized), fill_value=fill_value
    )

deserialize_sample_block abstractmethod staticmethod ¤

deserialize_sample_block(serialized: SerializedSampleBlockType) -> SampleBlock

Deserialize a sample block into a new sample or merge it into output_sample if provided.

Source code in src/bioimageio/core/_sample_serializer.py
82
83
84
85
@staticmethod
@abstractmethod
def deserialize_sample_block(serialized: SerializedSampleBlockType) -> SampleBlock:
    """Deserialize a sample block into a new sample or merge it into `output_sample` if provided."""

serialize_sample classmethod ¤

serialize_sample(sample: Sample) -> Tuple[SerializedSampleBlockType]

Serialize a sample as a single block

Source code in src/bioimageio/core/_sample_serializer.py
21
22
23
24
25
26
27
@classmethod
def serialize_sample(
    cls,
    sample: Sample,
) -> Tuple[SerializedSampleBlockType]:
    """Serialize a sample as a single block"""
    return (cls.serialize_sample_block(sample.as_single_block()),)

serialize_sample_block abstractmethod staticmethod ¤

serialize_sample_block(sample_block: SampleBlock) -> SerializedSampleBlockType
Source code in src/bioimageio/core/_sample_serializer.py
76
77
78
79
80
@staticmethod
@abstractmethod
def serialize_sample_block(
    sample_block: SampleBlock,
) -> SerializedSampleBlockType: ...

serialize_sample_blockwise ¤

serialize_sample_blockwise(sample: Sample, *, model: v0_5.ModelDescr, blocksize_parameter: int, batch_size: int = 1) -> Iterable[SerializedSampleBlockType]

Split a sample into blocks according to the model's input specifications and blocksize_parameter and serialize each block.

Source code in src/bioimageio/core/_sample_serializer.py
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
def serialize_sample_blockwise(
    self,
    sample: Sample,
    *,
    model: v0_5.ModelDescr,
    blocksize_parameter: int,
    batch_size: int = 1,
) -> Iterable[SerializedSampleBlockType]:
    """Split a sample into blocks according to the model's input specifications and `blocksize_parameter` and serialize each block."""

    _n_blocks, blocks = split_sample_into_blocks_for_model(
        sample,
        model=model,
        blocksize_parameter=blocksize_parameter,
        batch_size=batch_size,
    )
    for block in blocks:
        yield self.serialize_sample_block(block)

serialize_sample_with_fixed_blocking classmethod ¤

serialize_sample_with_fixed_blocking(sample: Sample, *, block_shapes: PerMember[PerAxis[int]], halo: PerMember[PerAxis[HaloLike]], pad_mode: Union[PadMode, PerMember[PadMode]] = 'symmetric') -> Iterable[SerializedSampleBlockType]
Source code in src/bioimageio/core/_sample_serializer.py
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
@classmethod
def serialize_sample_with_fixed_blocking(
    cls,
    sample: Sample,
    *,
    block_shapes: PerMember[PerAxis[int]],
    halo: PerMember[PerAxis[HaloLike]],
    pad_mode: Union[PadMode, PerMember[PadMode]] = "symmetric",
) -> Iterable[SerializedSampleBlockType]:

    _n_blocks, input_blocks = sample.split_into_blocks(
        block_shapes=block_shapes,
        halo=halo,
        pad_mode=pad_mode,
    )
    for block in input_blocks:
        yield cls.serialize_sample_block(block)

Settings ¤

Bases: SpecSettings


              flowchart TD
              bioimageio.core.Settings[Settings]
              bioimageio.spec._internal._settings.Settings[Settings]

                              bioimageio.spec._internal._settings.Settings --> bioimageio.core.Settings
                


              click bioimageio.core.Settings href "" "bioimageio.core.Settings"
              click bioimageio.spec._internal._settings.Settings href "" "bioimageio.spec._internal._settings.Settings"
            

environment variables for bioimageio.spec and bioimageio.core

Methods:

Name Description
__setattr__

Attributes:

Name Type Description
CI Annotated[Union[bool, str], Field(alias=CI)]

Wether or not the execution happens in a continuous integration (CI) environment.

allow_pickle bool

Sets the allow_pickle argument for numpy.load()

cache_path Path

bioimageio cache location

collection_config_url str

URL to the bioimageio collection config

collection_http_pattern str

A pattern to map bioimageio IDs to bioimageio.yaml URLs.

collection_index_url str

URL to the bioimageio collection index

disk_cache
github_auth
github_token Optional[str]

GitHub token for API requests

github_username Optional[str]

GitHub username for API requests

gradio_server Optional[str]

URL or Hugging Face space name to connect to with the remote gradio model adapter or remote gradio prediction pipeline.

gradio_server_model_cache_max_memory str

Max memory to use for model caching in the gradio server for prediction pipelines using the gradio backend.

gradio_server_model_cache_max_size int

Max number of models to cache in the gradio server for prediction pipelines using the gradio backend.

http_timeout float

Timeout in seconds for http requests.

huggingface_http_pattern str

A pattern to map huggingface repo IDs to bioimageio.yaml URLs.

hypha_upload str

URL to the upload endpoint for bioimageio resources.

hypha_upload_token Optional[str]

Hypha API token to use for uploads.

id_map str

URL to bioimageio id_map.json to resolve resource IDs.

id_map_draft str

URL to bioimageio id_map_draft.json to resolve draft IDs ending with '/draft'.

keras_backend Annotated[Literal['torch', 'tensorflow', 'jax'], Field(alias=KERAS_BACKEND)]
log_warnings bool

Log validation warnings to console.

model_config
perform_io_checks bool

Wether or not to perform validation that requires file io,

pytorch_enable_mps_fallback Annotated[Optional[bool], Field(alias=PYTORCH_ENABLE_MPS_FALLBACK)]
resolve_draft bool

Flag to resolve draft resource versions following the pattern

user_agent Optional[str]

user agent for http requests

CI class-attribute instance-attribute ¤

CI: Annotated[Union[bool, str], Field(alias=CI)] = False

Wether or not the execution happens in a continuous integration (CI) environment.

allow_pickle class-attribute instance-attribute ¤

allow_pickle: bool = False

Sets the allow_pickle argument for numpy.load()

cache_path class-attribute instance-attribute ¤

cache_path: Path = Path(platformdirs.user_cache_dir('bioimageio'))

bioimageio cache location

collection_config_url class-attribute instance-attribute ¤

collection_config_url: str = 'https://bioimage-io.github.io/collection/bioimageio_collection_config.json'

URL to the bioimageio collection config

collection_http_pattern class-attribute instance-attribute ¤

collection_http_pattern: str = 'https://hypha.aicell.io/bioimage-io/artifacts/{bioimageio_id}/files/rdf.yaml'

A pattern to map bioimageio IDs to bioimageio.yaml URLs. Notes: - '{bioimageio_id}' is replaced with user query, e.g. "affable-shark" when calling load_description("affable-shark"). - This method takes precedence over resolving via id_map. - If this endpoints fails, we fall back to id_map.

collection_index_url class-attribute instance-attribute ¤

collection_index_url: str = 'https://bioimage-io.github.io/collection/index.json'

URL to the bioimageio collection index

disk_cache cached property ¤

disk_cache

github_auth property ¤

github_auth

github_token class-attribute instance-attribute ¤

github_token: Optional[str] = None

GitHub token for API requests

github_username class-attribute instance-attribute ¤

github_username: Optional[str] = None

GitHub username for API requests

gradio_server class-attribute instance-attribute ¤

gradio_server: Optional[str] = None

URL or Hugging Face space name to connect to with the remote gradio model adapter or remote gradio prediction pipeline.

Example: "bioimage-io/bioimage-io-gradio-server"

gradio_server_model_cache_max_memory class-attribute instance-attribute ¤

gradio_server_model_cache_max_memory: str = '40GB'

Max memory to use for model caching in the gradio server for prediction pipelines using the gradio backend.

gradio_server_model_cache_max_size class-attribute instance-attribute ¤

gradio_server_model_cache_max_size: int = 10

Max number of models to cache in the gradio server for prediction pipelines using the gradio backend.

http_timeout class-attribute instance-attribute ¤

http_timeout: float = 10.0

Timeout in seconds for http requests.

huggingface_http_pattern class-attribute instance-attribute ¤

huggingface_http_pattern: str = 'https://huggingface.co/{repo_id}/resolve/{branch}/package/bioimageio.yaml'

A pattern to map huggingface repo IDs to bioimageio.yaml URLs. Notes: - Used for loading source strings of the form "huggingface/{user_or_org}/{resource_id}[/{version}]" - example use: load_description("huggingface/fynnbe/ambitious-sloth/1.3") - A given version {version} is mapped to a branch name "v{version}", e.g. "v1.3". - If no version is provided the "main" branch is used. - This method takes precedence over resolving via id_map. - If this endpoints fails, we fall back to id_map.

hypha_upload class-attribute instance-attribute ¤

hypha_upload: str = 'https://hypha.aicell.io/public/services/artifact-manager/create'

URL to the upload endpoint for bioimageio resources.

hypha_upload_token class-attribute instance-attribute ¤

hypha_upload_token: Optional[str] = None

Hypha API token to use for uploads.

By setting this token you agree to our terms of service at https://bioimage.io/#/toc.

How to obtain a token
  1. Login to https://bioimage.io
  2. Generate a new token at https://bioimage.io/#/api?tab=hypha-rpc

id_map class-attribute instance-attribute ¤

id_map: str = 'https://uk1s3.embassy.ebi.ac.uk/public-datasets/bioimage.io/id_map.json'

URL to bioimageio id_map.json to resolve resource IDs.

id_map_draft class-attribute instance-attribute ¤

id_map_draft: str = 'https://uk1s3.embassy.ebi.ac.uk/public-datasets/bioimage.io/id_map_draft.json'

URL to bioimageio id_map_draft.json to resolve draft IDs ending with '/draft'.

keras_backend class-attribute instance-attribute ¤

keras_backend: Annotated[Literal['torch', 'tensorflow', 'jax'], Field(alias=KERAS_BACKEND)] = 'torch'

log_warnings class-attribute instance-attribute ¤

log_warnings: bool = True

Log validation warnings to console.

model_config class-attribute instance-attribute ¤

model_config = SettingsConfigDict(env_prefix='BIOIMAGEIO_', env_file='.env', env_file_encoding='utf-8')

perform_io_checks class-attribute instance-attribute ¤

perform_io_checks: bool = True

Wether or not to perform validation that requires file io, e.g. downloading a remote files.

Existence of any local absolute file paths is still being checked.

pytorch_enable_mps_fallback class-attribute instance-attribute ¤

pytorch_enable_mps_fallback: Annotated[Optional[bool], Field(alias=PYTORCH_ENABLE_MPS_FALLBACK)] = None

resolve_draft class-attribute instance-attribute ¤

resolve_draft: bool = True

Flag to resolve draft resource versions following the pattern /draft.

Note that anyone may stage a new draft and that such a draft version may not have been reviewed yet. Set this flag to False to avoid this potential security risk and disallow loading draft versions.

user_agent class-attribute instance-attribute ¤

user_agent: Optional[str] = None

user agent for http requests

__setattr__ ¤

__setattr__(name: str, value: Any)
Source code in bioimageio/spec/_internal/_settings.py
31
32
33
34
35
36
37
38
39
def __setattr__(self, name: str, value: Any):
    super().__setattr__(name, value)
    # if cache_path is being changed, we need to reset the disk_cache so that it gets re-created with the new path when accessed next time
    if (
        name == "cache_path"
        and "disk_cache" in self.__dict__
        and self.disk_cache.dir_path != value
    ):
        del self.disk_cache

Tensor ¤

Tensor(array: Union[NDArray[Any], xr.DataArray], dims: Sequence[Union[AxisId, AxisLike]])

Bases: MagicTensorOpsMixin


              flowchart TD
              bioimageio.core.Tensor[Tensor]
              bioimageio.core._magic_tensor_ops.MagicTensorOpsMixin[MagicTensorOpsMixin]

                              bioimageio.core._magic_tensor_ops.MagicTensorOpsMixin --> bioimageio.core.Tensor
                


              click bioimageio.core.Tensor href "" "bioimageio.core.Tensor"
              click bioimageio.core._magic_tensor_ops.MagicTensorOpsMixin href "" "bioimageio.core._magic_tensor_ops.MagicTensorOpsMixin"
            

A wrapper around an xr.DataArray for better integration with bioimageio.spec and improved type annotations.

Methods:

Name Description
__abs__
__add__
__and__
__array__
__eq__
__floordiv__
__ge__
__getitem__
__gt__
__iadd__
__iand__
__ifloordiv__
__ilshift__
__imod__
__imul__
__invert__
__ior__
__ipow__
__irshift__
__isub__
__iter__
__itruediv__
__ixor__
__le__
__len__
__lshift__
__lt__
__mod__
__mul__
__ne__
__neg__
__or__
__pos__
__pow__
__radd__
__rand__
__repr__
__rfloordiv__
__rmod__
__rmul__
__ror__
__rpow__
__rshift__
__rsub__
__rtruediv__
__rxor__
__setitem__
__sub__
__truediv__
__xor__
argmax
argsort
assign_batch_multi_index

Set the batch multi-index for this tensor.

astype

Return tensor cast to dtype

clip

Return a tensor whose values are limited to [min, max].

conj
conjugate
crop_to

crop to match sizes

expand_dims
from_numpy

create a Tensor from a numpy array

from_xarray

create a Tensor from an xarray data array

item

Copy a tensor element to a standard Python scalar and return it.

mean
pad
pad_to

pad tensor to match sizes

quantile
resize_to

return cropped/padded tensor with sizes

round
std
sum

Reduce this Tensor's data by applying sum along some dimension(s).

to_numpy

Return the data of this tensor as a numpy array.

transpose

Return a transposed tensor, missing axes are expanded (if unstack_missing_dims_from_batch is False) or unstacked from batch (if unstack_missing_dims_from_batch is True), extra axes are stacked to batch (if stack_extra_dims_to_batch is True). Additional axes raise (if stack_extra_dims_to_batch is True).

unstack_batch_multi_index

Unstack the batch multi-index of this tensor.

var

Attributes:

Name Type Description
__hash__ None
__slots__
data
dims

Tuple of dimension names associated with this tensor.

dtype DTypeStr
ndim

Number of tensor dimensions.

shape

Tuple of tensor axes lengths

shape_tuple

Tuple of tensor axes lengths

size

Number of elements in the tensor.

sizes

Ordered, immutable mapping from axis ids to axis lengths.

tagged_shape

(alias for sizes) Ordered, immutable mapping from axis ids to lengths.

Source code in src/bioimageio/core/tensor.py
76
77
78
79
80
81
82
83
84
85
86
87
88
def __init__(
    self,
    array: Union[NDArray[Any], xr.DataArray],
    dims: Sequence[Union[AxisId, AxisLike]],
) -> None:
    super().__init__()
    axes = tuple(
        a if isinstance(a, AxisId) else AxisInfo.create(a).id for a in dims
    )
    if isinstance(array, xr.DataArray):
        self._data = array.transpose(*axes)
    else:
        self._data = xr.DataArray(array, dims=axes)

__hash__ instance-attribute ¤

__hash__: None

__slots__ class-attribute instance-attribute ¤

__slots__ = ()

data property ¤

data

dims property ¤

dims

Tuple of dimension names associated with this tensor.

dtype property ¤

dtype: DTypeStr

ndim property ¤

ndim

Number of tensor dimensions.

shape property ¤

shape

Tuple of tensor axes lengths

shape_tuple property ¤

shape_tuple

Tuple of tensor axes lengths

size property ¤

size

Number of elements in the tensor.

Equal to math.prod(tensor.shape), i.e., the product of the tensors’ dimensions.

sizes property ¤

sizes

Ordered, immutable mapping from axis ids to axis lengths.

tagged_shape property ¤

tagged_shape

(alias for sizes) Ordered, immutable mapping from axis ids to lengths.

__abs__ ¤

__abs__() -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
175
176
def __abs__(self) -> Self:
    return self._unary_op(operator.abs)

__add__ ¤

__add__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
31
32
def __add__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.add)

__and__ ¤

__and__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
52
53
def __and__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.and_)  # pyright: ignore[reportUnknownArgumentType]

__array__ ¤

__array__(dtype: DTypeLike = None)
Source code in src/bioimageio/core/tensor.py
93
94
def __array__(self, dtype: DTypeLike = None):
    return np.asarray(self._data, dtype=dtype)

__eq__ ¤

__eq__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
79
80
81
82
83
def __eq__(self, other: _Compatible) -> Self:  # type: ignore[override]
    return self._binary_op(
        other,
        nputils.array_eq,  # pyright: ignore[reportUnknownArgumentType]
    )

__floordiv__ ¤

__floordiv__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
46
47
def __floordiv__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.floordiv)  # pyright: ignore[reportUnknownArgumentType]

__ge__ ¤

__ge__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
76
77
def __ge__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.ge)

__getitem__ ¤

__getitem__(key: Union[SliceInfo, slice, int, PerAxis[Union[SliceInfo, slice, int]], Tensor, xr.DataArray]) -> Self
Source code in src/bioimageio/core/tensor.py
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
def __getitem__(
    self,
    key: Union[
        SliceInfo,
        slice,
        int,
        PerAxis[Union[SliceInfo, slice, int]],
        Tensor,
        xr.DataArray,
    ],
) -> Self:
    if isinstance(key, SliceInfo):
        key = slice(*key)
    elif isinstance(key, collections.abc.Mapping):
        key = {
            a: s if isinstance(s, int) else s if isinstance(s, slice) else slice(*s)
            for a, s in key.items()
        }
    elif isinstance(key, Tensor):
        key = key._data

    return self.__class__.from_xarray(self._data[key])

__gt__ ¤

__gt__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
73
74
def __gt__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.gt)

__iadd__ ¤

__iadd__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
130
131
def __iadd__(self, other: _Compatible) -> Self:
    return self._inplace_binary_op(other, operator.iadd)  # pyright: ignore[reportUnknownArgumentType]

__iand__ ¤

__iand__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
151
152
def __iand__(self, other: _Compatible) -> Self:
    return self._inplace_binary_op(other, operator.iand)  # pyright: ignore[reportUnknownArgumentType]

__ifloordiv__ ¤

__ifloordiv__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
145
146
def __ifloordiv__(self, other: _Compatible) -> Self:
    return self._inplace_binary_op(other, operator.ifloordiv)  # pyright: ignore[reportUnknownArgumentType]

__ilshift__ ¤

__ilshift__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
160
161
def __ilshift__(self, other: _Compatible) -> Self:
    return self._inplace_binary_op(other, operator.ilshift)  # pyright: ignore[reportUnknownArgumentType]

__imod__ ¤

__imod__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
148
149
def __imod__(self, other: _Compatible) -> Self:
    return self._inplace_binary_op(other, operator.imod)  # pyright: ignore[reportUnknownArgumentType]

__imul__ ¤

__imul__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
136
137
def __imul__(self, other: _Compatible) -> Self:
    return self._inplace_binary_op(other, operator.imul)  # pyright: ignore[reportUnknownArgumentType]

__invert__ ¤

__invert__() -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
178
179
def __invert__(self) -> Self:
    return self._unary_op(operator.invert)

__ior__ ¤

__ior__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
157
158
def __ior__(self, other: _Compatible) -> Self:
    return self._inplace_binary_op(other, operator.ior)  # pyright: ignore[reportUnknownArgumentType]

__ipow__ ¤

__ipow__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
139
140
def __ipow__(self, other: _Compatible) -> Self:
    return self._inplace_binary_op(other, operator.ipow)  # pyright: ignore[reportUnknownArgumentType]

__irshift__ ¤

__irshift__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
163
164
def __irshift__(self, other: _Compatible) -> Self:
    return self._inplace_binary_op(other, operator.irshift)  # pyright: ignore[reportUnknownArgumentType]

__isub__ ¤

__isub__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
133
134
def __isub__(self, other: _Compatible) -> Self:
    return self._inplace_binary_op(other, operator.isub)  # pyright: ignore[reportUnknownArgumentType]

__iter__ ¤

__iter__() -> Iterator[Any]
Source code in src/bioimageio/core/tensor.py
143
144
145
146
def __iter__(self: Any) -> Iterator[Any]:
    if self.ndim == 0:
        raise TypeError("iteration over a 0-d array")
    return self._iter()

__itruediv__ ¤

__itruediv__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
142
143
def __itruediv__(self, other: _Compatible) -> Self:
    return self._inplace_binary_op(other, operator.itruediv)  # pyright: ignore[reportUnknownArgumentType]

__ixor__ ¤

__ixor__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
154
155
def __ixor__(self, other: _Compatible) -> Self:
    return self._inplace_binary_op(other, operator.ixor)  # pyright: ignore[reportUnknownArgumentType]

__le__ ¤

__le__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
70
71
def __le__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.le)

__len__ ¤

__len__() -> int
Source code in src/bioimageio/core/tensor.py
136
137
def __len__(self) -> int:
    return len(self.data)

__lshift__ ¤

__lshift__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
61
62
def __lshift__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.lshift)  # pyright: ignore[reportUnknownArgumentType]

__lt__ ¤

__lt__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
67
68
def __lt__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.lt)

__mod__ ¤

__mod__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
49
50
def __mod__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.mod)

__mul__ ¤

__mul__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
37
38
def __mul__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.mul)

__ne__ ¤

__ne__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
85
86
87
88
89
def __ne__(self, other: _Compatible) -> Self:  # type: ignore[override]
    return self._binary_op(
        other,
        nputils.array_ne,  # pyright: ignore[reportUnknownArgumentType]
    )

__neg__ ¤

__neg__() -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
169
170
def __neg__(self) -> Self:
    return self._unary_op(operator.neg)

__or__ ¤

__or__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
58
59
def __or__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.or_)  # pyright: ignore[reportUnknownArgumentType]

__pos__ ¤

__pos__() -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
172
173
def __pos__(self) -> Self:
    return self._unary_op(operator.pos)

__pow__ ¤

__pow__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
40
41
def __pow__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.pow)  # pyright: ignore[reportUnknownArgumentType]

__radd__ ¤

__radd__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
95
96
def __radd__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.add, reflexive=True)

__rand__ ¤

__rand__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
116
117
def __rand__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.and_, reflexive=True)  # pyright: ignore[reportUnknownArgumentType]

__repr__ ¤

__repr__() -> str
Source code in src/bioimageio/core/tensor.py
90
91
def __repr__(self) -> str:
    return f"<Tensor {repr(self._data)}>"

__rfloordiv__ ¤

__rfloordiv__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
110
111
def __rfloordiv__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.floordiv, reflexive=True)  # pyright: ignore[reportUnknownArgumentType]

__rmod__ ¤

__rmod__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
113
114
def __rmod__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.mod, reflexive=True)

__rmul__ ¤

__rmul__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
101
102
def __rmul__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.mul, reflexive=True)

__ror__ ¤

__ror__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
122
123
def __ror__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.or_, reflexive=True)  # pyright: ignore[reportUnknownArgumentType]

__rpow__ ¤

__rpow__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
104
105
def __rpow__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.pow, reflexive=True)  # pyright: ignore[reportUnknownArgumentType]

__rshift__ ¤

__rshift__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
64
65
def __rshift__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.rshift)  # pyright: ignore[reportUnknownArgumentType]

__rsub__ ¤

__rsub__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
98
99
def __rsub__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.sub, reflexive=True)

__rtruediv__ ¤

__rtruediv__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
107
108
def __rtruediv__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.truediv, reflexive=True)  # pyright: ignore[reportUnknownArgumentType]

__rxor__ ¤

__rxor__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
119
120
def __rxor__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.xor, reflexive=True)  # pyright: ignore[reportUnknownArgumentType]

__setitem__ ¤

__setitem__(key: Union[PerAxis[Union[SliceInfo, slice]], Tensor, xr.DataArray], value: Union[Tensor, xr.DataArray, float, int]) -> None
Source code in src/bioimageio/core/tensor.py
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
def __setitem__(
    self,
    key: Union[PerAxis[Union[SliceInfo, slice]], Tensor, xr.DataArray],
    value: Union[Tensor, xr.DataArray, float, int],
) -> None:
    if isinstance(key, Tensor):
        key = key._data
    elif isinstance(key, xr.DataArray):
        pass
    else:
        key = {a: s if isinstance(s, slice) else slice(*s) for a, s in key.items()}

    if isinstance(value, Tensor):
        value = value._data

    self._data[key] = value

__sub__ ¤

__sub__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
34
35
def __sub__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.sub)

__truediv__ ¤

__truediv__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
43
44
def __truediv__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.truediv)  # pyright: ignore[reportUnknownArgumentType]

__xor__ ¤

__xor__(other: _Compatible) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
55
56
def __xor__(self, other: _Compatible) -> Self:
    return self._binary_op(other, operator.xor)  # pyright: ignore[reportUnknownArgumentType]

argmax ¤

argmax() -> Mapping[AxisId, int]
Source code in src/bioimageio/core/tensor.py
283
284
285
286
def argmax(self) -> Mapping[AxisId, int]:
    ret = self._data.argmax(...)
    assert isinstance(ret, dict)
    return {cast(AxisId, k): cast(int, v.item()) for k, v in ret.items()}

argsort ¤

argsort(*args: Any, **kwargs: Any) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
188
189
190
191
192
193
def argsort(self, *args: Any, **kwargs: Any) -> Self:
    return self._unary_op(
        ops.argsort,  # pyright: ignore[reportUnknownArgumentType]
        *args,
        **kwargs,
    )

assign_batch_multi_index ¤

assign_batch_multi_index(multi_index: 'pd.MultiIndex') -> Self

Set the batch multi-index for this tensor.

Parameters:

Name Type Description Default

multi_index ¤

'pd.MultiIndex'

The multi-index to set.

required
Source code in src/bioimageio/core/tensor.py
492
493
494
495
496
497
498
499
500
501
502
503
504
505
def assign_batch_multi_index(self, multi_index: "pd.MultiIndex") -> Self:
    """Set the batch multi-index for this tensor.

    Args:
        multi_index: The multi-index to set.
    """
    if AxisId("batch") not in self.dims:
        raise ValueError(
            "Cannot set batch multi-index on a tensor without a 'batch' axis."
        )

    return self.__class__.from_xarray(
        self._data.assign_coords({AxisId("batch"): multi_index})
    )

astype ¤

astype(dtype: DTypeStr, *, copy: bool = False)

Return tensor cast to dtype

note: if dtype is already satisfied copy if copy

Source code in src/bioimageio/core/tensor.py
288
289
290
291
292
def astype(self, dtype: DTypeStr, *, copy: bool = False):
    """Return tensor cast to `dtype`

    note: if dtype is already satisfied copy if `copy`"""
    return self.__class__.from_xarray(self._data.astype(dtype, copy=copy))

clip ¤

clip(min: Optional[float] = None, max: Optional[float] = None)

Return a tensor whose values are limited to [min, max]. At least one of max or min must be given.

Source code in src/bioimageio/core/tensor.py
294
295
296
297
def clip(self, min: Optional[float] = None, max: Optional[float] = None):
    """Return a tensor whose values are limited to [min, max].
    At least one of max or min must be given."""
    return self.__class__.from_xarray(self._data.clip(min, max))

conj ¤

conj(*args: Any, **kwargs: Any) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
195
196
197
198
199
200
def conj(self, *args: Any, **kwargs: Any) -> Self:
    return self._unary_op(
        ops.conj,  # pyright: ignore[reportUnknownArgumentType]
        *args,
        **kwargs,
    )

conjugate ¤

conjugate(*args: Any, **kwargs: Any) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
202
203
204
205
206
207
def conjugate(self, *args: Any, **kwargs: Any) -> Self:
    return self._unary_op(
        ops.conjugate,  # pyright: ignore[reportUnknownArgumentType]
        *args,
        **kwargs,
    )

crop_to ¤

crop_to(sizes: PerAxis[int], crop_where: Union[CropWhere, PerAxis[CropWhere]] = 'left_and_right') -> Self

crop to match sizes

Source code in src/bioimageio/core/tensor.py
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
def crop_to(
    self,
    sizes: PerAxis[int],
    crop_where: Union[
        CropWhere,
        PerAxis[CropWhere],
    ] = "left_and_right",
) -> Self:
    """crop to match `sizes`"""
    if isinstance(crop_where, str):
        crop_axis_where: PerAxis[CropWhere] = {a: crop_where for a in self.dims}
    else:
        crop_axis_where = crop_where

    slices: Dict[AxisId, SliceInfo] = {}

    for a, s_is in self.sizes.items():
        if a not in sizes or sizes[a] == s_is:
            pass
        elif sizes[a] > s_is:
            logger.warning(
                "Cannot crop axis {} of size {} to larger size {}",
                a,
                s_is,
                sizes[a],
            )
        elif a not in crop_axis_where:
            raise ValueError(
                f"Don't know where to crop axis {a}, `crop_where`={crop_where}"
            )
        else:
            crop_this_axis_where = crop_axis_where[a]
            if crop_this_axis_where == "left":
                slices[a] = SliceInfo(s_is - sizes[a], s_is)
            elif crop_this_axis_where == "right":
                slices[a] = SliceInfo(0, sizes[a])
            elif crop_this_axis_where == "left_and_right":
                slices[a] = SliceInfo(
                    start := (s_is - sizes[a]) // 2, sizes[a] + start
                )
            else:
                assert_never(crop_this_axis_where)

    return self[slices]

expand_dims ¤

expand_dims(dims: Union[Sequence[AxisId], PerAxis[int]]) -> Self
Source code in src/bioimageio/core/tensor.py
344
345
def expand_dims(self, dims: Union[Sequence[AxisId], PerAxis[int]]) -> Self:
    return self.__class__.from_xarray(self._data.expand_dims(dims=dims))

from_numpy classmethod ¤

from_numpy(array: NDArray[Any], *, dims: Optional[Union[AxisLike, Sequence[AxisLike]]]) -> Tensor

create a Tensor from a numpy array

Parameters:

Name Type Description Default

array ¤

NDArray[Any]

the nd numpy array

required

dims ¤

Optional[Union[AxisLike, Sequence[AxisLike]]]

A description of the array's axes. If None axes are guessed (which might fail and raise a ValueError.) If dims do not match array shape, permutations and singleton dimensions are tried to find a match.

required

Raises: ValueError: if dims is None and dims guessing fails.

Source code in src/bioimageio/core/tensor.py
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
@classmethod
def from_numpy(
    cls,
    array: NDArray[Any],
    *,
    dims: Optional[Union[AxisLike, Sequence[AxisLike]]],
) -> Tensor:
    """create a `Tensor` from a numpy array

    Args:
        array: the nd numpy array
        dims: A description of the array's axes.
            If None axes are guessed (which might fail and raise a ValueError.)
            If dims do not match array shape, permutations and singleton dimensions are tried to find a match.
    Raises:
        ValueError: if `dims` is None and dims guessing fails.
    """

    if dims is None:
        return cls._interprete_array_wo_known_axes(array)
    elif isinstance(dims, collections.abc.Sequence):
        dim_seq = list(dims)
    else:
        dim_seq = [dims]

    axis_infos = [AxisInfo.create(a) for a in dim_seq]
    original_shape = tuple(array.shape)

    successful_view = _get_array_view(array, axis_infos)
    if successful_view is None:
        raise ValueError(
            f"Array shape {original_shape} does not map to axes {dims}"
        )

    return Tensor(successful_view, dims=tuple(a.id for a in axis_infos))

from_xarray classmethod ¤

from_xarray(data_array: xr.DataArray) -> Self

create a Tensor from an xarray data array

this factory method is round-trip save

for any Tensor's data property (an xarray.DataArray).

Source code in src/bioimageio/core/tensor.py
186
187
188
189
190
191
192
193
@classmethod
def from_xarray(cls, data_array: xr.DataArray) -> Self:
    """create a `Tensor` from an xarray data array

    note for internal use: this factory method is round-trip save
        for any `Tensor`'s  `data` property (an xarray.DataArray).
    """
    return cls(array=data_array, dims=tuple(AxisId(d) for d in data_array.dims))

item ¤

item(key: Union[None, SliceInfo, slice, int, PerAxis[Union[SliceInfo, slice, int]]] = None)

Copy a tensor element to a standard Python scalar and return it.

Source code in src/bioimageio/core/tensor.py
347
348
349
350
351
352
353
354
355
356
357
358
359
360
def item(
    self,
    key: Union[
        None, SliceInfo, slice, int, PerAxis[Union[SliceInfo, slice, int]]
    ] = None,
):
    """Copy a tensor element to a standard Python scalar and return it."""
    if key is None:
        ret = self._data.item()
    else:
        ret = self[key]._data.item()

    assert isinstance(ret, (bool, float, int))
    return ret

mean ¤

mean(dim: Optional[Union[AxisId, Sequence[AxisId]]] = None) -> Self
Source code in src/bioimageio/core/tensor.py
362
363
def mean(self, dim: Optional[Union[AxisId, Sequence[AxisId]]] = None) -> Self:
    return self.__class__.from_xarray(self._data.mean(dim=dim))

pad ¤

pad(pad_width: PerAxis[PadWidthLike], mode: PadMode = 'symmetric') -> Self
Source code in src/bioimageio/core/tensor.py
365
366
367
368
369
370
371
372
373
374
375
376
def pad(
    self,
    pad_width: PerAxis[PadWidthLike],
    mode: PadMode = "symmetric",
) -> Self:
    pad_width = {a: PadWidth.create(p) for a, p in pad_width.items()}
    mode_name, constant_value = _resolve_pad_mode(mode)
    return self.__class__.from_xarray(
        self._data.pad(
            pad_width=pad_width, mode=mode_name, constant_values=constant_value
        )
    )

pad_to ¤

pad_to(sizes: PerAxis[int], pad_where: Union[PadWhere, PerAxis[PadWhere]] = 'left_and_right', mode: PadMode = 'symmetric') -> Self

pad tensor to match sizes

Source code in src/bioimageio/core/tensor.py
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
def pad_to(
    self,
    sizes: PerAxis[int],
    pad_where: Union[PadWhere, PerAxis[PadWhere]] = "left_and_right",
    mode: PadMode = "symmetric",
) -> Self:
    """pad `tensor` to match `sizes`"""
    if isinstance(pad_where, str):
        pad_axis_where: PerAxis[PadWhere] = {a: pad_where for a in self.dims}
    else:
        pad_axis_where = pad_where

    pad_width: Dict[AxisId, PadWidth] = {}
    for a, s_is in self.sizes.items():
        if a not in sizes or sizes[a] == s_is:
            pad_width[a] = PadWidth(0, 0)
        elif s_is > sizes[a]:
            pad_width[a] = PadWidth(0, 0)
            logger.warning(
                "Cannot pad axis {} of size {} to smaller size {}",
                a,
                s_is,
                sizes[a],
            )
        elif a not in pad_axis_where:
            raise ValueError(
                f"Don't know where to pad axis {a}, `pad_where`={pad_where}"
            )
        else:
            pad_this_axis_where = pad_axis_where[a]
            d = sizes[a] - s_is
            if pad_this_axis_where == "left":
                pad_width[a] = PadWidth(d, 0)
            elif pad_this_axis_where == "right":
                pad_width[a] = PadWidth(0, d)
            elif pad_this_axis_where == "left_and_right":
                pad_width[a] = PadWidth(left := d // 2, d - left)
            else:
                assert_never(pad_this_axis_where)

    return self.pad(pad_width, mode)

quantile ¤

quantile(q: Union[float, Sequence[float]], dim: Optional[Union[AxisId, Sequence[AxisId]]] = None, method: QuantileMethod = 'linear') -> Self
Source code in src/bioimageio/core/tensor.py
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
def quantile(
    self,
    q: Union[float, Sequence[float]],
    dim: Optional[Union[AxisId, Sequence[AxisId]]] = None,
    method: QuantileMethod = "linear",
) -> Self:
    assert (
        isinstance(q, (float, int))
        and q >= 0.0
        or not isinstance(q, (float, int))
        and all(qq >= 0.0 for qq in q)
    )
    assert (
        isinstance(q, (float, int))
        and q <= 1.0
        or not isinstance(q, (float, int))
        and all(qq <= 1.0 for qq in q)
    )
    assert dim is None or (
        (quantile_dim := AxisId("quantile")) != dim and quantile_dim not in set(dim)
    )
    return self.__class__.from_xarray(
        self._data.quantile(q, dim=dim, method=method)
    )

resize_to ¤

resize_to(sizes: PerAxis[int], *, pad_where: Union[PadWhere, PerAxis[PadWhere]] = 'left_and_right', crop_where: Union[CropWhere, PerAxis[CropWhere]] = 'left_and_right', pad_mode: PadMode = 'symmetric')

return cropped/padded tensor with sizes

Source code in src/bioimageio/core/tensor.py
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
def resize_to(
    self,
    sizes: PerAxis[int],
    *,
    pad_where: Union[
        PadWhere,
        PerAxis[PadWhere],
    ] = "left_and_right",
    crop_where: Union[
        CropWhere,
        PerAxis[CropWhere],
    ] = "left_and_right",
    pad_mode: PadMode = "symmetric",
):
    """return cropped/padded tensor with `sizes`"""
    crop_to_sizes: Dict[AxisId, int] = {}
    pad_to_sizes: Dict[AxisId, int] = {}
    new_axes = dict(sizes)
    for a, s_is in self.sizes.items():
        a = AxisId(str(a))
        _ = new_axes.pop(a, None)
        if a not in sizes or sizes[a] == s_is:
            pass
        elif s_is > sizes[a]:
            crop_to_sizes[a] = sizes[a]
        else:
            pad_to_sizes[a] = sizes[a]

    tensor = self
    if crop_to_sizes:
        tensor = tensor.crop_to(crop_to_sizes, crop_where=crop_where)

    if pad_to_sizes:
        tensor = tensor.pad_to(pad_to_sizes, pad_where=pad_where, mode=pad_mode)

    if new_axes:
        tensor = tensor.expand_dims(new_axes)

    return tensor

round ¤

round(*args: Any, **kwargs: Any) -> Self
Source code in src/bioimageio/core/_magic_tensor_ops.py
181
182
183
184
185
186
def round(self, *args: Any, **kwargs: Any) -> Self:
    return self._unary_op(
        ops.round_,  # pyright: ignore[reportUnknownArgumentType]
        *args,
        **kwargs,
    )

std ¤

std(dim: Optional[Union[AxisId, Sequence[AxisId]]] = None) -> Self
Source code in src/bioimageio/core/tensor.py
485
486
def std(self, dim: Optional[Union[AxisId, Sequence[AxisId]]] = None) -> Self:
    return self.__class__.from_xarray(self._data.std(dim=dim))

sum ¤

sum(dim: Optional[Union[AxisId, Sequence[AxisId]]] = None) -> Self

Reduce this Tensor's data by applying sum along some dimension(s).

Source code in src/bioimageio/core/tensor.py
488
489
490
def sum(self, dim: Optional[Union[AxisId, Sequence[AxisId]]] = None) -> Self:
    """Reduce this Tensor's data by applying sum along some dimension(s)."""
    return self.__class__.from_xarray(self._data.sum(dim=dim))

to_numpy ¤

to_numpy() -> NDArray[Any]

Return the data of this tensor as a numpy array.

Source code in src/bioimageio/core/tensor.py
279
280
281
def to_numpy(self) -> NDArray[Any]:
    """Return the data of this tensor as a numpy array."""
    return self.data.to_numpy()  # pyright: ignore[reportUnknownVariableType]

transpose ¤

transpose(axes: Sequence[AxisId], *, extra_dims: Literal['raise', 'squeeze', 'stack', 'squeeze_or_stack'] = 'squeeze', missing_dims: Literal['raise', 'expand', 'unstack', 'unstack_or_expand'] = 'unstack_or_expand') -> Self

Return a transposed tensor, missing axes are expanded (if unstack_missing_dims_from_batch is False) or unstacked from batch (if unstack_missing_dims_from_batch is True), extra axes are stacked to batch (if stack_extra_dims_to_batch is True). Additional axes raise (if stack_extra_dims_to_batch is True).

Parameters:

Name Type Description Default

axes ¤

Sequence[AxisId]

The desired tensor axes

required

extra_dims ¤

Literal['raise', 'squeeze', 'stack', 'squeeze_or_stack']

Extra dimensions are any dimensions in the tensor that are not specified in axes. If "raise", any extra dimensions will raise an error. If "squeeze", any extra singleton dimensions will be squeezed, non-singleton dimensions will raise an error. If "stack", any extra dimensions will be stacked to the batch dimension. Such a stacked batch dimension then has a multi-index that can be unstacked using Tensor.unstack_batch_multi_index(). If "squeeze_or_stack", any extra singleton dimensions will be squeezed, non-singleton dimensions will be stacked to the batch dimension.

'squeeze'

missing_dims ¤

Literal['raise', 'expand', 'unstack', 'unstack_or_expand']

Missing dimensions are any dimensions specified in axes that are not present in the tensor. If "raise", any missing dimensions will raise an error. If "expand", any missing dimensions will be added as singleton dimensions. If "unstack", any missing dimensions will be unstacked from the batch dimension. For this option a batch dimension with a multi-index must be present from previous stacking operations or assigned by Tensor.assign_batch_multi_index(). If "unstack_or_expand", any missing dimensions will be unstacked from the batch dimension if it has a multi-index, otherwise they will be added as singleton dimensions.

'unstack_or_expand'
Source code in src/bioimageio/core/tensor.py
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
def transpose(
    self,
    axes: Sequence[AxisId],
    *,
    extra_dims: Literal[
        "raise", "squeeze", "stack", "squeeze_or_stack"
    ] = "squeeze",
    missing_dims: Literal[
        "raise", "expand", "unstack", "unstack_or_expand"
    ] = "unstack_or_expand",
) -> Self:
    """Return a transposed tensor, missing axes are expanded (if `unstack_missing_dims_from_batch` is False) or unstacked from batch (if `unstack_missing_dims_from_batch` is True), extra axes are stacked to batch (if `stack_extra_dims_to_batch` is True). Additional axes raise (if `stack_extra_dims_to_batch` is True).

    Args:
        axes: The desired tensor axes
        extra_dims:
            Extra dimensions are any dimensions in the tensor that are not specified in `axes`.
            If "raise", any extra dimensions will raise an error.
            If "squeeze", any extra singleton dimensions will be squeezed, non-singleton dimensions will raise an error.
            If "stack", any extra dimensions will be stacked to the batch dimension. Such a stacked batch dimension then has a multi-index that can be unstacked using `Tensor.unstack_batch_multi_index()`.
            If "squeeze_or_stack", any extra singleton dimensions will be squeezed, non-singleton dimensions will be stacked to the batch dimension.
        missing_dims:
            Missing dimensions are any dimensions specified in `axes` that are not present in the tensor.
            If "raise", any missing dimensions will raise an error.
            If "expand", any missing dimensions will be added as singleton dimensions.
            If "unstack", any missing dimensions will be unstacked from the batch dimension. For this option a batch dimension with a multi-index must be present from previous stacking operations or assigned by `Tensor.assign_batch_multi_index()`.
            If "unstack_or_expand", any missing dimensions will be unstacked from the batch dimension if it has a multi-index, otherwise they will be added as singleton dimensions.
    """
    array = self._data

    unhandled_missing_dims = [a for a in axes if a not in array.dims]
    if unhandled_missing_dims and missing_dims == "raise":
        raise ValueError(f"Found missing dimensions {unhandled_missing_dims}.")

    unstack_error = None
    if unhandled_missing_dims and missing_dims in ("unstack", "unstack_or_expand"):
        lets_unstack = AxisId("batch") in array.dims
        if not lets_unstack:
            unstack_error = f"Missing dimensions {unhandled_missing_dims} found, but 'batch' axis is not in the tensor. Cannot unstack missing dimensions from batch."
            if missing_dims == "unstack":
                raise ValueError(unstack_error)

        if lets_unstack and not isinstance(
            array.indexes.get(AxisId("batch")), pd.MultiIndex
        ):
            lets_unstack = False
            unstack_error = f"Missing dimensions {unhandled_missing_dims} found, but 'batch' axis does not have a MultiIndex. Cannot unstack missing dimensions from non-multi-index batch."
            if missing_dims == "unstack":
                raise ValueError(unstack_error)
    else:
        lets_unstack = False

    if lets_unstack:
        array = array.unstack(AxisId("batch"))

        if AxisId("original_batch") in array.dims:
            if AxisId("batch") in axes:
                array = array.rename({AxisId("original_batch"): AxisId("batch")})
            else:
                array = array.squeeze(AxisId("original_batch"))

        unhandled_missing_dims = [a for a in axes if a not in array.dims]

    if unhandled_missing_dims and missing_dims in ("expand", "unstack_or_expand"):
        array = array.expand_dims(unhandled_missing_dims)
        unhandled_missing_dims = []

    if unhandled_missing_dims:
        if unstack_error is not None:
            raise ValueError(unstack_error)

        raise ValueError(f"Missing dimensions {unhandled_missing_dims}.")

    unhandled_extra_dims = [a for a in array.dims if a not in axes]

    if unhandled_extra_dims and extra_dims == "raise":
        raise ValueError(f"Found extra dimensions {unhandled_extra_dims}.")

    if unhandled_extra_dims and extra_dims in ("squeeze", "squeeze_or_stack"):
        for d in list(unhandled_extra_dims):
            if array.sizes[d] == 1:
                array = array.squeeze(d)
                unhandled_extra_dims.remove(d)
            elif extra_dims == "squeeze":
                raise ValueError(
                    f"Extra dimension {d} found but stack_extra_dims_to_batch is False and the dimension is not a singleton."
                )

    if unhandled_extra_dims and extra_dims in ("stack", "squeeze_or_stack"):
        if AxisId("batch") not in axes:
            raise ValueError(
                f"Extra dimensions {unhandled_extra_dims} found but 'batch' axis is not in the desired axes {axes}."
                + " Cannot stack extra dimensions to batch."
            )

        if AxisId("batch") in array.dims:
            array = array.rename({AxisId("batch"): AxisId("original_batch")})
            unhandled_extra_dims.insert(0, AxisId("original_batch"))

        array = array.stack({AxisId("batch"): unhandled_extra_dims})
        unhandled_extra_dims = []

    if unhandled_extra_dims:
        raise ValueError(
            f"Non-singleton extra dimensions {unhandled_extra_dims} found, but `extra_dims` not in ('stack', 'squeeze_or_stack')."
        )

    # transpose to the correct axis order
    return self.__class__.from_xarray(array.transpose(*axes))

unstack_batch_multi_index ¤

unstack_batch_multi_index(*, errors: Literal['raise', 'ignore'] = 'raise') -> Self

Unstack the batch multi-index of this tensor.

Returns:

Type Description
Self

A new tensor with the batch multi-index unstacked into separate axes.

Source code in src/bioimageio/core/tensor.py
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
def unstack_batch_multi_index(
    self, *, errors: Literal["raise", "ignore"] = "raise"
) -> Self:
    """Unstack the batch multi-index of this tensor.

    Returns:
        A new tensor with the batch multi-index unstacked into separate axes.
    """
    if AxisId("batch") not in self.dims:
        if errors == "raise":
            raise ValueError(
                "Cannot unstack batch multi-index on a tensor without a 'batch' axis."
            )
        elif errors == "ignore":
            return self
        else:
            assert_never(errors)

    if not isinstance(self._data.indexes.get(AxisId("batch")), pd.MultiIndex):
        if errors == "raise":
            raise ValueError(
                "Cannot unstack batch multi-index on a tensor whose 'batch' axis does not have a MultiIndex."
            )
        elif errors == "ignore":
            return self
        else:
            assert_never(errors)

    old_dims = self.dims
    array = self._data.unstack(AxisId("batch"))
    added_dims = [AxisId(d) for d in array.dims if d not in self._data.dims]

    # restore expected axis order, replace batch dim with added dims
    new_dims: List[AxisId] = []
    for d in old_dims:
        if d in array.dims:
            new_dims.append(d)
        elif d == AxisId("batch"):
            new_dims.extend(added_dims)
        else:
            raise ValueError(f"Expected axis {d} not found in unstacked array.")

    array = array.transpose(*new_dims)
    if AxisId("original_batch") in array.dims:
        array = array.rename({AxisId("original_batch"): AxisId("batch")})

    return self.__class__.from_xarray(array)

var ¤

var(dim: Optional[Union[AxisId, Sequence[AxisId]]] = None) -> Self
Source code in src/bioimageio/core/tensor.py
665
666
def var(self, dim: Optional[Union[AxisId, Sequence[AxisId]]] = None) -> Self:
    return self.__class__.from_xarray(self._data.var(dim=dim))

add_weights ¤

add_weights(model_descr: ModelDescr, *, output_path: DirectoryPath, source_format: Optional[WeightsFormat] = None, target_format: Optional[WeightsFormat] = None, verbose: bool = False, allow_tracing: bool = True) -> Union[ModelDescr, InvalidDescr]

Convert model weights to other formats and add them to the model description

Parameters:

Name Type Description Default

output_path ¤

DirectoryPath

Path to save updated model package to.

required

source_format ¤

Optional[WeightsFormat]

convert from a specific weights format. Default: choose automatically from any available.

None

target_format ¤

Optional[WeightsFormat]

convert to a specific weights format. Default: attempt to convert to any missing format.

None

verbose ¤

bool

log more (error) output

False

allow_tracing ¤

bool

allow conversion to torchscript by tracing if scripting fails.

True

Returns:

Type Description
Union[ModelDescr, InvalidDescr]

A (potentially invalid) model copy stored at output_path with added weights if any conversion was possible.

Source code in src/bioimageio/core/weight_converters/_add_weights.py
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
def add_weights(
    model_descr: ModelDescr,
    *,
    output_path: DirectoryPath,
    source_format: Optional[WeightsFormat] = None,
    target_format: Optional[WeightsFormat] = None,
    verbose: bool = False,
    allow_tracing: bool = True,
) -> Union[ModelDescr, InvalidDescr]:
    """Convert model weights to other formats and add them to the model description

    Args:
        output_path: Path to save updated model package to.
        source_format: convert from a specific weights format.
                       Default: choose automatically from any available.
        target_format: convert to a specific weights format.
                       Default: attempt to convert to any missing format.
        verbose: log more (error) output
        allow_tracing: allow conversion to torchscript by tracing if scripting fails.

    Returns:
        A (potentially invalid) model copy stored at `output_path` with added weights if any conversion was possible.

    """
    if not isinstance(model_descr, ModelDescr):
        if model_descr.type == "model" and not isinstance(model_descr, InvalidDescr):
            raise TypeError(
                f"Model format {model_descr.format} is not supported, please update"
                + f" model to format {ModelDescr.implemented_format_version} first."
            )

        raise TypeError(type(model_descr))

    # save model to local folder
    output_path = save_bioimageio_package_as_folder(
        model_descr, output_path=output_path
    )
    # reload from local folder to make sure we do not edit the given model
    model_descr = load_model_description(
        output_path, perform_io_checks=False, format_version="latest"
    )

    if source_format is None:
        available = set(model_descr.weights.available_formats)
    else:
        available = {source_format}

    if target_format is None:
        missing = set(model_descr.weights.missing_formats)
    else:
        missing = {target_format}

    originally_missing = set(missing)

    if "pytorch_state_dict" in available and "torchscript" in missing:
        logger.info(
            "Attempting to convert 'pytorch_state_dict' weights to 'torchscript'."
        )
        from .pytorch_to_torchscript import convert

        try:
            torchscript_weights_path = output_path / "weights_torchscript.pt"
            model_descr.weights.torchscript = convert(
                model_descr,
                output_path=torchscript_weights_path,
                use_tracing=False,
            )
        except Exception as e:
            if verbose:
                traceback.print_exception(type(e), e, e.__traceback__)

            logger.error(e)
        else:
            available.add("torchscript")
            missing.discard("torchscript")

    if allow_tracing and "pytorch_state_dict" in available and "torchscript" in missing:
        logger.info(
            "Attempting to convert 'pytorch_state_dict' weights to 'torchscript' by tracing."
        )
        from .pytorch_to_torchscript import convert

        try:
            torchscript_weights_path = output_path / "weights_torchscript_traced.pt"

            model_descr.weights.torchscript = convert(
                model_descr,
                output_path=torchscript_weights_path,
                use_tracing=True,
            )
        except Exception as e:
            if verbose:
                traceback.print_exception(type(e), e, e.__traceback__)

            logger.error(e)
        else:
            available.add("torchscript")
            missing.discard("torchscript")

    if "pytorch_state_dict" in available and "onnx" in missing:
        logger.info("Attempting to convert 'pytorch_state_dict' weights to 'onnx'.")
        from .pytorch_to_onnx import convert

        try:
            onnx_weights_path = output_path / "weights.onnx"

            model_descr.weights.onnx = convert(
                model_descr,
                output_path=onnx_weights_path,
                verbose=verbose,
            )
        except Exception as e:
            if verbose:
                traceback.print_exception(type(e), e, e.__traceback__)

            logger.error(e)
        else:
            available.add("onnx")
            missing.discard("onnx")

    if "torchscript" in available and "onnx" in missing:
        logger.info("Attempting to convert 'torchscript' weights to 'onnx'.")
        from .torchscript_to_onnx import convert

        try:
            onnx_weights_path = output_path / "weights.onnx"
            model_descr.weights.onnx = convert(
                model_descr,
                output_path=onnx_weights_path,
                verbose=verbose,
            )
        except Exception as e:
            if verbose:
                traceback.print_exception(type(e), e, e.__traceback__)

            logger.error(e)
        else:
            available.add("onnx")
            missing.discard("onnx")

    if missing:
        logger.warning(
            f"Converting from any of the available weights formats {available} to any"
            + f" of {missing} failed or is not yet implemented. Please create an issue"
            + " at https://github.com/bioimage-io/core-bioimage-io-python/issues/new/choose"
            + " if you would like bioimageio.core to support a particular conversion."
        )

    if originally_missing == missing:
        logger.warning("failed to add any converted weights")
        return model_descr
    else:
        logger.info("added weights formats {}", originally_missing - missing)
        # resave model with updated rdf.yaml
        _ = save_bioimageio_package_as_folder(model_descr, output_path=output_path)
        tested_model_descr = load_description_and_test(
            model_descr, format_version="latest", expected_type="model"
        )
        if not isinstance(tested_model_descr, ModelDescr):
            logger.error(
                f"The updated model description at {output_path} did not pass testing."
            )

        return tested_model_descr

build_description ¤

build_description(content: BioimageioYamlContentView, /, *, context: Optional[ValidationContext] = None, format_version: Literal['latest']) -> Union[LatestResourceDescr, InvalidDescr]
build_description(content: BioimageioYamlContentView, /, *, context: Optional[ValidationContext] = None, format_version: Union[FormatVersionPlaceholder, str] = DISCOVER) -> Union[ResourceDescr, InvalidDescr]
build_description(content: BioimageioYamlContentView, /, *, context: Optional[ValidationContext] = None, format_version: Union[FormatVersionPlaceholder, str] = DISCOVER) -> Union[ResourceDescr, InvalidDescr]

build a bioimage.io resource description from an RDF's content.

Use load_description if you want to build a resource description from an rdf.yaml or bioimage.io zip-package.

Parameters:

Name Type Description Default

content ¤

BioimageioYamlContentView

loaded rdf.yaml file (loaded with YAML, not bioimageio.spec)

required

context ¤

Optional[ValidationContext]

validation context to use during validation

None

format_version ¤

Union[FormatVersionPlaceholder, str]

(optional) use this argument to load the resource and convert its metadata to a higher format_version. Note: - Use "latest" to convert to the latest available format version. - Use "discover" to use the format version specified in the RDF. - Only considers major.minor format version, ignores patch version. - Conversion to lower format versions is not supported.

DISCOVER

Returns:

Type Description
Union[ResourceDescr, InvalidDescr]

An object holding all metadata of the bioimage.io resource

Source code in bioimageio/spec/_description.py
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
def build_description(
    content: BioimageioYamlContentView,
    /,
    *,
    context: Optional[ValidationContext] = None,
    format_version: Union[FormatVersionPlaceholder, str] = DISCOVER,
) -> Union[ResourceDescr, InvalidDescr]:
    """build a bioimage.io resource description from an RDF's content.

    Use `load_description` if you want to build a resource description from an rdf.yaml
    or bioimage.io zip-package.

    Args:
        content: loaded rdf.yaml file (loaded with YAML, not bioimageio.spec)
        context: validation context to use during validation
        format_version:
            (optional) use this argument to load the resource and
            convert its metadata to a higher format_version.
            Note:
            - Use "latest" to convert to the latest available format version.
            - Use "discover" to use the format version specified in the RDF.
            - Only considers major.minor format version, ignores patch version.
            - Conversion to lower format versions is not supported.

    Returns:
        An object holding all metadata of the bioimage.io resource

    """

    return build_description_impl(
        content,
        context=context,
        format_version=format_version,
        get_rd_class=_get_rd_class,
    )

compute_dataset_measures ¤

compute_dataset_measures(measures: Iterable[DatasetMeasure], dataset: Iterable[Sample]) -> Dict[DatasetMeasure, MeasureValue]

compute all dataset measures for the given dataset

Source code in src/bioimageio/core/stat_calculators.py
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
def compute_dataset_measures(
    measures: Iterable[DatasetMeasure], dataset: Iterable[Sample]
) -> Dict[DatasetMeasure, MeasureValue]:
    """compute all dataset `measures` for the given `dataset`"""
    sample_calculators, calculators = get_measure_calculators(measures)
    assert not sample_calculators

    ret: Dict[DatasetMeasure, MeasureValue] = {}

    for sample in dataset:
        for calc in calculators:
            calc.update(sample)

    for calc in calculators:
        ret.update(calc.finalize().items())

    return ret

compute_measures ¤

compute_measures(measures: Iterable[Measure], dataset: Iterable[Sample]) -> Dict[Measure, MeasureValue]

compute all measures for the given dataset sample measures are computed for the last sample in dataset

Source code in src/bioimageio/core/stat_calculators.py
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
def compute_measures(
    measures: Iterable[Measure], dataset: Iterable[Sample]
) -> Dict[Measure, MeasureValue]:
    """compute all `measures` for the given `dataset`
    sample measures are computed for the last sample in `dataset`"""
    sample_calculators, dataset_calculators = get_measure_calculators(measures)
    ret: Dict[Measure, MeasureValue] = {}
    sample = None
    for sample in dataset:
        for calc in dataset_calculators:
            calc.update(sample)
    if sample is None:
        raise ValueError("empty dataset")

    for calc in dataset_calculators:
        ret.update(calc.finalize().items())

    for calc in sample_calculators:
        ret.update(calc.compute(sample).items())

    return ret

compute_sample_measures ¤

compute_sample_measures(measures: Iterable[SampleMeasure], sample: Sample) -> Dict[SampleMeasure, MeasureValue]

compute all sample measures for the given sample

Source code in src/bioimageio/core/stat_calculators.py
596
597
598
599
600
601
602
603
604
605
606
607
def compute_sample_measures(
    measures: Iterable[SampleMeasure], sample: Sample
) -> Dict[SampleMeasure, MeasureValue]:
    """compute all sample `measures` for the given `sample`"""
    calculators, dataset_calculators = get_measure_calculators(measures)
    assert not dataset_calculators
    ret: Dict[SampleMeasure, MeasureValue] = {}

    for calc in calculators:
        ret.update(calc.compute(sample).items())

    return ret

create_model_adapter ¤

create_model_adapter(model_description: Union[v0_4.ModelDescr, v0_5.ModelDescr], *, devices: Optional[Sequence[str]] = None, weight_format_priority_order: Optional[Sequence[SupportedWeightsFormat]] = None)

Creates model adapter for model_descritption

Source code in src/bioimageio/core/backends/__init__.py
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
def create_model_adapter(
    model_description: Union[v0_4.ModelDescr, v0_5.ModelDescr],
    *,
    devices: Optional[Sequence[str]] = None,
    weight_format_priority_order: Optional[Sequence[SupportedWeightsFormat]] = None,
):
    """Creates model adapter for `model_descritption`"""
    if not isinstance(model_description, (v0_4.ModelDescr, v0_5.ModelDescr)):
        raise TypeError(
            f"expected v0_4.ModelDescr or v0_5.ModelDescr, but got {type(model_description)}"
        )

    weights = model_description.weights
    errors: List[Exception] = []
    weight_format_priority_order = (
        DEFAULT_WEIGHT_FORMAT_PRIORITY_ORDER
        if weight_format_priority_order is None
        else weight_format_priority_order
    )
    # limit weight formats to the ones present
    weight_format_priority_order_present: Sequence[SupportedWeightsFormat] = [
        w for w in weight_format_priority_order if getattr(weights, w, None) is not None
    ]
    if not weight_format_priority_order_present:
        raise ValueError(
            f"None of the specified weight formats ({weight_format_priority_order}) is present ({weight_format_priority_order_present})"
        )

    for wf in weight_format_priority_order_present:
        if wf == "pytorch_state_dict":
            assert weights.pytorch_state_dict is not None
            try:
                from .pytorch_backend import PytorchModelAdapter

                return PytorchModelAdapter(model_description, devices=devices)
            except Exception as e:
                errors.append(e)
        elif wf == "tensorflow_saved_model_bundle":
            assert weights.tensorflow_saved_model_bundle is not None
            try:
                from .tensorflow_backend import create_tf_model_adapter

                return create_tf_model_adapter(model_description, devices=devices)
            except Exception as e:
                errors.append(e)
        elif wf == "onnx":
            assert weights.onnx is not None
            try:
                from .onnx_backend import ONNXModelAdapter

                return ONNXModelAdapter(model_description, devices=devices)
            except Exception as e:
                errors.append(e)
        elif wf == "torchscript":
            assert weights.torchscript is not None
            try:
                from .torchscript_backend import TorchscriptModelAdapter

                return TorchscriptModelAdapter(model_description, devices=devices)
            except Exception as e:
                errors.append(e)
        elif wf == "keras_hdf5":
            assert weights.keras_hdf5 is not None
            # keras can either be installed as a separate package or used as part of tensorflow
            # we try to first import the keras model adapter using the separate package and,
            # if it is not available, try to load the one using tf
            try:
                try:
                    from .keras_backend import KerasModelAdapter
                except Exception:
                    from .tensorflow_backend import KerasModelAdapter

                return KerasModelAdapter(model_description, devices=devices)
            except Exception as e:
                errors.append(e)
        elif wf == "keras_v3":
            assert not isinstance(weights, v0_4.WeightsDescr), (
                "keras_v3 weights not supported for v0.4 specs"
            )
            assert weights.keras_v3 is not None
            try:
                from .keras_backend import KerasModelAdapter

                return KerasModelAdapter(model_description, devices=devices)
            except Exception as e:
                errors.append(e)
        else:
            assert_never(wf)

    assert errors
    if len(weight_format_priority_order) == 1:
        assert len(errors) == 1
        raise errors[0]

    else:
        msg = (
            "None of the weight format specific model adapters could be created"
            + " in this environment."
        )
        raise ExceptionGroup(msg, errors)

create_prediction_pipeline ¤

create_prediction_pipeline(bioimageio_model: AnyModelDescr, *, devices: Optional[Sequence[str]] = None, weight_format: Optional[SupportedWeightsFormat] = None, weights_format: Optional[SupportedWeightsFormat] = None, dataset_for_initial_statistics: Iterable[Union[Sample, Sequence[Tensor]]] = tuple(), keep_updating_initial_dataset_statistics: bool = False, fixed_dataset_statistics: Mapping[Measure, MeasureValue] = MappingProxyType({}), model_adapter: Optional[ModelAdapter] = None, ns: Optional[BlocksizeParameter] = None, default_blocksize_parameter: BlocksizeParameter = 10, preceding_prediction_pipelines: Optional[Sequence[Union[PredictionPipeline, RemotePredictionPipeline]]] = None, **deprecated_kwargs: Any) -> PredictionPipeline

Creates prediction pipeline which includes: * computation of input statistics * preprocessing * model prediction * computation of output statistics * postprocessing

Parameters:

Name Type Description Default

bioimageio_model ¤

AnyModelDescr

A bioimageio model description.

required

devices ¤

Optional[Sequence[str]]

(optional)

None

weight_format ¤

Optional[SupportedWeightsFormat]

deprecated in favor of weights_format

None

weights_format ¤

Optional[SupportedWeightsFormat]

(optional) Use a specific weights_format rather than choosing one automatically. A corresponding bioimageio.core.model_adapters.ModelAdapter will be created to run inference with the bioimageio_model.

None

dataset_for_initial_statistics ¤

Iterable[Union[Sample, Sequence[Tensor]]]

(optional) If preprocessing steps require input dataset statistics, dataset_for_initial_statistics allows you to specifcy a dataset from which these statistics are computed.

tuple()

keep_updating_initial_dataset_statistics ¤

bool

(optional) Set to True if you want to update dataset statistics with each processed sample.

False

fixed_dataset_statistics ¤

Mapping[Measure, MeasureValue]

(optional) Precomputed dataset (and optionally sample) statistics. Any included sample statistics will not be calculated on the fly and it is the callers responsibility to use samples with the corresponding statistics availble in sample.stat.

MappingProxyType({})

model_adapter ¤

Optional[ModelAdapter]

(optional) Allows you to use a custom model_adapter instead of creating one according to the present/selected weights_format.

None

ns ¤

Optional[BlocksizeParameter]

deprecated in favor of default_blocksize_parameter

None

default_blocksize_parameter ¤

BlocksizeParameter

Allows to control the default block size for blockwise predictions, see BlocksizeParameter.

10

preceding_prediction_pipelines ¤

Optional[Sequence[Union[PredictionPipeline, RemotePredictionPipeline]]]

(optional) If the model has inputs that are outputs of other models (input field 'output_of'), you can provide a sequence of preceding prediction pipelines. The prediction pipeline will then automatically use the outputs of those preceding pipelines as inputs for the current model. If no preceding prediction pipelines for a model are provided, prediction pipelines using the same devices and weight format as for the current model will be created for any required preceding models.

None
Source code in src/bioimageio/core/_prediction_pipeline.py
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
def create_prediction_pipeline(
    bioimageio_model: AnyModelDescr,
    *,
    devices: Optional[Sequence[str]] = None,
    weight_format: Optional[SupportedWeightsFormat] = None,
    weights_format: Optional[SupportedWeightsFormat] = None,
    dataset_for_initial_statistics: Iterable[Union[Sample, Sequence[Tensor]]] = tuple(),
    keep_updating_initial_dataset_statistics: bool = False,
    fixed_dataset_statistics: Mapping[Measure, MeasureValue] = MappingProxyType({}),
    model_adapter: Optional[ModelAdapter] = None,
    ns: Optional[BlocksizeParameter] = None,
    default_blocksize_parameter: BlocksizeParameter = 10,  # TODO: default to None and find smart blocksize params per axis to reduce overlap of blocks with large halo
    preceding_prediction_pipelines: Optional[
        Sequence[Union[PredictionPipeline, RemotePredictionPipeline]]
    ] = None,
    **deprecated_kwargs: Any,
) -> PredictionPipeline:
    """
    Creates prediction pipeline which includes:
    * computation of input statistics
    * preprocessing
    * model prediction
    * computation of output statistics
    * postprocessing

    Args:
        bioimageio_model: A bioimageio model description.
        devices: (optional)
        weight_format: deprecated in favor of **weights_format**
        weights_format: (optional) Use a specific **weights_format** rather than
            choosing one automatically.
            A corresponding `bioimageio.core.model_adapters.ModelAdapter` will be
            created to run inference with the **bioimageio_model**.
        dataset_for_initial_statistics: (optional) If preprocessing steps require input
            dataset statistics, **dataset_for_initial_statistics** allows you to
            specifcy a dataset from which these statistics are computed.
        keep_updating_initial_dataset_statistics: (optional) Set to `True` if you want
            to update dataset statistics with each processed sample.
        fixed_dataset_statistics: (optional) Precomputed dataset (and optionally sample) statistics.
            Any included sample statistics will not be calculated on the fly and it is the callers
            responsibility to use samples with the corresponding statistics availble in `sample.stat`.
        model_adapter: (optional) Allows you to use a custom **model_adapter** instead
            of creating one according to the present/selected **weights_format**.
        ns: deprecated in favor of **default_blocksize_parameter**
        default_blocksize_parameter: Allows to control the default block size for
            blockwise predictions, see `BlocksizeParameter`.
        preceding_prediction_pipelines: (optional) If the model has inputs that are
            outputs of other models (input field 'output_of'), you can provide a sequence
            of preceding prediction pipelines. The prediction pipeline will then automatically
            use the outputs of those preceding pipelines as inputs for the current model.
            If no preceding prediction pipelines for a model are provided, prediction pipelines using the
            same devices and weight format as for the current model will be created for any required preceding models.
    """
    weights_format = weight_format or weights_format
    del weight_format
    default_blocksize_parameter = ns or default_blocksize_parameter
    del ns
    if deprecated_kwargs:
        warnings.warn(
            f"deprecated create_prediction_pipeline kwargs: {set(deprecated_kwargs)}"
        )

    model_adapter = model_adapter or create_model_adapter(
        model_description=bioimageio_model,
        devices=devices,
        weight_format_priority_order=weights_format and (weights_format,),
    )

    input_ids = get_member_ids(bioimageio_model.inputs)

    def dataset():
        common_stat: Stat = {}
        for i, x in enumerate(dataset_for_initial_statistics):
            if isinstance(x, Sample):
                yield x
            else:
                yield Sample(members=dict(zip(input_ids, x)), stat=common_stat, id=i)

    preprocessing, postprocessing = setup_pre_and_postprocessing(
        bioimageio_model,
        dataset(),
        keep_updating_initial_dataset_stats=keep_updating_initial_dataset_statistics,
        fixed_dataset_stats=fixed_dataset_statistics,
    )

    def _get_preceding_model_ids(model: AnyModelDescr) -> Set[v0_5.ModelId]:
        return {
            input_descr.output_of
            for input_descr in model.inputs
            if isinstance(input_descr, v0_5.InputTensorDescr)
            and input_descr.output_of is not None
        }

    preceding_model_ids = _get_preceding_model_ids(bioimageio_model)
    if preceding_prediction_pipelines is None:
        preceding_prediction_pipelines = []
    else:
        preceding_prediction_pipelines = list(preceding_prediction_pipelines)

    for preceding_model_id in preceding_model_ids:
        if preceding_model_id in {
            pp.model_description.id for pp in preceding_prediction_pipelines
        }:
            continue

        preceding_model = load_model_description(preceding_model_id)
        preceding_prediction_pipelines.insert(
            0,
            create_prediction_pipeline(
                preceding_model,
                devices=devices,
                weights_format=weights_format,
                default_blocksize_parameter=default_blocksize_parameter,
                dataset_for_initial_statistics=dataset_for_initial_statistics,
                keep_updating_initial_dataset_statistics=keep_updating_initial_dataset_statistics,
                fixed_dataset_statistics=fixed_dataset_statistics,
            ),
        )

    return PredictionPipeline(
        name=bioimageio_model.name,
        model_description=bioimageio_model,
        model_adapter=model_adapter,
        preprocessing=preprocessing,
        postprocessing=postprocessing,
        default_blocksize_parameter=default_blocksize_parameter,
        preceding_prediction_pipelines=preceding_prediction_pipelines,
    )

create_remote_prediction_pipeline ¤

create_remote_prediction_pipeline(model_description: AnyModelDescr, *, server: Optional[str] = None, server_type: Optional[Literal['gradio']] = 'gradio', precomputed_statistics: Mapping[Measure, MeasureValue] = MappingProxyType({}), default_blocksize_parameter: BlocksizeParameter = 10, default_batch_size: int = 1) -> RemotePredictionPipeline

Create a RemotePredictionPipeline for the given model_description.

Parameters:

Name Type Description Default

model_description ¤

AnyModelDescr

The model to run inference with.

required

server ¤

Optional[str]

The URL or Hugging Face space name of a running bioimageio server instance

None

server_type ¤

Optional[Literal['gradio']]

The type of the remote server to connect to. Currently only "gradio" is supported.

'gradio'

precomputed_statistics ¤

Mapping[Measure, MeasureValue]

Precomputed dataset (and optionally sample) statistics. Any included sample statistics will not be calculated on the fly and it is the callers responsibility to use samples with the corresponding statistics availble in sample.stat.

MappingProxyType({})

default_blocksize_parameter ¤

BlocksizeParameter

Allows to control the default block size with a single parameter for blockwise predictions. (not all models support this)

10

default_batch_size ¤

int

Default batch size to use

1
Source code in src/bioimageio/core/_prediction_pipeline.py
 974
 975
 976
 977
 978
 979
 980
 981
 982
 983
 984
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
def create_remote_prediction_pipeline(
    model_description: AnyModelDescr,
    *,
    server: Optional[str] = None,
    server_type: Optional[Literal["gradio"]] = "gradio",
    precomputed_statistics: Mapping[Measure, MeasureValue] = MappingProxyType({}),
    default_blocksize_parameter: BlocksizeParameter = 10,  # TODO: default to None and find smart blocksize params per axis to reduce overlap of blocks with large halo
    default_batch_size: int = 1,
) -> RemotePredictionPipeline:
    """Create a `RemotePredictionPipeline` for the given `model_description`.

    Args:
        model_description: The model to run inference with.
        server: The URL or Hugging Face space name of a running bioimageio server instance
        server_type: The type of the remote server to connect to. Currently only "gradio" is supported.
        precomputed_statistics: Precomputed dataset (and optionally sample) statistics.
            Any included sample statistics will not be calculated on the fly and it is the callers
            responsibility to use samples with the corresponding statistics availble in `sample.stat`.
        default_blocksize_parameter: Allows to control the default block size with a single parameter for blockwise predictions. (not all models support this)
        default_batch_size: Default batch size to use
    """

    if server_type is None:
        server_type = "gradio"

    try:
        if server_type == "gradio":
            from .remote_backends.gradio.client import (
                GradioPredictionPipeline as RemotePredictionPipelineImpl,
            )
        else:
            assert_never(server_type)
    except ImportError as e:
        raise ImportError(
            f"Failed to import {server_type.capitalize()}PredictionPipeline. Make sure to install the '{server_type}-client' extra,"
            + f" e.g. with `pip install bioimageio.core[{server_type}-client]`."
        ) from e

    return RemotePredictionPipelineImpl(
        model_description,
        server=server,
        precomputed_statistics=precomputed_statistics,
        default_blocksize_parameter=default_blocksize_parameter,
        default_batch_size=default_batch_size,
    )

dump_description ¤

dump_description(rd: Union[ResourceDescr, InvalidDescr], /, *, exclude_unset: bool = True, exclude_defaults: bool = False) -> BioimageioYamlContent

Converts a resource to a dictionary containing only simple types that can directly be serialzed to YAML.

Parameters:

Name Type Description Default

rd ¤

Union[ResourceDescr, InvalidDescr]

bioimageio resource description

required

exclude_unset ¤

bool

Exclude fields that have not explicitly be set.

True

exclude_defaults ¤

bool

Exclude fields that have the default value (even if set explicitly).

False
Source code in bioimageio/spec/_description.py
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
def dump_description(
    rd: Union[ResourceDescr, InvalidDescr],
    /,
    *,
    exclude_unset: bool = True,
    exclude_defaults: bool = False,
) -> BioimageioYamlContent:
    """Converts a resource to a dictionary containing only simple types that can directly be serialzed to YAML.

    Args:
        rd: bioimageio resource description
        exclude_unset: Exclude fields that have not explicitly be set.
        exclude_defaults: Exclude fields that have the default value (even if set explicitly).
    """
    return rd.model_dump(
        mode="json", exclude_unset=exclude_unset, exclude_defaults=exclude_defaults
    )

enable_determinism ¤

enable_determinism(mode: Literal['seed_only', 'full'] = 'full', weight_formats: Optional[Sequence[SupportedWeightsFormat]] = None)

Seed and configure ML frameworks for maximum reproducibility. May degrade performance. Only recommended for testing reproducibility!

Seed any random generators and (if mode=="full") request ML frameworks to use deterministic algorithms.

Parameters:

Name Type Description Default

mode ¤

Literal['seed_only', 'full']

determinism mode - 'seed_only' -- only set seeds, or - 'full' determinsm features (might degrade performance or throw exceptions)

'full'

weight_formats ¤

Optional[Sequence[SupportedWeightsFormat]]

Limit deep learning importing deep learning frameworks based on weight_formats. E.g. this allows to avoid importing tensorflow when testing with pytorch.

None
Notes
  • mode == "full" might degrade performance or throw exceptions.
  • Subsequent inference calls might still differ. Call before each function (sequence) that is expected to be reproducible.
  • Degraded performance: Use for testing reproducibility only!
  • Recipes:
Source code in src/bioimageio/core/_resource_tests.py
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
def enable_determinism(
    mode: Literal["seed_only", "full"] = "full",
    weight_formats: Optional[Sequence[SupportedWeightsFormat]] = None,
):
    """Seed and configure ML frameworks for maximum reproducibility.
    May degrade performance. Only recommended for testing reproducibility!

    Seed any random generators and (if **mode**=="full") request ML frameworks to use
    deterministic algorithms.

    Args:
        mode: determinism mode
            - 'seed_only' -- only set seeds, or
            - 'full' determinsm features (might degrade performance or throw exceptions)
        weight_formats: Limit deep learning importing deep learning frameworks
            based on weight_formats.
            E.g. this allows to avoid importing tensorflow when testing with pytorch.

    Notes:
        - **mode** == "full"  might degrade performance or throw exceptions.
        - Subsequent inference calls might still differ. Call before each function
          (sequence) that is expected to be reproducible.
        - Degraded performance: Use for testing reproducibility only!
        - Recipes:
            - [PyTorch](https://pytorch.org/docs/stable/notes/randomness.html)
            - [Keras](https://keras.io/examples/keras_recipes/reproducibility_recipes/)
            - [NumPy](https://numpy.org/doc/2.0/reference/random/generated/numpy.random.seed.html)
    """
    try:
        try:
            import numpy.random
        except ImportError:
            pass
        else:
            numpy.random.seed(0)
    except Exception as e:
        logger.debug(str(e))

    if (
        weight_formats is None
        or "pytorch_state_dict" in weight_formats
        or "torchscript" in weight_formats
    ):
        try:
            try:
                import torch
            except ImportError:
                pass
            else:
                _ = torch.manual_seed(0)
                torch.use_deterministic_algorithms(mode == "full")
        except Exception as e:
            logger.debug(str(e))

    if (
        weight_formats is None
        or "tensorflow_saved_model_bundle" in weight_formats
        or "keras_hdf5" in weight_formats
    ):
        try:
            os.environ["TF_ENABLE_ONEDNN_OPTS"] = "0"
            try:
                import tensorflow as tf
            except ImportError:
                pass
            else:
                tf.random.set_seed(0)
                if mode == "full":
                    tf.config.experimental.enable_op_determinism()
                # TODO: find possibility to switch it off again??
        except Exception as e:
            logger.debug(str(e))

    if weight_formats is None or "keras_hdf5" in weight_formats:
        try:
            try:
                import keras  # pyright: ignore[reportMissingTypeStubs]
            except ImportError:
                pass
            else:
                keras.utils.set_random_seed(0)
        except Exception as e:
            logger.debug(str(e))

load_dataset_description ¤

load_dataset_description(source: Union[PermissiveFileSource, ZipFile], /, *, format_version: Literal['latest'], perform_io_checks: Optional[bool] = None, known_files: Optional[Dict[str, Optional[Sha256]]] = None, sha256: Optional[Sha256] = None) -> DatasetDescr
load_dataset_description(source: Union[PermissiveFileSource, ZipFile], /, *, format_version: Union[FormatVersionPlaceholder, str] = DISCOVER, perform_io_checks: Optional[bool] = None, known_files: Optional[Dict[str, Optional[Sha256]]] = None, sha256: Optional[Sha256] = None) -> AnyDatasetDescr
load_dataset_description(source: Union[PermissiveFileSource, ZipFile], /, *, format_version: Union[FormatVersionPlaceholder, str] = DISCOVER, perform_io_checks: Optional[bool] = None, known_files: Optional[Dict[str, Optional[Sha256]]] = None, sha256: Optional[Sha256] = None) -> AnyDatasetDescr

same as load_description, but addtionally ensures that the loaded description is valid and of type 'dataset'.

Source code in bioimageio/spec/_io.py
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
def load_dataset_description(
    source: Union[PermissiveFileSource, ZipFile],
    /,
    *,
    format_version: Union[FormatVersionPlaceholder, str] = DISCOVER,
    perform_io_checks: Optional[bool] = None,
    known_files: Optional[Dict[str, Optional[Sha256]]] = None,
    sha256: Optional[Sha256] = None,
) -> AnyDatasetDescr:
    """same as `load_description`, but addtionally ensures that the loaded
    description is valid and of type 'dataset'.
    """
    rd = load_description(
        source,
        format_version=format_version,
        perform_io_checks=perform_io_checks,
        known_files=known_files,
        sha256=sha256,
    )
    return ensure_description_is_dataset(rd)

load_description ¤

load_description(source: Union[PermissiveFileSource, ZipFile], /, *, format_version: Literal['latest'], perform_io_checks: Optional[bool] = None, known_files: Optional[Dict[str, Optional[Sha256]]] = None, sha256: Optional[Sha256] = None) -> Union[LatestResourceDescr, InvalidDescr]
load_description(source: Union[PermissiveFileSource, ZipFile], /, *, format_version: Union[FormatVersionPlaceholder, str] = DISCOVER, perform_io_checks: Optional[bool] = None, known_files: Optional[Dict[str, Optional[Sha256]]] = None, sha256: Optional[Sha256] = None) -> Union[ResourceDescr, InvalidDescr]
load_description(source: Union[PermissiveFileSource, ZipFile], /, *, format_version: Union[FormatVersionPlaceholder, str] = DISCOVER, perform_io_checks: Optional[bool] = None, known_files: Optional[Dict[str, Optional[Sha256]]] = None, sha256: Optional[Sha256] = None) -> Union[ResourceDescr, InvalidDescr]

load a bioimage.io resource description

Parameters:

Name Type Description Default

source ¤

Union[PermissiveFileSource, ZipFile]

Path or URL to an rdf.yaml or a bioimage.io package (zip-file with rdf.yaml in it).

required

format_version ¤

Union[FormatVersionPlaceholder, str]

(optional) Use this argument to load the resource and convert its metadata to a higher format_version. Note: - Use "latest" to convert to the latest available format version. - Use "discover" to use the format version specified in the RDF. - Only considers major.minor format version, ignores patch version. - Conversion to lower format versions is not supported.

DISCOVER

perform_io_checks ¤

Optional[bool]

Wether or not to perform validation that requires file io, e.g. downloading a remote files. The existence of local absolute file paths is still being checked.

None

known_files ¤

Optional[Dict[str, Optional[Sha256]]]

Allows to bypass download and hashing of referenced files (even if perform_io_checks is True).

Keys should be file paths or URL strings as they appear in the bioimageio.yaml file.

Values are Sha256 values compared to hash values in the description. For None values no hash value comparison is performed.

If perfrom_io_checks is True, checked files will be added to this dictionary with their SHA-256 value.

If perform_io_checks is False and known_files is not empty, missing, 'unknown' file references are considered invalid.

None

sha256 ¤

Optional[Sha256]

Optional SHA-256 value of source

None

Returns:

Type Description
Union[ResourceDescr, InvalidDescr]

An object holding all metadata of the bioimage.io resource

Source code in bioimageio/spec/_io.py
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
def load_description(
    source: Union[PermissiveFileSource, ZipFile],
    /,
    *,
    format_version: Union[FormatVersionPlaceholder, str] = DISCOVER,
    perform_io_checks: Optional[bool] = None,
    known_files: Optional[Dict[str, Optional[Sha256]]] = None,
    sha256: Optional[Sha256] = None,
) -> Union[ResourceDescr, InvalidDescr]:
    """load a bioimage.io resource description

    Args:
        source:
            Path or URL to an rdf.yaml or a bioimage.io package
            (zip-file with rdf.yaml in it).
        format_version:
            (optional) Use this argument to load the resource and
            convert its metadata to a higher format_version.
            Note:
            - Use "latest" to convert to the latest available format version.
            - Use "discover" to use the format version specified in the RDF.
            - Only considers major.minor format version, ignores patch version.
            - Conversion to lower format versions is not supported.
        perform_io_checks:
            Wether or not to perform validation that requires file io,
            e.g. downloading a remote files. The existence of local
            absolute file paths is still being checked.
        known_files:
            Allows to bypass download and hashing of referenced files
            (even if perform_io_checks is True).

            Keys should be file paths or URL strings as they appear in the
            bioimageio.yaml file.

            Values are Sha256 values compared to hash values in the description.
            For `None` values no hash value comparison is performed.

            If `perfrom_io_checks` is True, checked files will be added to
            this dictionary with their SHA-256 value.

            If `perform_io_checks` is False and `known_files` is not empty,
            missing, 'unknown' file references are considered invalid.
        sha256:
            Optional SHA-256 value of **source**

    Returns:
        An object holding all metadata of the bioimage.io resource

    """
    if isinstance(source, ResourceDescrBase):
        name = getattr(source, "name", f"{str(source)[:10]}...")
        logger.warning("returning already loaded description '{}' as is", name)
        return source  # pyright: ignore[reportReturnType]

    opened = open_bioimageio_yaml(source, sha256=sha256)

    context = get_validation_context().replace(
        root=opened.original_root,
        file_name=opened.original_file_name,
        original_source_name=opened.original_source_name,
        perform_io_checks=perform_io_checks,
        known_files=known_files,
    )

    return build_description(
        opened.content,
        context=context,
        format_version=format_version,
    )

load_description_and_test ¤

load_description_and_test(source: Union[ResourceDescr, PermissiveFileSource, BioimageioYamlContent], *, format_version: Literal['latest'], weight_format: Optional[SupportedWeightsFormat] = None, devices: Optional[Sequence[str]] = None, determinism: Literal['seed_only', 'full'] = 'seed_only', expected_type: Literal['model'], sha256: Optional[Sha256] = None, stop_early: bool = False, working_dir: Optional[Union[os.PathLike[str], str]] = None, **deprecated: Unpack[DeprecatedKwargs]) -> Union[ModelDescr, InvalidDescr]
load_description_and_test(source: Union[ResourceDescr, PermissiveFileSource, BioimageioYamlContent], *, format_version: Literal['latest'], weight_format: Optional[SupportedWeightsFormat] = None, devices: Optional[Sequence[str]] = None, determinism: Literal['seed_only', 'full'] = 'seed_only', expected_type: Literal['dataset'], sha256: Optional[Sha256] = None, stop_early: bool = False, working_dir: Optional[Union[os.PathLike[str], str]] = None, **deprecated: Unpack[DeprecatedKwargs]) -> Union[DatasetDescr, InvalidDescr]
load_description_and_test(source: Union[ResourceDescr, PermissiveFileSource, BioimageioYamlContent], *, format_version: Literal['latest'], weight_format: Optional[SupportedWeightsFormat] = None, devices: Optional[Sequence[str]] = None, determinism: Literal['seed_only', 'full'] = 'seed_only', expected_type: Optional[str] = None, sha256: Optional[Sha256] = None, stop_early: bool = False, working_dir: Optional[Union[os.PathLike[str], str]] = None, **deprecated: Unpack[DeprecatedKwargs]) -> Union[LatestResourceDescr, InvalidDescr]
load_description_and_test(source: Union[ResourceDescr, PermissiveFileSource, BioimageioYamlContent], *, format_version: Union[FormatVersionPlaceholder, str] = DISCOVER, weight_format: Optional[SupportedWeightsFormat] = None, devices: Optional[Sequence[str]] = None, determinism: Literal['seed_only', 'full'] = 'seed_only', expected_type: Literal['model'], sha256: Optional[Sha256] = None, stop_early: bool = False, working_dir: Optional[Union[os.PathLike[str], str]] = None, **deprecated: Unpack[DeprecatedKwargs]) -> Union[AnyModelDescr, InvalidDescr]
load_description_and_test(source: Union[ResourceDescr, PermissiveFileSource, BioimageioYamlContent], *, format_version: Union[FormatVersionPlaceholder, str] = DISCOVER, weight_format: Optional[SupportedWeightsFormat] = None, devices: Optional[Sequence[str]] = None, determinism: Literal['seed_only', 'full'] = 'seed_only', expected_type: Literal['dataset'], sha256: Optional[Sha256] = None, stop_early: bool = False, working_dir: Optional[Union[os.PathLike[str], str]] = None, **deprecated: Unpack[DeprecatedKwargs]) -> Union[AnyDatasetDescr, InvalidDescr]
load_description_and_test(source: Union[ResourceDescr, PermissiveFileSource, BioimageioYamlContent], *, format_version: Union[FormatVersionPlaceholder, str] = DISCOVER, weight_format: Optional[SupportedWeightsFormat] = None, devices: Optional[Sequence[str]] = None, determinism: Literal['seed_only', 'full'] = 'seed_only', expected_type: Optional[str] = None, sha256: Optional[Sha256] = None, stop_early: bool = False, working_dir: Optional[Union[os.PathLike[str], str]] = None, **deprecated: Unpack[DeprecatedKwargs]) -> Union[ResourceDescr, InvalidDescr]
load_description_and_test(source: Union[ResourceDescr, PermissiveFileSource, BioimageioYamlContent], *, format_version: Union[FormatVersionPlaceholder, str] = DISCOVER, weight_format: Optional[SupportedWeightsFormat] = None, devices: Optional[Sequence[str]] = None, determinism: Literal['seed_only', 'full'] = 'seed_only', expected_type: Optional[str] = None, sha256: Optional[Sha256] = None, stop_early: bool = False, working_dir: Optional[Union[os.PathLike[str], str]] = None, **deprecated: Unpack[DeprecatedKwargs]) -> Union[ResourceDescr, InvalidDescr]

Test a bioimage.io resource dynamically, for example run prediction of test tensors for models.

See test_description for more details.

Returns:

Type Description
Union[ResourceDescr, InvalidDescr]

A (possibly invalid) resource description object with a populated .validation_summary attribute.

Source code in src/bioimageio/core/_resource_tests.py
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
def load_description_and_test(
    source: Union[ResourceDescr, PermissiveFileSource, BioimageioYamlContent],
    *,
    format_version: Union[FormatVersionPlaceholder, str] = DISCOVER,
    weight_format: Optional[SupportedWeightsFormat] = None,
    devices: Optional[Sequence[str]] = None,
    determinism: Literal["seed_only", "full"] = "seed_only",
    expected_type: Optional[str] = None,
    sha256: Optional[Sha256] = None,
    stop_early: bool = False,
    working_dir: Optional[Union[os.PathLike[str], str]] = None,
    **deprecated: Unpack[DeprecatedKwargs],
) -> Union[ResourceDescr, InvalidDescr]:
    """Test a bioimage.io resource dynamically,
    for example run prediction of test tensors for models.

    See `test_description` for more details.

    Returns:
        A (possibly invalid) resource description object
        with a populated `.validation_summary` attribute.
    """
    if isinstance(source, ResourceDescrBase):
        root = source.root
        file_name = source.file_name
        if (
            (
                format_version
                not in (
                    DISCOVER,
                    source.format_version,
                    ".".join(source.format_version.split(".")[:2]),
                )
            )
            or (c := source.validation_summary.details[0].context) is None
            or not c.perform_io_checks
        ):
            logger.debug(
                "deserializing source to ensure we validate and test using format {} and perform io checks",
                format_version,
            )
            source = dump_description(source)
    else:
        root = Path()
        file_name = None

    if isinstance(source, ResourceDescrBase):
        rd = source
    elif isinstance(source, dict):
        # check context for a given root; default to root of source
        context = get_validation_context(
            ValidationContext(root=root, file_name=file_name)
        ).replace(
            perform_io_checks=True  # make sure we perform io checks though
        )

        rd = build_description(
            source,
            format_version=format_version,
            context=context,
        )
    else:
        rd = load_description(
            source, format_version=format_version, sha256=sha256, perform_io_checks=True
        )

    rd.validation_summary.env.add(
        InstalledPackage(name="bioimageio.core", version=__version__)
    )

    if expected_type is not None:
        has_expected_type = _test_expected_resource_type(rd, expected_type)
        if not has_expected_type:
            # unexpected type -> invalid format
            rd.validation_summary.status = "failed"
            return rd

    # elevate status valid-format to passed and start testing
    if rd.validation_summary.status == "valid-format":
        rd.validation_summary.status = "passed"

    if isinstance(rd, (v0_4.ModelDescr, v0_5.ModelDescr)):
        if weight_format is None:
            weight_formats: List[SupportedWeightsFormat] = [
                w for w, we in rd.weights if we is not None
            ]  # pyright: ignore[reportAssignmentType]
        else:
            weight_formats = [weight_format]

        enable_determinism(determinism, weight_formats=weight_formats)
        for w in weight_formats:
            passed_recreate_test_outputs = _test_recreate_test_outputs(
                rd,
                w,
                devices,
                stop_early=stop_early,
                working_dir=working_dir,
                verbose=working_dir is not None,
                **deprecated,
            )

            if stop_early and not passed_recreate_test_outputs:
                break

            if not isinstance(rd, v0_4.ModelDescr):
                passed_parametrized_inference = _test_parametrized_inference(
                    rd, w, devices, stop_early=stop_early
                )
                if stop_early and not passed_parametrized_inference:
                    break

    # TODO: add execution of jupyter notebooks
    # TODO: add more tests

    return rd

load_description_and_validate_format_only ¤

load_description_and_validate_format_only(source: Union[PermissiveFileSource, ZipFile], /, *, format_version: Union[FormatVersionPlaceholder, str] = DISCOVER, perform_io_checks: Optional[bool] = None, known_files: Optional[Dict[str, Optional[Sha256]]] = None, sha256: Optional[Sha256] = None) -> ValidationSummary

same as load_description, but only return the validation summary.

Returns:

Type Description
ValidationSummary

Validation summary of the bioimage.io resource found at source.

Source code in bioimageio/spec/_io.py
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
def load_description_and_validate_format_only(
    source: Union[PermissiveFileSource, ZipFile],
    /,
    *,
    format_version: Union[FormatVersionPlaceholder, str] = DISCOVER,
    perform_io_checks: Optional[bool] = None,
    known_files: Optional[Dict[str, Optional[Sha256]]] = None,
    sha256: Optional[Sha256] = None,
) -> ValidationSummary:
    """same as `load_description`, but only return the validation summary.

    Returns:
        Validation summary of the bioimage.io resource found at `source`.

    """
    rd = load_description(
        source,
        format_version=format_version,
        perform_io_checks=perform_io_checks,
        known_files=known_files,
        sha256=sha256,
    )
    assert rd.validation_summary is not None
    return rd.validation_summary

load_model_description ¤

load_model_description(source: Union[PermissiveFileSource, ZipFile], /, *, format_version: Literal['latest'], perform_io_checks: Optional[bool] = None, known_files: Optional[Dict[str, Optional[Sha256]]] = None, sha256: Optional[Sha256] = None) -> ModelDescr
load_model_description(source: Union[PermissiveFileSource, ZipFile], /, *, format_version: Union[FormatVersionPlaceholder, str] = DISCOVER, perform_io_checks: Optional[bool] = None, known_files: Optional[Dict[str, Optional[Sha256]]] = None, sha256: Optional[Sha256] = None) -> AnyModelDescr
load_model_description(source: Union[PermissiveFileSource, ZipFile], /, *, format_version: Union[FormatVersionPlaceholder, str] = DISCOVER, perform_io_checks: Optional[bool] = None, known_files: Optional[Dict[str, Optional[Sha256]]] = None, sha256: Optional[Sha256] = None) -> AnyModelDescr

same as load_description, but addtionally ensures that the loaded description is valid and of type 'model'.

Raises:

Type Description
ValueError

for invalid or non-model resources

Source code in bioimageio/spec/_io.py
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
def load_model_description(
    source: Union[PermissiveFileSource, ZipFile],
    /,
    *,
    format_version: Union[FormatVersionPlaceholder, str] = DISCOVER,
    perform_io_checks: Optional[bool] = None,
    known_files: Optional[Dict[str, Optional[Sha256]]] = None,
    sha256: Optional[Sha256] = None,
) -> AnyModelDescr:
    """same as `load_description`, but addtionally ensures that the loaded
    description is valid and of type 'model'.

    Raises:
        ValueError: for invalid or non-model resources
    """
    rd = load_description(
        source,
        format_version=format_version,
        perform_io_checks=perform_io_checks,
        known_files=known_files,
        sha256=sha256,
    )
    return ensure_description_is_model(rd)

predict ¤

predict(*, model: Union[PermissiveFileSource, v0_4.ModelDescr, v0_5.ModelDescr, PredictionPipeline], inputs: Union[Sample, PerMember[TensorSource], TensorSource], sample_id: Hashable = 'sample', blocksize_parameter: Optional[BlocksizeParameter] = None, input_block_shape: Optional[Mapping[MemberId, Mapping[AxisId, int]]] = None, skip_preprocessing: bool = False, skip_postprocessing: bool = False, save_output_path: Optional[Union[Path, str]] = None) -> Sample

Run prediction for a single set of input(s) with a bioimage.io model

Parameters:

Name Type Description Default

model ¤

Union[PermissiveFileSource, v0_4.ModelDescr, v0_5.ModelDescr, PredictionPipeline]

Model to predict with. May be given as RDF source, model description or prediction pipeline.

required

inputs ¤

Union[Sample, PerMember[TensorSource], TensorSource]

the input sample or the named input(s) for this model as a dictionary

required

sample_id ¤

Hashable

the sample id. The sample_id is used to format save_output_path and to distinguish sample specific log messages.

'sample'

blocksize_parameter ¤

Optional[BlocksizeParameter]

(optional) Tile the input into blocks parametrized by blocksize_parameter according to any parametrized axis sizes defined by the model. See bioimageio.spec.model.v0_5.ParameterizedSize for details. Note: For a predetermined, fixed block shape use input_block_shape.

None

input_block_shape ¤

Optional[Mapping[MemberId, Mapping[AxisId, int]]]

(optional) Tile the input sample tensors into blocks. Note: Use blocksize_parameter for a parameterized block shape to run prediction independent of the exact block shape.

None

skip_preprocessing ¤

bool

Flag to skip the model's preprocessing.

False

skip_postprocessing ¤

bool

Flag to skip the model's postprocessing.

False

save_output_path ¤

Optional[Union[Path, str]]

A path with to save the output to. M Must contain: - {output_id} (or {member_id}) if the model has multiple output tensors May contain: - {sample_id} to avoid overwriting recurrent calls

None
Source code in src/bioimageio/core/prediction.py
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
def predict(
    *,
    model: Union[
        PermissiveFileSource, v0_4.ModelDescr, v0_5.ModelDescr, PredictionPipeline
    ],
    inputs: Union[Sample, PerMember[TensorSource], TensorSource],
    sample_id: Hashable = "sample",
    blocksize_parameter: Optional[BlocksizeParameter] = None,
    input_block_shape: Optional[Mapping[MemberId, Mapping[AxisId, int]]] = None,
    skip_preprocessing: bool = False,
    skip_postprocessing: bool = False,
    save_output_path: Optional[Union[Path, str]] = None,
) -> Sample:
    """Run prediction for a single set of input(s) with a bioimage.io model

    Args:
        model: Model to predict with.
            May be given as RDF source, model description or prediction pipeline.
        inputs: the input sample or the named input(s) for this model as a dictionary
        sample_id: the sample id.
            The **sample_id** is used to format **save_output_path**
            and to distinguish sample specific log messages.
        blocksize_parameter: (optional) Tile the input into blocks parametrized by
            **blocksize_parameter** according to any parametrized axis sizes defined
            by the **model**.
            See `bioimageio.spec.model.v0_5.ParameterizedSize` for details.
            Note: For a predetermined, fixed block shape use **input_block_shape**.
        input_block_shape: (optional) Tile the input sample tensors into blocks.
            Note: Use **blocksize_parameter** for a parameterized block shape to
                run prediction independent of the exact block shape.
        skip_preprocessing: Flag to skip the model's preprocessing.
        skip_postprocessing: Flag to skip the model's postprocessing.
        save_output_path: A path with to save the output to. M
            Must contain:
            - `{output_id}` (or `{member_id}`) if the model has multiple output tensors
            May contain:
            - `{sample_id}` to avoid overwriting recurrent calls
    """
    if isinstance(model, PredictionPipeline):
        pp = model
        model = pp.model_descr
    else:
        if not isinstance(model, (v0_4.ModelDescr, v0_5.ModelDescr)):
            loaded = load_description(model)
            if not isinstance(loaded, (v0_4.ModelDescr, v0_5.ModelDescr)):
                raise ValueError(f"expected model description, but got {loaded}")
            model = loaded

        pp = create_prediction_pipeline(
            model,
            fixed_dataset_statistics=inputs.stat if isinstance(inputs, Sample) else {},
        )

    with pp:
        model = pp.model_descr
        if save_output_path is not None:
            if (
                "{output_id}" not in str(save_output_path)
                and "{member_id}" not in str(save_output_path)
                and len(model.outputs) > 1
            ):
                raise ValueError(
                    f"Missing `{{output_id}}` in save_output_path={save_output_path} to "
                    + "distinguish model outputs "
                    + str([get_member_id(d) for d in model.outputs])
                )

        if isinstance(inputs, Sample):
            sample = inputs
        else:
            sample = create_sample_for_model(
                pp.model_descr, inputs=inputs, sample_id=sample_id
            )

        if input_block_shape is not None:
            if blocksize_parameter is not None:
                logger.warning(
                    "ignoring blocksize_parameter={} in favor of input_block_shape={}",
                    blocksize_parameter,
                    input_block_shape,
                )

            output = pp.predict_sample_with_fixed_blocking(
                sample,
                input_block_shape=input_block_shape,
                skip_preprocessing=skip_preprocessing,
                skip_postprocessing=skip_postprocessing,
            )
        elif blocksize_parameter is not None:
            output = pp.predict_sample_with_blocking(
                sample,
                skip_preprocessing=skip_preprocessing,
                skip_postprocessing=skip_postprocessing,
                ns=blocksize_parameter,
            )
        else:
            output = pp.predict_sample_without_blocking(
                sample,
                skip_preprocessing=skip_preprocessing,
                skip_postprocessing=skip_postprocessing,
            )
        if save_output_path:
            save_sample(save_output_path, output)

    return output

predict_many ¤

predict_many(*, model: Union[PermissiveFileSource, v0_4.ModelDescr, v0_5.ModelDescr, PredictionPipeline], inputs: Union[Iterable[PerMember[TensorSource]], Iterable[TensorSource]], sample_id: str = 'sample{i:03}', blocksize_parameter: Optional[Union[v0_5.ParameterizedSize_N, Mapping[Tuple[MemberId, AxisId], v0_5.ParameterizedSize_N]]] = None, skip_preprocessing: bool = False, skip_postprocessing: bool = False, save_output_path: Optional[Union[Path, str]] = None) -> Iterator[Sample]

Run prediction for a multiple sets of inputs with a bioimage.io model

Parameters:

Name Type Description Default

model ¤

Union[PermissiveFileSource, v0_4.ModelDescr, v0_5.ModelDescr, PredictionPipeline]

Model to predict with. May be given as RDF source, model description or prediction pipeline.

required

inputs ¤

Union[Iterable[PerMember[TensorSource]], Iterable[TensorSource]]

An iterable of the named input(s) for this model as a dictionary.

required

sample_id ¤

str

The sample id. note: {i} will be formatted as the i-th sample. If {i} (or {i:) is not present and inputs is not an iterable {i:03} is appended.

'sample{i:03}'

blocksize_parameter ¤

Optional[Union[v0_5.ParameterizedSize_N, Mapping[Tuple[MemberId, AxisId], v0_5.ParameterizedSize_N]]]

(optional) Tile the input into blocks parametrized by blocksize according to any parametrized axis sizes defined in the model RDF.

None

skip_preprocessing ¤

bool

Flag to skip the model's preprocessing.

False

skip_postprocessing ¤

bool

Flag to skip the model's postprocessing.

False

save_output_path ¤

Optional[Union[Path, str]]

A path to save the output to. Must contain: - {sample_id} to differentiate predicted samples - {output_id} (or {member_id}) if the model has multiple outputs

None
Source code in src/bioimageio/core/prediction.py
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
def predict_many(
    *,
    model: Union[
        PermissiveFileSource, v0_4.ModelDescr, v0_5.ModelDescr, PredictionPipeline
    ],
    inputs: Union[Iterable[PerMember[TensorSource]], Iterable[TensorSource]],
    sample_id: str = "sample{i:03}",
    blocksize_parameter: Optional[
        Union[
            v0_5.ParameterizedSize_N,
            Mapping[Tuple[MemberId, AxisId], v0_5.ParameterizedSize_N],
        ]
    ] = None,
    skip_preprocessing: bool = False,
    skip_postprocessing: bool = False,
    save_output_path: Optional[Union[Path, str]] = None,
) -> Iterator[Sample]:
    """Run prediction for a multiple sets of inputs with a bioimage.io model

    Args:
        model: Model to predict with.
            May be given as RDF source, model description or prediction pipeline.
        inputs: An iterable of the named input(s) for this model as a dictionary.
        sample_id: The sample id.
            note: `{i}` will be formatted as the i-th sample.
            If `{i}` (or `{i:`) is not present and `inputs` is not an iterable `{i:03}`
            is appended.
        blocksize_parameter: (optional) Tile the input into blocks parametrized by
            blocksize according to any parametrized axis sizes defined in the model RDF.
        skip_preprocessing: Flag to skip the model's preprocessing.
        skip_postprocessing: Flag to skip the model's postprocessing.
        save_output_path: A path to save the output to.
            Must contain:
            - `{sample_id}` to differentiate predicted samples
            - `{output_id}` (or `{member_id}`) if the model has multiple outputs
    """
    if save_output_path is not None and "{sample_id}" not in str(save_output_path):
        raise ValueError(
            f"Missing `{{sample_id}}` in save_output_path={save_output_path}"
            + " to differentiate predicted samples."
        )

    if isinstance(model, PredictionPipeline):
        pp = model
    else:
        if not isinstance(model, (v0_4.ModelDescr, v0_5.ModelDescr)):
            loaded = load_description(model)
            if not isinstance(loaded, (v0_4.ModelDescr, v0_5.ModelDescr)):
                raise ValueError(f"expected model description, but got {loaded}")
            model = loaded

        pp = create_prediction_pipeline(model)

    if not isinstance(inputs, collections.abc.Mapping):
        if "{i}" not in sample_id and "{i:" not in sample_id:
            sample_id += "{i:03}"

        total = len(inputs) if isinstance(inputs, collections.abc.Sized) else None

        for i, ipts in tqdm(enumerate(inputs), total=total):
            yield predict(
                model=pp,
                inputs=ipts,
                sample_id=sample_id.format(i=i),
                blocksize_parameter=blocksize_parameter,
                skip_preprocessing=skip_preprocessing,
                skip_postprocessing=skip_postprocessing,
                save_output_path=save_output_path,
            )

save_bioimageio_package ¤

save_bioimageio_package(source: Union[BioimageioYamlSource, ResourceDescr], /, *, compression: int = ZIP_DEFLATED, compression_level: int = 1, output_path: Union[NewPath, FilePath, None] = None, weights_priority_order: Optional[Sequence[Literal['keras_hdf5', 'onnx', 'pytorch_state_dict', 'tensorflow_js', 'tensorflow_saved_model_bundle', 'torchscript']]] = None, allow_invalid: bool = False, local_files_only: bool = False) -> FilePath

Package a bioimageio resource as a zip file.

Parameters:

Name Type Description Default

source ¤

Union[BioimageioYamlSource, ResourceDescr]

bioimageio resource description

required

compression ¤

int

The numeric constant of compression method.

ZIP_DEFLATED

compression_level ¤

int

Compression level to use when writing files to the archive. See https://docs.python.org/3/library/zipfile.html#zipfile.ZipFile

1

output_path ¤

Union[NewPath, FilePath, None]

file path to write package to

None

weights_priority_order ¤

Optional[Sequence[Literal['keras_hdf5', 'onnx', 'pytorch_state_dict', 'tensorflow_js', 'tensorflow_saved_model_bundle', 'torchscript']]]

If given only the first weights format present in the model is included. If none of the prioritized weights formats is found all are included.

None

allow_invalid ¤

bool

If True, do not raise an error if the exported package is invalid, but log an error instead.

False

local_files_only ¤

bool

If True, only local files are included in the package. If False, remote files are also included.

False

Returns:

Type Description
FilePath

path to zipped bioimageio package

Source code in bioimageio/spec/_package.py
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
def save_bioimageio_package(
    source: Union[BioimageioYamlSource, ResourceDescr],
    /,
    *,
    compression: int = ZIP_DEFLATED,
    compression_level: int = 1,
    output_path: Union[NewPath, FilePath, None] = None,
    weights_priority_order: Optional[  # model only
        Sequence[
            Literal[
                "keras_hdf5",
                "onnx",
                "pytorch_state_dict",
                "tensorflow_js",
                "tensorflow_saved_model_bundle",
                "torchscript",
            ]
        ]
    ] = None,
    allow_invalid: bool = False,
    local_files_only: bool = False,
) -> FilePath:
    """Package a bioimageio resource as a zip file.

    Args:
        source: bioimageio resource description
        compression: The numeric constant of compression method.
        compression_level: Compression level to use when writing files to the archive.
                           See https://docs.python.org/3/library/zipfile.html#zipfile.ZipFile
        output_path: file path to write package to
        weights_priority_order: If given only the first weights format present in the model is included.
                                If none of the prioritized weights formats is found all are included.
        allow_invalid: If True, do not raise an error if the exported package is invalid, but log an error instead.
        local_files_only: If True, only local files are included in the package. If False, remote files are also included.

    Returns:
        path to zipped bioimageio package
    """
    package_content = _prepare_resource_package(
        source,
        weights_priority_order=weights_priority_order,
        local_files_only=local_files_only,
    )
    if output_path is None:
        output_path = Path(
            NamedTemporaryFile(suffix=".bioimageio.zip", delete=False).name
        )
    else:
        output_path = Path(output_path)

    write_zip(
        output_path,
        package_content,
        compression=compression,
        compression_level=compression_level,
    )
    with get_validation_context().replace(warning_level=ERROR):
        if isinstance((exported := load_description(output_path)), InvalidDescr):
            msg = f"Exported package at '{output_path}' is invalid:\n{exported.get_reason()}"
            if allow_invalid:
                logger.error(msg)
            else:
                raise ValueError(msg)

    return output_path

save_bioimageio_package_as_folder ¤

save_bioimageio_package_as_folder(source: Union[BioimageioYamlSource, ResourceDescr], /, *, output_path: Union[NewPath, DirectoryPath, None] = None, weights_priority_order: Optional[Sequence[Literal['keras_hdf5', 'onnx', 'pytorch_state_dict', 'tensorflow_js', 'tensorflow_saved_model_bundle', 'torchscript']]] = None, local_files_only: bool = False) -> DirectoryPath

Write the content of a bioimage.io resource package to a folder.

Parameters:

Name Type Description Default

source ¤

Union[BioimageioYamlSource, ResourceDescr]

bioimageio resource description

required

output_path ¤

Union[NewPath, DirectoryPath, None]

file path to write package to

None

weights_priority_order ¤

Optional[Sequence[Literal['keras_hdf5', 'onnx', 'pytorch_state_dict', 'tensorflow_js', 'tensorflow_saved_model_bundle', 'torchscript']]]

If given only the first weights format present in the model is included. If none of the prioritized weights formats is found all are included.

None

local_files_only ¤

bool

If True, only local files are included in the package. If False, remote files are also included.

False

Returns:

Type Description
DirectoryPath

directory path to bioimageio package folder

Source code in bioimageio/spec/_package.py
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
def save_bioimageio_package_as_folder(
    source: Union[BioimageioYamlSource, ResourceDescr],
    /,
    *,
    output_path: Union[NewPath, DirectoryPath, None] = None,
    weights_priority_order: Optional[  # model only
        Sequence[
            Literal[
                "keras_hdf5",
                "onnx",
                "pytorch_state_dict",
                "tensorflow_js",
                "tensorflow_saved_model_bundle",
                "torchscript",
            ]
        ]
    ] = None,
    local_files_only: bool = False,
) -> DirectoryPath:
    """Write the content of a bioimage.io resource package to a folder.

    Args:
        source: bioimageio resource description
        output_path: file path to write package to
        weights_priority_order: If given only the first weights format present in the model is included.
                                If none of the prioritized weights formats is found all are included.
        local_files_only: If True, only local files are included in the package. If False, remote files are also included.

    Returns:
        directory path to bioimageio package folder
    """
    package_content = _prepare_resource_package(
        source,
        weights_priority_order=weights_priority_order,
        local_files_only=local_files_only,
    )
    if output_path is None:
        output_path = Path(mkdtemp())
    else:
        output_path = Path(output_path)

    output_path.mkdir(exist_ok=True, parents=True)
    for name, src in package_content.items():
        if not name:
            raise ValueError("got empty file name in package content")

        if isinstance(src, collections.abc.Mapping):
            write_yaml(src, output_path / name)
        elif (
            isinstance(src.original_root, Path)
            and src.original_root / src.original_file_name
            == (output_path / name).resolve()
        ):
            logger.debug(
                f"Not copying {src.original_root / src.original_file_name} to itself."
            )
        else:
            if isinstance(src.original_root, Path):
                logger.debug(
                    f"Copying from path {src.original_root / src.original_file_name} to {output_path / name}."
                )
            else:
                logger.debug(
                    f"Copying {src.original_root}/{src.original_file_name} to {output_path / name}."
                )
            with (output_path / name).open("wb") as dest:
                _ = shutil.copyfileobj(src, dest)

    return output_path

save_bioimageio_yaml_only ¤

save_bioimageio_yaml_only(rd: Union[ResourceDescr, BioimageioYamlContent, InvalidDescr], /, file: Union[NewPath, FilePath, TextIO], *, exclude_unset: bool = True, exclude_defaults: bool = False)

write the metadata of a resource description (rd) to file without writing any of the referenced files in it.

Parameters:

Name Type Description Default

rd ¤

Union[ResourceDescr, BioimageioYamlContent, InvalidDescr]

bioimageio resource description

required

file ¤

Union[NewPath, FilePath, TextIO]

file or stream to save to

required

exclude_unset ¤

bool

Exclude fields that have not explicitly be set.

True

exclude_defaults ¤

bool

Exclude fields that have the default value (even if set explicitly).

False

Note: To save a resource description with its associated files as a package, use save_bioimageio_package or save_bioimageio_package_as_folder.

Source code in bioimageio/spec/_io.py
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
def save_bioimageio_yaml_only(
    rd: Union[ResourceDescr, BioimageioYamlContent, InvalidDescr],
    /,
    file: Union[NewPath, FilePath, TextIO],
    *,
    exclude_unset: bool = True,
    exclude_defaults: bool = False,
):
    """write the metadata of a resource description (`rd`) to `file`
    without writing any of the referenced files in it.

    Args:
        rd: bioimageio resource description
        file: file or stream to save to
        exclude_unset: Exclude fields that have not explicitly be set.
        exclude_defaults: Exclude fields that have the default value (even if set explicitly).

    Note: To save a resource description with its associated files as a package,
    use `save_bioimageio_package` or `save_bioimageio_package_as_folder`.
    """
    if isinstance(rd, ResourceDescrBase):
        content = dump_description(
            rd, exclude_unset=exclude_unset, exclude_defaults=exclude_defaults
        )
    else:
        content = rd

    write_yaml(cast(YamlValue, content), file)

test_description ¤

test_description(source: Union[ResourceDescr, PermissiveFileSource, BioimageioYamlContent], *, format_version: Union[FormatVersionPlaceholder, str] = 'discover', weight_format: Optional[SupportedWeightsFormat] = None, devices: Optional[Sequence[str]] = None, determinism: Literal['seed_only', 'full'] = 'seed_only', expected_type: Optional[str] = None, sha256: Optional[Sha256] = None, stop_early: bool = False, runtime_env: Union[Literal['currently-active', 'as-described'], Path, BioimageioCondaEnv] = 'currently-active', run_command: Callable[[Sequence[str]], None] = default_run_command, working_dir: Optional[Union[os.PathLike[str], str]] = None, **deprecated: Unpack[DeprecatedKwargs]) -> ValidationSummary

Test a bioimage.io resource dynamically, for example run prediction of test tensors for models.

Parameters:

Name Type Description Default

source ¤

Union[ResourceDescr, PermissiveFileSource, BioimageioYamlContent]

model description source.

required

weight_format ¤

Optional[SupportedWeightsFormat]

Weight format to test. Default: All weight formats present in source.

None

devices ¤

Optional[Sequence[str]]

Devices to test with, e.g. 'cpu', 'cuda'. Default (may be weight format dependent): ['cuda'] if available, ['cpu'] otherwise.

None

determinism ¤

Literal['seed_only', 'full']

Modes to improve reproducibility of test outputs.

'seed_only'

expected_type ¤

Optional[str]

Assert an expected resource description type.

None

sha256 ¤

Optional[Sha256]

Expected SHA256 value of source. (Ignored if source already is a loaded ResourceDescr object.)

None

stop_early ¤

bool

Do not run further subtests after a failed one.

False

runtime_env ¤

Union[Literal['currently-active', 'as-described'], Path, BioimageioCondaEnv]

(Experimental feature!) The Python environment to run the tests in - "currently-active": Use active Python interpreter. - "as-described": Use bioimageio.spec.get_conda_env to generate a conda environment YAML file based on the model weights description. - A BioimageioCondaEnv or a path to a conda environment YAML file. Note: The bioimageio.core dependency will be added automatically if not present.

'currently-active'

run_command ¤

Callable[[Sequence[str]], None]

(Experimental feature!) Function to execute (conda) terminal commands in a subprocess. The function should raise an exception if the command fails. run_command is ignored if runtime_env is "currently-active".

default_run_command

working_dir ¤

Optional[Union[os.PathLike[str], str]]

(for debugging) directory to save any temporary files (model packages, conda environments, test summaries). Defaults to a temporary directory.

None
Source code in src/bioimageio/core/_resource_tests.py
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
def test_description(
    source: Union[ResourceDescr, PermissiveFileSource, BioimageioYamlContent],
    *,
    format_version: Union[FormatVersionPlaceholder, str] = "discover",
    weight_format: Optional[SupportedWeightsFormat] = None,
    devices: Optional[Sequence[str]] = None,
    determinism: Literal["seed_only", "full"] = "seed_only",
    expected_type: Optional[str] = None,
    sha256: Optional[Sha256] = None,
    stop_early: bool = False,
    runtime_env: Union[
        Literal["currently-active", "as-described"], Path, BioimageioCondaEnv
    ] = ("currently-active"),
    run_command: Callable[[Sequence[str]], None] = default_run_command,
    working_dir: Optional[Union[os.PathLike[str], str]] = None,
    **deprecated: Unpack[DeprecatedKwargs],
) -> ValidationSummary:
    """Test a bioimage.io resource dynamically,
    for example run prediction of test tensors for models.

    Args:
        source: model description source.
        weight_format: Weight format to test.
            Default: All weight formats present in **source**.
        devices: Devices to test with, e.g. 'cpu', 'cuda'.
            Default (may be weight format dependent): ['cuda'] if available, ['cpu'] otherwise.
        determinism: Modes to improve reproducibility of test outputs.
        expected_type: Assert an expected resource description `type`.
        sha256: Expected SHA256 value of **source**.
                (Ignored if **source** already is a loaded `ResourceDescr` object.)
        stop_early: Do not run further subtests after a failed one.
        runtime_env: (Experimental feature!) The Python environment to run the tests in
            - `"currently-active"`: Use active Python interpreter.
            - `"as-described"`: Use `bioimageio.spec.get_conda_env` to generate a conda
                environment YAML file based on the model weights description.
            - A `BioimageioCondaEnv` or a path to a conda environment YAML file.
                Note: The `bioimageio.core` dependency will be added automatically if not present.
        run_command: (Experimental feature!) Function to execute (conda) terminal commands in a subprocess.
            The function should raise an exception if the command fails.
            **run_command** is ignored if **runtime_env** is `"currently-active"`.
        working_dir: (for debugging) directory to save any temporary files
            (model packages, conda environments, test summaries).
            Defaults to a temporary directory.
    """
    if runtime_env == "currently-active":
        rd = load_description_and_test(
            source,
            format_version=format_version,
            weight_format=weight_format,
            devices=devices,
            determinism=determinism,
            expected_type=expected_type,
            sha256=sha256,
            stop_early=stop_early,
            working_dir=working_dir,
            **deprecated,
        )
        return rd.validation_summary

    if runtime_env == "as-described":
        conda_env = None
    elif isinstance(runtime_env, (str, Path)):
        conda_env = BioimageioCondaEnv.model_validate(read_yaml(Path(runtime_env)))
    elif isinstance(runtime_env, BioimageioCondaEnv):
        conda_env = runtime_env
    else:
        assert_never(runtime_env)

    if run_command is not default_run_command:
        try:
            run_command(["thiscommandshouldalwaysfail", "please"])
        except Exception:
            pass
        else:
            raise RuntimeError(
                "given run_command does not raise an exception for a failing command"
            )

    verbose = working_dir is not None
    if working_dir is None:
        td_kwargs: Dict[str, Any] = (
            dict(ignore_cleanup_errors=True) if sys.version_info >= (3, 10) else {}
        )
        working_dir_ctxt = TemporaryDirectory(**td_kwargs)
    else:
        working_dir_ctxt = nullcontext(working_dir)

    with working_dir_ctxt as _d:
        working_dir = Path(_d)

        if isinstance(source, ResourceDescrBase):
            descr = source
        elif isinstance(source, dict):
            context = get_validation_context().replace(
                perform_io_checks=True  # make sure we perform io checks though
            )

            descr = build_description(source, context=context)
        else:
            descr = load_description(source, perform_io_checks=True)

        if isinstance(descr, InvalidDescr):
            return descr.validation_summary
        elif isinstance(source, (dict, ResourceDescrBase)):
            file_source = save_bioimageio_package(
                descr, output_path=working_dir / "package.zip"
            )
        else:
            file_source = source

        # elevate status valid-format to passed and start testing
        descr.validation_summary.status = "passed"
        try:
            _test_in_env(
                file_source,
                descr=descr,
                working_dir=working_dir,
                weight_format=weight_format,
                conda_env=conda_env,
                devices=devices,
                determinism=determinism,
                expected_type=expected_type,
                sha256=sha256,
                stop_early=stop_early,
                run_command=run_command,
                verbose=verbose,
                **deprecated,
            )
        except Exception as e:
            descr.validation_summary.add_detail(
                ValidationDetail(
                    name="Test in dedicated environment",
                    status="failed",
                    loc=(),
                    errors=[
                        ErrorEntry(
                            loc=(),
                            msg=str(e),
                            type="bioimageio.core",
                            with_traceback=True,
                        )
                    ],
                )
            )

    return descr.validation_summary

test_model ¤

test_model(source: Union[v0_4.ModelDescr, v0_5.ModelDescr, PermissiveFileSource], weight_format: Optional[SupportedWeightsFormat] = None, devices: Optional[List[str]] = None, *, determinism: Literal['seed_only', 'full'] = 'seed_only', sha256: Optional[Sha256] = None, stop_early: bool = False, working_dir: Optional[Union[os.PathLike[str], str]] = None, **deprecated: Unpack[DeprecatedKwargs]) -> ValidationSummary

Test model inference

Source code in src/bioimageio/core/_resource_tests.py
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
def test_model(
    source: Union[v0_4.ModelDescr, v0_5.ModelDescr, PermissiveFileSource],
    weight_format: Optional[SupportedWeightsFormat] = None,
    devices: Optional[List[str]] = None,
    *,
    determinism: Literal["seed_only", "full"] = "seed_only",
    sha256: Optional[Sha256] = None,
    stop_early: bool = False,
    working_dir: Optional[Union[os.PathLike[str], str]] = None,
    **deprecated: Unpack[DeprecatedKwargs],
) -> ValidationSummary:
    """Test model inference"""
    return test_description(
        source,
        weight_format=weight_format,
        devices=devices,
        determinism=determinism,
        expected_type="model",
        sha256=sha256,
        stop_early=stop_early,
        working_dir=working_dir,
        **deprecated,
    )

validate_format ¤

validate_format(data: BioimageioYamlContent, /, *, format_version: Union[Literal['discover', 'latest'], str] = DISCOVER, context: Optional[ValidationContext] = None) -> ValidationSummary

Validate a dictionary holding a bioimageio description. See bioimagieo.spec.load_description_and_validate_format_only to validate a file source.

Parameters:

Name Type Description Default

data ¤

BioimageioYamlContent

Dictionary holding the raw bioimageio.yaml content.

required

format_version ¤

Union[Literal['discover', 'latest'], str]

Format version to (update to and) use for validation. Note: - Use "latest" to convert to the latest available format version. - Use "discover" to use the format version specified in the RDF. - Only considers major.minor format version, ignores patch version. - Conversion to lower format versions is not supported.

DISCOVER

context ¤

Optional[ValidationContext]

Validation context, see bioimagieo.spec.ValidationContext

None
Note

Use bioimagieo.spec.load_description_and_validate_format_only to validate a file source instead of loading the YAML content and creating the appropriate ValidationContext.

Alternatively you can use bioimagieo.spec.load_description and access the validation_summary attribute of the returned object.

Source code in bioimageio/spec/_description.py
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
def validate_format(
    data: BioimageioYamlContent,
    /,
    *,
    format_version: Union[Literal["discover", "latest"], str] = DISCOVER,
    context: Optional[ValidationContext] = None,
) -> ValidationSummary:
    """Validate a dictionary holding a bioimageio description.
    See `bioimagieo.spec.load_description_and_validate_format_only`
    to validate a file source.

    Args:
        data: Dictionary holding the raw bioimageio.yaml content.
        format_version:
            Format version to (update to and) use for validation.
            Note:
            - Use "latest" to convert to the latest available format version.
            - Use "discover" to use the format version specified in the RDF.
            - Only considers major.minor format version, ignores patch version.
            - Conversion to lower format versions is not supported.
        context: Validation context, see `bioimagieo.spec.ValidationContext`

    Note:
        Use `bioimagieo.spec.load_description_and_validate_format_only` to validate a
        file source instead of loading the YAML content and creating the appropriate
        `ValidationContext`.

        Alternatively you can use `bioimagieo.spec.load_description` and access the
        `validation_summary` attribute of the returned object.
    """
    with context or get_validation_context():
        rd = build_description(data, format_version=format_version)

    assert rd.validation_summary is not None
    return rd.validation_summary