Use BITS data in a MONAI pipeline

WarningContent review status

This page contains unreviewed content created with large language model (LLM) tools.

ImportantIntegration ownership

The APIs on this page are implemented by bitsfuse, not bitsio. This page is retained temporarily because it follows the training tutorial. The long-term home for MONAI integration documentation is the bitsfuse documentation.

bitsfuse adapts a BITS record set to MONAI dictionary transforms and MetaTensor objects.

pip install "bitsfuse[monai]"

1 A map-style dataset

Select images with the METATENSOR return type, then wrap the record set in bitsfuse.monai.BitsDataset:

from bitsfuse.monai import BitsDataset
from bitsio import BITSZarrDataset
from tensorbids.query import BIDSReference, BIDSReferenceType

ds = BITSZarrDataset.open("ds000114.bits")
records = ds.records(
    BIDSReference(suffix="T1w", return_type=BIDSReferenceType.METATENSOR),
    "participants.dominant_hand",
)
dataset = BitsDataset(records)
item = dataset[0]
image = item["T1w"]
print(len(dataset), sorted(item))
print(type(image).__name__, tuple(image.shape), image.dtype, tuple(image.meta["affine"].shape))
10 ['T1w', 'participants.dominant_hand', 'subject']
MetaTensor (256, 156, 256) torch.float32 (4, 4)

Each item retains the record fields. A METATENSOR reference becomes a MetaTensor in NIfTI axis order, with affine and spatial_shape metadata; a TENSOR reference becomes a torch.Tensor. The default output data type is float32. Pass float16, bfloat16, float64, or native to select a different type. The optional transform argument applies a MONAI dictionary transform to each item.

2 Inside an existing pipeline

Use LoadBITSImaged where an existing dictionary pipeline would otherwise use LoadImaged. The transform resolves BIDS target paths through the open dataset:

from bitsfuse.monai import LoadBITSImaged

load = LoadBITSImaged(["image"], dataset=ds, ensure_channel_first=True)
(ref,) = ds.query(subject="02", suffix="T1w")
loaded = load({"image": ref.target_path, "label": 1})
print(type(loaded["image"]).__name__, tuple(loaded["image"].shape), loaded["label"])
MetaTensor (1, 156, 256, 256) 1

A missing target path raises RecordError. With allow_missing_keys=True, the transform leaves absent keys unchanged.

3 Batch

Images with different shapes cannot be stacked directly. Crop or pad them to a common shape with a MONAI transform or a BITS record function before batching:

from monai.transforms import CenterSpatialCropd, EnsureChannelFirstd, Compose
from torch.utils.data import DataLoader

crop = Compose([EnsureChannelFirstd("T1w", channel_dim="no_channel"), CenterSpatialCropd("T1w", (64, 64, 64))])
loader = DataLoader(BitsDataset(records, transform=crop), batch_size=2)
batch = next(iter(loader))
print(tuple(batch["T1w"].shape), batch["participants.dominant_hand"])
(2, 1, 64, 64, 64) ['left', 'right']

4 When to use the record set’s loader instead

records.loader() can translate a lazy spatial window into region reads of the stored arrays. BitsDataset reads each selected image before applying its MONAI transform. Use the record-set loader when partial array reads are the priority, and use BitsDataset when reusing an existing MONAI transform pipeline is more important.

5 Constraints

  • BitsDataset casts image arrays to float32 unless dtype specifies another type.
  • For spawn or forkserver workers, transforms and record functions must be importable by module and name.

6 See also