Data API#
KonfAI datasets are built from group definitions, transforms, augmentations, and optional patching strategies.
Dataset configuration objects#
- class konfai.data.data_manager.DataTrain(dataset_filenames=['default|./Dataset:mha'], groups_src={'default|Labels': {'default|Labels': {'transforms': [], 'patch_transforms': []}}}, augmentations={'DataAugmentation_0': <konfai.data.augmentation.DataAugmentationsList object>}, inline_augmentations=False, patch=<konfai.data.patching.DatasetPatch object>, memory_budget=None, subset=<konfai.data.data_manager.TrainSubset object>, batch_size=1, validation=0.2, validation_augmentations=True, num_workers=None, pin_memory=False, prefetch_factor=None, persistent_workers=None)[source]
Bases:
DataDataset configuration used by the training workflow.
- class konfai.data.data_manager.DataPrediction(dataset_filenames=['default|./Dataset'], groups_src={'default': {'default|Labels': {'transforms': [], 'patch_transforms': []}}}, augmentations={'DataAugmentation_0': <konfai.data.augmentation.DataAugmentationsList object>}, patch=<konfai.data.patching.DatasetPatch object>, memory_budget=None, subset=<konfai.data.data_manager.PredictionSubset object>, batch_size=1, num_workers=None, pin_memory=False, prefetch_factor=None, persistent_workers=None)[source]
Bases:
DataDataset configuration used by the prediction workflow.
- class konfai.data.data_manager.DataMetric(dataset_filenames=['default|./Dataset:mha'], groups_src={'default': {'default|group_dest': {'transforms': [], 'patch_transforms': []}}}, memory_budget=None, subset=<konfai.data.data_manager.PredictionSubset object>, validation=None, num_workers=None, pin_memory=False, prefetch_factor=None, persistent_workers=None)[source]
Bases:
DataDataset configuration used by the evaluation workflow.
Evaluation never exposes a patch: each run sizes its own from
memory_budget(a missing key means"auto") – a case that fits the budget is evaluated whole (exact); one that does not is cut into the largest DISJOINT patches that fit (overlap 0, no padding) and the reducible metrics combine their running partials into the exact whole-case value. The evaluator disables this sizing when any of its metrics is not reducible, so a metric that needs the whole volume always gets it.
Patching#
- class konfai.data.patching.DatasetPatch(patch_size=[128, 128, 128], overlap=None, pad_value=None, extend_slice=0)[source]
Bases:
PatchPatch definition applied when sampling data from datasets.
- class konfai.data.patching.ModelPatch(patch_size=[128, 128, 128], overlap=None, patch_combine=None, pad_value=None, extend_slice=0)[source]
Bases:
PatchPatch definition applied inside model graphs during prediction or training.
- class konfai.data.patching.DatasetManager(index, group_src, group_dest, name, dataset, patch, transforms, data_augmentations_list)[source]
Bases:
objectCache-backed manager for one dataset case and one source/destination group.
- class konfai.data.patching.Accumulator(patch_slices, patch_size, patch_combine=None, batch=True)[source]
Bases:
objectAccumulate patch predictions and reassemble them into a full tensor.
- add_layer(index, layer)[source]
Blend one patch in; returns the slabs this completes (none for the whole-volume base).
- is_empty()[source]
True until the first patch has been blended in (no volume-sized buffer allocated yet).
- Return type:
Transforms and metadata#
- class konfai.data.transform.Transform[source]
Bases:
NeedDevice,ABCBase class for transforms operating on tensors and cached attributes.
- patch_locality(cache_attribute)[source]
Declare how this transform’s output depends on its input, for patch streaming.
Answered from the transform’s own
__init__config and, where the honest answer depends on the image, fromcache_attribute– the case’s SOURCE metadata, as the volume is stored. The dispatcher reads the header before any voxel, so a transform whose contract the image decides (a reorientation that is only a flip when the direction cosines are axis-aligned, a resample whose halo is the case’s own scale) can still declare it up front.The default
WHOLE_VOLUMEis the safety net: any transform (including third-party custom ones) that does not override this falls to the whole-volume path, so nothing silently breaks.An override is bound by three rules:
READ-ONLY. Never write to
cache_attribute. A declaration is made once, for the whole case, and what it wrote would be one patch’s answer imposed on every other – the first-patch-wins bug the streamed paths are built to avoid. The dispatcher hands over a private copy, so a write cannot reach the case; it is simply lost.NO I/O. Read the attribute already in hand, nothing else. Whether the outside world can honour the declaration (are the disk statistics readable, does a mask group exist) is the dispatcher’s call, and it already makes it.
TOTAL. Answer for ANY case. The metadata may be absent – the config-time checks probe with an empty
Attribute, and a group carries only what its writer stored – so a missing key must returnWHOLE_VOLUME, never raise.
- Return type:
- stream_region_source(target_slices, source_spatial_shape, cache_attribute)[source]
Map a target-patch’s spatial slices to the source spatial region to read (region kinds).
Overridden by the kinds whose source region is an index remap of the target’s –
ORIENTATIONmaps it and reorients what it reads,CROPmaps it and is done.HALOandRESCALEare handled generically by the dispatcher, so the base raises for any transform that declares a region kind without providing the remap.cache_attributeis the case’s SOURCE metadata, under the same rules aspatch_locality(): a remap the image decides (a reorientation whose mirrored axes are the case’s own direction cosines) reads it here, and reads nothing else.
- stream_slab(name, tensor, region, spatial_shape, cache_attribute)[source]
Run this transform on one finalized slab — rows
regionof aspatial_shapevolume.The streamed-write dispatcher calls this instead of
__call__for aSLABdeclaration: the value map is per-voxel, so the default whole-volume call is exact on the slab, but the stage’s side effect needs to know where the slab sits — which is what aSLABtransform overrides this to read. Slabs arrive in order and tile the volume exactly once per case.- Return type:
- stream_abort(name)[source]
Drop whatever
stream_slabholds open fornameafter a mid-case failure.Called by the streamed-write dispatcher when a case dies between slabs, so a
SLABstage’s region sink or buffer does not outlive the case. The base holds nothing.- Return type:
- write_stream_cache_attribute(cache_attribute, source_spatial_shape)[source]
Record the geometry a whole-volume
__call__would, given the FULL source shape.Called once per case, on the persistent attribute, for the stage that owns a streamed region. A transform whose geometry rewrite depends on the volume’s EXTENT (a reorientation’s new origin is the corner it mirrors onto) cannot compute it from a patch, which is all its
__call__is handed while streaming: it writes the case-level answer here instead, and the patch-local one it wrote on the way is dropped rather than persisted. The base is a no-op – a transform that leaves geometry alone has nothing to record.- Return type:
- class konfai.data.transform.TransformInverse(inverse)[source]
-
Base class for transforms that can also invert their effect.
- inverse_patch_locality(cache_attribute)[source]
Declare how
inverse’s output depends on its input, for the streamed-write dispatcher.The write mirror of
patch_locality(): a prediction’s finalize chain applies transforms INVERTED, so the streamed-write gate asks each one about its inverse.cache_attributeis the finalize-time state — the case’s attribute asinversewill receive it, with everything the forward pass pushed still stacked on it — under the same three rules (read-only, no I/O, total).The default derives from the forward contract where the derivation is safe for any subclass: a per-voxel value map inverts to a per-voxel value map, and an index remap inverts to an index remap. Every other kind falls to
WHOLE_VOLUME— an inverse that is streamable anyway (Padding’s crop,Resample’s rescale) declares itself.- Return type:
- inverse_transform_shape(shape, cache_attribute)[source]
The spatial shape
inverseproduces fromshape(write mirror oftransform_shape).cache_attributeis the finalize-time state, as ininverse_patch_locality(). The default is the identity, exactly as (in)exact astransform_shape’s: a shape-changing inverse must override it, and the streamed-write dispatcher only trusts it for the kindsinverse_patch_locality()declared streamable.
- stream_region_target(target_slices, source_spatial_shape, cache_attribute)[source]
Map a region of
inverse’s OUTPUT to the region of its INPUT it is computed from.The write mirror of
stream_region_source(), with the same direction of travel: the slices are in the space being produced (here the written image), the shape is the space being consumed (here the finalized accumulator), and the answer is the consumed region. The streamed-write dispatcher holds a sliding window of finalized slabs and emits each output region once the region this returns has arrived.cache_attributeis the finalize-time state; a transform whose remap is read from what its owninversepops accounts for those pops on a copy.
- class konfai.data.transform.TransformLoader[source]
Bases:
objectResolve and instantiate transform classes from KonfAI configuration.
- class konfai.data.transform.Clip(min_value=-1024, max_value=1024, save_clip_min=False, save_clip_max=False, mask=None)[source]
Bases:
TransformClip tensor intensities to a fixed or data-dependent value range.
- patch_locality(cache_attribute)[source]
Declare how this transform’s output depends on its input, for patch streaming.
Answered from the transform’s own
__init__config and, where the honest answer depends on the image, fromcache_attribute– the case’s SOURCE metadata, as the volume is stored. The dispatcher reads the header before any voxel, so a transform whose contract the image decides (a reorientation that is only a flip when the direction cosines are axis-aligned, a resample whose halo is the case’s own scale) can still declare it up front.The default
WHOLE_VOLUMEis the safety net: any transform (including third-party custom ones) that does not override this falls to the whole-volume path, so nothing silently breaks.An override is bound by three rules:
READ-ONLY. Never write to
cache_attribute. A declaration is made once, for the whole case, and what it wrote would be one patch’s answer imposed on every other – the first-patch-wins bug the streamed paths are built to avoid. The dispatcher hands over a private copy, so a write cannot reach the case; it is simply lost.NO I/O. Read the attribute already in hand, nothing else. Whether the outside world can honour the declaration (are the disk statistics readable, does a mask group exist) is the dispatcher’s call, and it already makes it.
TOTAL. Answer for ANY case. The metadata may be absent – the config-time checks probe with an empty
Attribute, and a group carries only what its writer stored – so a missing key must returnWHOLE_VOLUME, never raise.
- Return type:
- class konfai.data.transform.Normalize(lazy=False, channels=None, min_value=-1, max_value=1, inverse=True)[source]
Bases:
TransformInverseMap intensities to a target min/max interval and optionally invert it.
- patch_locality(cache_attribute)[source]
Declare how this transform’s output depends on its input, for patch streaming.
Answered from the transform’s own
__init__config and, where the honest answer depends on the image, fromcache_attribute– the case’s SOURCE metadata, as the volume is stored. The dispatcher reads the header before any voxel, so a transform whose contract the image decides (a reorientation that is only a flip when the direction cosines are axis-aligned, a resample whose halo is the case’s own scale) can still declare it up front.The default
WHOLE_VOLUMEis the safety net: any transform (including third-party custom ones) that does not override this falls to the whole-volume path, so nothing silently breaks.An override is bound by three rules:
READ-ONLY. Never write to
cache_attribute. A declaration is made once, for the whole case, and what it wrote would be one patch’s answer imposed on every other – the first-patch-wins bug the streamed paths are built to avoid. The dispatcher hands over a private copy, so a write cannot reach the case; it is simply lost.NO I/O. Read the attribute already in hand, nothing else. Whether the outside world can honour the declaration (are the disk statistics readable, does a mask group exist) is the dispatcher’s call, and it already makes it.
TOTAL. Answer for ANY case. The metadata may be absent – the config-time checks probe with an empty
Attribute, and a group carries only what its writer stored – so a missing key must returnWHOLE_VOLUME, never raise.
- Return type:
- inverse_patch_locality(cache_attribute)[source]
Declare how
inverse’s output depends on its input, for the streamed-write dispatcher.The write mirror of
patch_locality(): a prediction’s finalize chain applies transforms INVERTED, so the streamed-write gate asks each one about its inverse.cache_attributeis the finalize-time state — the case’s attribute asinversewill receive it, with everything the forward pass pushed still stacked on it — under the same three rules (read-only, no I/O, total).The default derives from the forward contract where the derivation is safe for any subclass: a per-voxel value map inverts to a per-voxel value map, and an index remap inverts to an index remap. Every other kind falls to
WHOLE_VOLUME— an inverse that is streamable anyway (Padding’s crop,Resample’s rescale) declares itself.- Return type:
- class konfai.data.transform.Standardize(lazy=False, mean=None, std=None, mask=None, inverse=True)[source]
Bases:
TransformInverseStandardize tensors using cached or computed mean and standard deviation.
- patch_locality(cache_attribute)[source]
Declare how this transform’s output depends on its input, for patch streaming.
Answered from the transform’s own
__init__config and, where the honest answer depends on the image, fromcache_attribute– the case’s SOURCE metadata, as the volume is stored. The dispatcher reads the header before any voxel, so a transform whose contract the image decides (a reorientation that is only a flip when the direction cosines are axis-aligned, a resample whose halo is the case’s own scale) can still declare it up front.The default
WHOLE_VOLUMEis the safety net: any transform (including third-party custom ones) that does not override this falls to the whole-volume path, so nothing silently breaks.An override is bound by three rules:
READ-ONLY. Never write to
cache_attribute. A declaration is made once, for the whole case, and what it wrote would be one patch’s answer imposed on every other – the first-patch-wins bug the streamed paths are built to avoid. The dispatcher hands over a private copy, so a write cannot reach the case; it is simply lost.NO I/O. Read the attribute already in hand, nothing else. Whether the outside world can honour the declaration (are the disk statistics readable, does a mask group exist) is the dispatcher’s call, and it already makes it.
TOTAL. Answer for ANY case. The metadata may be absent – the config-time checks probe with an empty
Attribute, and a group carries only what its writer stored – so a missing key must returnWHOLE_VOLUME, never raise.
- Return type:
- inverse_patch_locality(cache_attribute)[source]
Declare how
inverse’s output depends on its input, for the streamed-write dispatcher.The write mirror of
patch_locality(): a prediction’s finalize chain applies transforms INVERTED, so the streamed-write gate asks each one about its inverse.cache_attributeis the finalize-time state — the case’s attribute asinversewill receive it, with everything the forward pass pushed still stacked on it — under the same three rules (read-only, no I/O, total).The default derives from the forward contract where the derivation is safe for any subclass: a per-voxel value map inverts to a per-voxel value map, and an index remap inverts to an index remap. Every other kind falls to
WHOLE_VOLUME— an inverse that is streamable anyway (Padding’s crop,Resample’s rescale) declares itself.- Return type:
Dataset utilities#
- class konfai.utils.dataset.Attribute(attributes=None)[source]
-
Metadata container storing repeated values with a stack-like naming scheme.
- class konfai.utils.dataset.Dataset(filename, file_format)[source]
Bases:
objectFilesystem or HDF5-backed dataset abstraction used across KonfAI.
- class AbstractFile[source]
Bases:
ABC- open_data_stream(name, shape, dtype, attributes)[source]
Open
namefor incremental region writes;Nonewhen this backend cannot.- Return type:
- class H5File(filename, read)[source]
Bases:
AbstractFile- open_data_stream(name, shape, dtype, attributes)[source]
Open
namefor incremental region writes;Nonewhen this backend cannot.- Return type:
- class SitkFile(filename, read, file_format)[source]
Bases:
AbstractFile- open_data_stream(name, shape, dtype, attributes)[source]
Open
namefor incremental region writes;Nonewhen this backend cannot.- Return type:
- class OmeZarrFile(filename, read, level=0)[source]
Bases:
AbstractFileOME-NGFF backend using chunked Zarr reads for KonfAI patches.
levelselects the multiscale pyramid resolution to read (0 = full resolution, higher = coarser); it comes from theomezarr@<level>dataset-spec suffix.- open_data_stream(name, shape, dtype, attributes)[source]
Open
namefor incremental region writes;Nonewhen this backend cannot.- Return type:
- class DicomFile(filename, read)[source]
Bases:
AbstractFileDICOM series backend with header-only metadata and slice-level reads.
- rebase(prefix)[source]
Prepend
prefixto this dataset’s path, re-derivingis_directoryfrom the format.- Return type:
- concurrent_write_safe()[source]
Whether writes to different entries land in disjoint files, so a background writer may flush one entry while another thread writes elsewhere in the dataset.
Mirrors the backend dispatch in
File.__enter__: everything that is not a single-store backend is aSitkFiledirectory, one image file per(group, name). A single store (one HDF5 file, one zarr hierarchy, a DICOM series) shares handles and metadata across entries and must stay serial.- Return type:
- can_stream_data(attributes)[source]
Whether
open_data_streamcan serve this dataset’s write format.H5 and OME-Zarr always can; MetaImage
mhaneeds image geometry to write its header up front; every other format only writes whole volumes (usewrite).- Return type:
- open_data_stream(group, name, shape, dtype, attributes=None)[source]
Open one entry for incremental region writes.
Returns
Nonewhen the write format cannot serve region writes; the caller then assembles the volume and useswrite. The returned stream is a context manager: a clean exit finalizes the entry, an exception removes the partial one.- Return type:
- konfai.utils.dataset.data_to_image(data, attributes)[source]
Convert a NumPy array and KonfAI attributes into a SimpleITK image.
- Return type:
Image
- konfai.utils.dataset.image_to_data(image)[source]
Convert a SimpleITK image into a channel-first NumPy array and attributes.