Skip to content

Commit

Permalink
Merge branch 'spec_v0_5' into spec_v0_5__fixing_pytorch_conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
Tomaz-Vieira committed Nov 24, 2023
2 parents ce3e014 + 7a94ce9 commit 02f5299
Show file tree
Hide file tree
Showing 16 changed files with 697 additions and 988 deletions.
45 changes: 45 additions & 0 deletions bioimageio/core/common.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
from typing import Any, Dict, Generic, List, Literal, NamedTuple, TypeVar, Union

import numpy as np
import xarray as xr
from attr import dataclass
from typing_extensions import Final

from bioimageio.core.stat_measures import Measure
from bioimageio.spec.model import v0_4, v0_5
from bioimageio.spec.model.v0_5 import TensorId

TensorId = v0_5.TensorId
AxisId = v0_5.AxisId

Sample = Dict[TensorId, xr.DataArray]

ProcessingDescrBase = Union[v0_4.ProcessingDescrBase, v0_5.ProcessingDescrBase]
ProcessingKwargs = Union[v0_4.ProcessingKwargs, v0_5.ProcessingKwargs]

PER_SAMPLE = "per_sample"
PER_DATASET = "per_dataset"


MeasureVar = TypeVar("MeasureVar", bound=Measure)
ModeVar = TypeVar("ModeVar", Literal["per_sample"], Literal["per_dataset"])


@dataclass(frozen=True)
class RequiredMeasure(Generic[MeasureVar, ModeVar]):
measure: MeasureVar
tensor_id: TensorId
mode: ModeVar


@dataclass(frozen=True)
class SampleMeasure(RequiredMeasure[MeasureVar, Literal["per_sample"]]):
pass


@dataclass(frozen=True)
class DatasetMeasure(RequiredMeasure[MeasureVar, Literal["per_dataset"]]):
pass


MeasureValue = xr.DataArray
38 changes: 21 additions & 17 deletions bioimageio/core/image_helper.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,17 @@

import os
from copy import deepcopy
from typing import Dict, List, Optional, Sequence, Tuple, Union
from typing import Dict, List, Optional, Sequence, Tuple, TypeVar, Union

import imageio
import numpy as np
from numpy.typing import NDArray
from xarray import DataArray

from bioimageio.spec.model.v0_4 import InputTensor as InputTensor04
from bioimageio.spec.model.v0_4 import OutputTensor as OutputTensor04
from bioimageio.spec.model.v0_5 import InputTensor as InputTensor05
from bioimageio.spec.model.v0_5 import OutputTensor as OutputTensor05
from numpy.typing import NDArray
from xarray import DataArray

InputTensor = Union[InputTensor04, InputTensor05]
OutputTensor = Union[OutputTensor04, OutputTensor05]
Expand All @@ -22,34 +23,37 @@
#


def transform_input_image(image: NDArray, tensor_axes: str, image_axes: Optional[str] = None):
"""Transform input image into output tensor with desired axes.
DType = TypeVar("DType", bound=np.dtype)


def transpose_image(image: NDArray[DType], desired_axes: str, current_axes: Optional[str] = None) -> NDArray[DType]:
"""Transform an image to match desired axes.
Args:
image: the input image
tensor_axes: the desired tensor axes
input_axes: the axes of the input image (optional)
desired_axes: the desired image axes
current_axes: the axes of the input image
"""
# if the image axes are not given deduce them from the required axes and image shape
if image_axes is None:
has_z_axis = "z" in tensor_axes
if current_axes is None:
has_z_axis = "z" in desired_axes
ndim = image.ndim
if ndim == 2:
image_axes = "yx"
current_axes = "yx"
elif ndim == 3:
image_axes = "zyx" if has_z_axis else "cyx"
current_axes = "zyx" if has_z_axis else "cyx"
elif ndim == 4:
image_axes = "czyx"
current_axes = "czyx"
elif ndim == 5:
image_axes = "bczyx"
current_axes = "bczyx"
else:
raise ValueError(f"Invalid number of image dimensions: {ndim}")
tensor = DataArray(image, dims=tuple(image_axes))
tensor = DataArray(image, dims=tuple(current_axes))
# expand the missing image axes
missing_axes = tuple(set(tensor_axes) - set(image_axes))
missing_axes = tuple(set(desired_axes) - set(current_axes))
tensor = tensor.expand_dims(dim=missing_axes)
# transpose to the correct axis order
tensor = tensor.transpose(*tuple(tensor_axes))
tensor = tensor.transpose(*tuple(desired_axes))
# return numpy array
return tensor.values

Expand Down Expand Up @@ -103,7 +107,7 @@ def load_image(in_path, axes: Sequence[str]) -> DataArray:
else:
is_volume = "z" in axes
im = imageio.volread(in_path) if is_volume else imageio.imread(in_path)
im = transform_input_image(im, axes)
im = transpose_image(im, axes)
return DataArray(im, dims=axes)


Expand Down
13 changes: 7 additions & 6 deletions bioimageio/core/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from bioimageio.spec._internal.base_nodes import ResourceDescriptionBase
from bioimageio.spec._internal.constants import DISCOVER
from bioimageio.spec._internal.types import FileName, RdfContent, RelativeFilePath, Sha256, ValidationContext, YamlValue
from bioimageio.spec.description import InvalidDescription, dump_description
from bioimageio.spec.common import BioimageioYamlContent, FileSource, InvalidDescription
from bioimageio.spec.model.v0_4 import WeightsFormat
from bioimageio.spec.package import extract_file_name, get_resource_package_content
from bioimageio.spec.summary import ValidationSummary
Expand All @@ -32,23 +32,24 @@ def load_description_and_validate(
*,
format_version: Union[Literal["discover"], Literal["latest"], str] = DISCOVER,
) -> Union[ResourceDescription, InvalidDescription]:
rdf = download_rdf(source)
opened = open_bioimageio_yaml(source)

return build_description_and_validate(
rdf.content,
context=ValidationContext(root=rdf.original_root, file_name=rdf.original_file_name),
opened.content,
context=ValidationContext(root=opened.original_root, file_name=opened.original_file_name),
format_version=format_version,
)


def build_description_and_validate(
rdf_content: RdfContent,
data: BioimageioYamlContent,
/,
*,
context: Optional[ValidationContext] = None,
format_version: Union[Literal["discover"], Literal["latest"], str] = DISCOVER,
) -> Union[ResourceDescription, InvalidDescription]:
"""load and validate a BioImage.IO description from the content of a resource description file (RDF)"""
rd = load_description(rdf_content, context=context, format_version=format_version)
descr = build_description(rdf_content, context=context, format_version=format_version)
# todo: add dynamic validation
return rd

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,20 @@
import xarray as xr

from bioimageio.core.model_adapters import ModelAdapter, create_model_adapter
from bioimageio.core.model_adapters import get_weight_formats as get_weight_formats
from bioimageio.core.utils.node_visitor import resolve_raw_node
from bioimageio.spec.model import AnyModel, raw_nodes

from ._combined_processing import CombinedProcessing
from ._stat_state import StatsState
from ._utils import ComputedMeasures, Sample, TensorName
from .stat_state import StatsState


@dataclass
class NamedImplicitOutputShape:
reference_input: TensorName = missing
scale: List[Tuple[str, float]] = missing
offset: List[Tuple[str, int]] = missing
reference_input: TensorName
scale: List[Tuple[str, float]]
offset: List[Tuple[str, int]]

def __len__(self):
return len(self.scale)
Expand Down
4 changes: 0 additions & 4 deletions bioimageio/core/prediction_pipeline/__init__.py

This file was deleted.

105 changes: 0 additions & 105 deletions bioimageio/core/prediction_pipeline/_combined_processing.py

This file was deleted.

65 changes: 0 additions & 65 deletions bioimageio/core/prediction_pipeline/_utils.py

This file was deleted.

Loading

0 comments on commit 02f5299

Please sign in to comment.