Skip to content

Built-in datasets

TorchIO provides demo datasets for testing and tutorials. Each downloads on first use and caches locally.

Synthetic

ZonePlate

Bases: Subject

Synthetic data generated from a zone plate.

The zone plate is a circular diffraction grating that produces concentric rings of light and dark bands. This dataset is useful for testing image processing algorithms, particularly those related to frequency analysis and interpolation.

See equation 10.63 in Practical Handbook on Image Processing for Scientific Applications <https://www.routledge.com/Practical-Handbook-on-Image-Processing-for-Scientific-and-Technical-Applications/Jahne/p/book/9780849319006>_ by Bernd Jähne.

Parameters:

Name Type Description Default
size int

The size of the generated image along all dimensions.

501
Source code in src/torchio/datasets/zone_plate.py
class ZonePlate(Subject):
    """Synthetic data generated from a zone plate.

    The zone plate is a circular diffraction grating that produces concentric
    rings of light and dark bands. This dataset is useful for testing image
    processing algorithms, particularly those related to frequency analysis and
    interpolation.

    See equation 10.63 in `Practical Handbook on Image Processing for
    Scientific Applications
    <https://www.routledge.com/Practical-Handbook-on-Image-Processing-for-Scientific-and-Technical-Applications/Jahne/p/book/9780849319006>`_
    by Bernd Jähne.

    Args:
        size: The size of the generated image along all dimensions.
    """

    def __init__(self, size: int = 501) -> None:
        if size < 3:
            msg = "Size must be at least 3."
            raise ValueError(msg)
        self.size = size
        image = self._generate_image(size)
        super().__init__(image=image)

    @staticmethod
    def _generate_image(size: int) -> ScalarImage:
        if size % 2 == 1:
            fin = (size - 1) // 2
            ini = -fin
        else:
            fin = size // 2
            ini = -fin + 1
        x = np.arange(ini, fin + 1)
        y = np.arange(ini, fin + 1)
        z = np.arange(ini, fin + 1)
        xx, yy, zz = np.meshgrid(x, y, z)
        r = np.sqrt(xx**2 + yy**2 + zz**2)
        km = 0.8 * np.pi
        rm = ini
        w = rm / 10
        term1 = np.sin((km * r**2) / (2 * rm))
        term2 = 0.5 * np.tanh((rm - r) / w) + 0.5
        g = term1 * term2
        affine = np.eye(4)
        origin = np.array([ini, ini, ini])
        affine[:3, 3] = origin
        return ScalarImage(g[np.newaxis], affine=affine)

metadata property

Non-spatial metadata.

spatial_shape property

Spatial shape, checked for consistency across all images.

shape property

Shape of the first image, checked for consistency.

spacing property

Spacing from the first image, checked for consistency.

device property

Device of the data, checked for consistency across all entries.

images property

Dict of all Image entries.

points property

Dict of all Points entries.

bounding_boxes property

Dict of all BoundingBoxes entries.

get_inverse_transform(*, warn=True, ignore_intensity=False)

Get a composed transform that inverts the applied history.

Returns a Compose of the inverse of each applied transform, in reverse order. Non-invertible transforms are skipped (with a warning if warn=True).

Parameters:

Name Type Description Default
warn bool

Issue a warning for non-invertible transforms.

True
ignore_intensity bool

Skip all intensity transforms.

False

Returns:

Type Description
Any

A Compose transform that undoes the history.

Source code in src/torchio/data/invertible.py
def get_inverse_transform(
    self,
    *,
    warn: bool = True,
    ignore_intensity: bool = False,
) -> Any:
    """Get a composed transform that inverts the applied history.

    Returns a [`Compose`][torchio.Compose] of the inverse of each
    applied transform, in reverse order. Non-invertible transforms
    are skipped (with a warning if `warn=True`).

    Args:
        warn: Issue a warning for non-invertible transforms.
        ignore_intensity: Skip all intensity transforms.

    Returns:
        A `Compose` transform that undoes the history.
    """
    from ..transforms.inverse import get_inverse_transform

    return get_inverse_transform(
        self.applied_transforms,
        warn=warn,
        ignore_intensity=ignore_intensity,
    )

apply_inverse_transform(**kwargs)

Apply the inverse of all applied transforms, in reverse order.

Non-invertible transforms are skipped. Intensity transforms can be ignored with ignore_intensity=True.

Parameters:

Name Type Description Default
**kwargs Any

Forwarded to get_inverse_transform() (warn, ignore_intensity).

{}

Returns:

Type Description
Self

Data with transforms undone.

Examples:

>>> transformed = transform(subject)
>>> restored = transformed.apply_inverse_transform()
Source code in src/torchio/data/invertible.py
def apply_inverse_transform(self, **kwargs: Any) -> Self:
    """Apply the inverse of all applied transforms, in reverse order.

    Non-invertible transforms are skipped. Intensity transforms
    can be ignored with `ignore_intensity=True`.

    Args:
        **kwargs: Forwarded to
            `get_inverse_transform()` (`warn`,
            `ignore_intensity`).

    Returns:
        Data with transforms undone.

    Examples:
        >>> transformed = transform(subject)
        >>> restored = transformed.apply_inverse_transform()
    """
    inverse_transform = self.get_inverse_transform(**kwargs)
    result = inverse_transform(self)
    if hasattr(result, "applied_transforms"):
        result.applied_transforms = []
    return result

clear_history()

Remove all applied transform records.

Source code in src/torchio/data/invertible.py
def clear_history(self) -> None:
    """Remove all applied transform records."""
    self.applied_transforms = []

all_points()

Collect points from both subject-level and image-level.

Subject-level points are keyed by their name (str). Image-level points are keyed by a (image_name, points_name) tuple.

Returns:

Type Description
dict[str | tuple[str, str], Points]

Merged dict of all points across both levels.

Source code in src/torchio/data/subject.py
def all_points(self) -> dict[str | tuple[str, str], Points]:
    """Collect points from both subject-level and image-level.

    Subject-level points are keyed by their name (`str`).
    Image-level points are keyed by a `(image_name, points_name)`
    tuple.

    Returns:
        Merged dict of all points across both levels.
    """
    result: dict[str | tuple[str, str], Points] = {}
    result.update(self._points)
    for image_name, image in self._images.items():
        for points_name, pts in image.points.items():
            result[(image_name, points_name)] = pts
    return result

all_bounding_boxes()

Collect bounding boxes from both subject-level and image-level.

Subject-level boxes are keyed by their name (str). Image-level boxes are keyed by a (image_name, boxes_name) tuple.

Returns:

Type Description
dict[str | tuple[str, str], BoundingBoxes]

Merged dict of all bounding boxes across both levels.

Source code in src/torchio/data/subject.py
def all_bounding_boxes(
    self,
) -> dict[str | tuple[str, str], BoundingBoxes]:
    """Collect bounding boxes from both subject-level and image-level.

    Subject-level boxes are keyed by their name (`str`).
    Image-level boxes are keyed by a `(image_name, boxes_name)`
    tuple.

    Returns:
        Merged dict of all bounding boxes across both levels.
    """
    result: dict[str | tuple[str, str], BoundingBoxes] = {}
    result.update(self._bounding_boxes)
    for image_name, image in self._images.items():
        for box_name, boxes in image.bounding_boxes.items():
            result[(image_name, box_name)] = boxes
    return result

load()

Load all images from disk.

Source code in src/torchio/data/subject.py
def load(self) -> None:
    """Load all images from disk."""
    for image in self._images.values():
        image.load()

to(*args, **kwargs)

Move all data to a device and/or cast to a dtype.

Calls .to() on every Image, Points, and BoundingBoxes.

Returns:

Type Description
Self

self (modified in-place).

Source code in src/torchio/data/subject.py
def to(self, *args: Any, **kwargs: Any) -> Self:
    """Move all data to a device and/or cast to a dtype.

    Calls `.to()` on every Image, Points, and BoundingBoxes.

    Returns:
        `self` (modified in-place).
    """
    for image in self._images.values():
        image.to(*args, **kwargs)
    for pts in self._points.values():
        pts.to(*args, **kwargs)
    for boxes in self._bounding_boxes.values():
        boxes.to(*args, **kwargs)
    return self

plot(**kwargs)

Plot all images as a grid of orthogonal slices.

Requires the [plot] extras (pip install torchio[plot]). See plot_subject for the full list of keyword arguments.

Source code in src/torchio/data/subject.py
def plot(self, **kwargs: Any) -> Any:
    """Plot all images as a grid of orthogonal slices.

    Requires the `[plot]` extras (`pip install torchio[plot]`).
    See [`plot_subject`][torchio.visualization.plot_subject] for the
    full list of keyword arguments.
    """
    from ..visualization import plot_subject

    return plot_subject(self, **kwargs)

MNI

Colin27

Bases: SubjectMNI

Colin27 MNI template.

More information can be found in the website of the 1998 <https://nist.mni.mcgill.ca/colin-27-average-brain/> and 2008 <http://www.bic.mni.mcgill.ca/ServicesAtlases/Colin27Highres> versions.

Parameters:

Name Type Description Default
version int

Template year. It can be 1998 or 2008.

1998
Warning

The resolution of the 2008 version is quite high. The subject instance will contain four images of size 362 x 434 x 362, therefore applying a transform to it might take longer than expected.

Source code in src/torchio/datasets/mni/colin.py
class Colin27(SubjectMNI):
    """Colin27 MNI template.

    More information can be found in the website of the
    `1998 <https://nist.mni.mcgill.ca/colin-27-average-brain/>`_ and
    `2008 <http://www.bic.mni.mcgill.ca/ServicesAtlases/Colin27Highres>`_
    versions.

    Args:
        version: Template year. It can be `1998` or `2008`.

    Warning:
        The resolution of the `2008` version is quite high. The
        subject instance will contain four images of size
        362 x 434 x 362, therefore applying a transform to
        it might take longer than expected.
    """

    NAME_TO_LABEL: ClassVar[dict[str, int]] = {
        name: label for label, name in TISSUES_2008.items()
    }

    def __init__(self, version: int = 1998) -> None:
        if version not in (1998, 2008):
            msg = f'Version must be 1998 or 2008, not "{version}"'
            raise ValueError(msg)
        self.version = version
        self.name = f"mni_colin27_{version}_nifti"
        self.url_dir = urllib.parse.urljoin(self.url_base, "colin27/")
        self.filename = f"{self.name}.zip"
        self.url = urllib.parse.urljoin(self.url_dir, self.filename)
        if not self.download_root.is_dir():
            download_and_extract_archive(
                self.url,
                download_root=self.download_root,
                filename=self.filename,
            )
            # Fix label map
            # https://github.com/TorchIO-project/torchio/issues/220
            if version == 2008:
                path = self.download_root / "colin27_cls_tal_hires.nii"
                cls_image = LabelMap(path)
                cls_image.set_data(cls_image.data.round().byte())
                cls_image.save(path)

            (self.download_root / self.filename).unlink()
            for path in self.download_root.glob("*.nii"):
                compress(path)
                path.unlink()

        subject_kwargs = self._get_subject_kwargs(
            self.download_root,
            extension=".nii.gz",
        )
        super().__init__(**subject_kwargs)

    def _get_subject_kwargs(self, download_root, extension):
        if self.version == 1998:
            return _get_colin1998_kwargs(download_root, extension)
        return _get_colin2008_kwargs(download_root, extension)

metadata property

Non-spatial metadata.

spatial_shape property

Spatial shape, checked for consistency across all images.

shape property

Shape of the first image, checked for consistency.

spacing property

Spacing from the first image, checked for consistency.

device property

Device of the data, checked for consistency across all entries.

images property

Dict of all Image entries.

points property

Dict of all Points entries.

bounding_boxes property

Dict of all BoundingBoxes entries.

download_root property

Return the download root directory for this atlas.

get_inverse_transform(*, warn=True, ignore_intensity=False)

Get a composed transform that inverts the applied history.

Returns a Compose of the inverse of each applied transform, in reverse order. Non-invertible transforms are skipped (with a warning if warn=True).

Parameters:

Name Type Description Default
warn bool

Issue a warning for non-invertible transforms.

True
ignore_intensity bool

Skip all intensity transforms.

False

Returns:

Type Description
Any

A Compose transform that undoes the history.

Source code in src/torchio/data/invertible.py
def get_inverse_transform(
    self,
    *,
    warn: bool = True,
    ignore_intensity: bool = False,
) -> Any:
    """Get a composed transform that inverts the applied history.

    Returns a [`Compose`][torchio.Compose] of the inverse of each
    applied transform, in reverse order. Non-invertible transforms
    are skipped (with a warning if `warn=True`).

    Args:
        warn: Issue a warning for non-invertible transforms.
        ignore_intensity: Skip all intensity transforms.

    Returns:
        A `Compose` transform that undoes the history.
    """
    from ..transforms.inverse import get_inverse_transform

    return get_inverse_transform(
        self.applied_transforms,
        warn=warn,
        ignore_intensity=ignore_intensity,
    )

apply_inverse_transform(**kwargs)

Apply the inverse of all applied transforms, in reverse order.

Non-invertible transforms are skipped. Intensity transforms can be ignored with ignore_intensity=True.

Parameters:

Name Type Description Default
**kwargs Any

Forwarded to get_inverse_transform() (warn, ignore_intensity).

{}

Returns:

Type Description
Self

Data with transforms undone.

Examples:

>>> transformed = transform(subject)
>>> restored = transformed.apply_inverse_transform()
Source code in src/torchio/data/invertible.py
def apply_inverse_transform(self, **kwargs: Any) -> Self:
    """Apply the inverse of all applied transforms, in reverse order.

    Non-invertible transforms are skipped. Intensity transforms
    can be ignored with `ignore_intensity=True`.

    Args:
        **kwargs: Forwarded to
            `get_inverse_transform()` (`warn`,
            `ignore_intensity`).

    Returns:
        Data with transforms undone.

    Examples:
        >>> transformed = transform(subject)
        >>> restored = transformed.apply_inverse_transform()
    """
    inverse_transform = self.get_inverse_transform(**kwargs)
    result = inverse_transform(self)
    if hasattr(result, "applied_transforms"):
        result.applied_transforms = []
    return result

clear_history()

Remove all applied transform records.

Source code in src/torchio/data/invertible.py
def clear_history(self) -> None:
    """Remove all applied transform records."""
    self.applied_transforms = []

all_points()

Collect points from both subject-level and image-level.

Subject-level points are keyed by their name (str). Image-level points are keyed by a (image_name, points_name) tuple.

Returns:

Type Description
dict[str | tuple[str, str], Points]

Merged dict of all points across both levels.

Source code in src/torchio/data/subject.py
def all_points(self) -> dict[str | tuple[str, str], Points]:
    """Collect points from both subject-level and image-level.

    Subject-level points are keyed by their name (`str`).
    Image-level points are keyed by a `(image_name, points_name)`
    tuple.

    Returns:
        Merged dict of all points across both levels.
    """
    result: dict[str | tuple[str, str], Points] = {}
    result.update(self._points)
    for image_name, image in self._images.items():
        for points_name, pts in image.points.items():
            result[(image_name, points_name)] = pts
    return result

all_bounding_boxes()

Collect bounding boxes from both subject-level and image-level.

Subject-level boxes are keyed by their name (str). Image-level boxes are keyed by a (image_name, boxes_name) tuple.

Returns:

Type Description
dict[str | tuple[str, str], BoundingBoxes]

Merged dict of all bounding boxes across both levels.

Source code in src/torchio/data/subject.py
def all_bounding_boxes(
    self,
) -> dict[str | tuple[str, str], BoundingBoxes]:
    """Collect bounding boxes from both subject-level and image-level.

    Subject-level boxes are keyed by their name (`str`).
    Image-level boxes are keyed by a `(image_name, boxes_name)`
    tuple.

    Returns:
        Merged dict of all bounding boxes across both levels.
    """
    result: dict[str | tuple[str, str], BoundingBoxes] = {}
    result.update(self._bounding_boxes)
    for image_name, image in self._images.items():
        for box_name, boxes in image.bounding_boxes.items():
            result[(image_name, box_name)] = boxes
    return result

load()

Load all images from disk.

Source code in src/torchio/data/subject.py
def load(self) -> None:
    """Load all images from disk."""
    for image in self._images.values():
        image.load()

to(*args, **kwargs)

Move all data to a device and/or cast to a dtype.

Calls .to() on every Image, Points, and BoundingBoxes.

Returns:

Type Description
Self

self (modified in-place).

Source code in src/torchio/data/subject.py
def to(self, *args: Any, **kwargs: Any) -> Self:
    """Move all data to a device and/or cast to a dtype.

    Calls `.to()` on every Image, Points, and BoundingBoxes.

    Returns:
        `self` (modified in-place).
    """
    for image in self._images.values():
        image.to(*args, **kwargs)
    for pts in self._points.values():
        pts.to(*args, **kwargs)
    for boxes in self._bounding_boxes.values():
        boxes.to(*args, **kwargs)
    return self

plot(**kwargs)

Plot all images as a grid of orthogonal slices.

Requires the [plot] extras (pip install torchio[plot]). See plot_subject for the full list of keyword arguments.

Source code in src/torchio/data/subject.py
def plot(self, **kwargs: Any) -> Any:
    """Plot all images as a grid of orthogonal slices.

    Requires the `[plot]` extras (`pip install torchio[plot]`).
    See [`plot_subject`][torchio.visualization.plot_subject] for the
    full list of keyword arguments.
    """
    from ..visualization import plot_subject

    return plot_subject(self, **kwargs)

ICBM2009CNonlinearSymmetric

Bases: SubjectMNI

ICBM template.

More information can be found in the website <http://www.bic.mni.mcgill.ca/ServicesAtlases/ICBM152NLin2009>_.

Parameters:

Name Type Description Default
load_4d_tissues bool

If True, the tissue probability maps will be loaded together into a 4D image. Otherwise, they will be loaded into independent images.

False
Source code in src/torchio/datasets/mni/icbm.py
class ICBM2009CNonlinearSymmetric(SubjectMNI):
    r"""ICBM template.

    More information can be found in the
    `website <http://www.bic.mni.mcgill.ca/ServicesAtlases/ICBM152NLin2009>`_.

    Args:
        load_4d_tissues: If `True`, the tissue probability maps will be
            loaded together into a 4D image. Otherwise, they will be loaded
            into independent images.
    """

    def __init__(self, load_4d_tissues: bool = False) -> None:
        self.name = "mni_icbm152_nlin_sym_09c_nifti"
        self.url_base = "http://www.bic.mni.mcgill.ca/~vfonov/icbm/2009/"
        self.filename = f"{self.name}.zip"
        self.url = urllib.parse.urljoin(self.url_base, self.filename)
        download_root = get_torchio_cache_dir() / self.name
        if not download_root.is_dir():
            download_and_extract_archive(
                self.url,
                download_root=download_root,
                filename=self.filename,
                remove_finished=True,
            )

        files_dir = download_root / "mni_icbm152_nlin_sym_09c"

        p = str(files_dir / "mni_icbm152")
        m = "tal_nlin_sym_09c"
        s = ".nii.gz"

        tissues_path = f"{p}_tissues_{m}.nii.gz"
        if not Path(tissues_path).is_file():
            gm = LabelMap(f"{p}_gm_{m}.nii")
            wm = LabelMap(f"{p}_wm_{m}.nii")
            csf = LabelMap(f"{p}_csf_{m}.nii")
            gm.load()
            wm.load()
            csf.load()
            gm.set_data(torch.cat((gm.data, wm.data, csf.data)))
            gm.save(tissues_path)

        for fp in files_dir.glob("*.nii"):
            compress(fp, fp.with_suffix(".nii.gz"))
            fp.unlink()

        subject_kwargs: dict[str, ScalarImage | LabelMap] = {
            "t1": ScalarImage(f"{p}_t1_{m}{s}"),
            "eyes": LabelMap(f"{p}_t1_{m}_eye_mask{s}"),
            "face": LabelMap(f"{p}_t1_{m}_face_mask{s}"),
            "brain": LabelMap(f"{p}_t1_{m}_mask{s}"),
            "t2": ScalarImage(f"{p}_t2_{m}{s}"),
            "pd": ScalarImage(f"{p}_csf_{m}{s}"),
        }
        if load_4d_tissues:
            subject_kwargs["tissues"] = LabelMap(
                tissues_path,
                channels_last=True,
            )
        else:
            subject_kwargs["gm"] = LabelMap(f"{p}_gm_{m}{s}")
            subject_kwargs["wm"] = LabelMap(f"{p}_wm_{m}{s}")
            subject_kwargs["csf"] = LabelMap(f"{p}_csf_{m}{s}")

        super().__init__(**subject_kwargs)

metadata property

Non-spatial metadata.

spatial_shape property

Spatial shape, checked for consistency across all images.

shape property

Shape of the first image, checked for consistency.

spacing property

Spacing from the first image, checked for consistency.

device property

Device of the data, checked for consistency across all entries.

images property

Dict of all Image entries.

points property

Dict of all Points entries.

bounding_boxes property

Dict of all BoundingBoxes entries.

download_root property

Return the download root directory for this atlas.

get_inverse_transform(*, warn=True, ignore_intensity=False)

Get a composed transform that inverts the applied history.

Returns a Compose of the inverse of each applied transform, in reverse order. Non-invertible transforms are skipped (with a warning if warn=True).

Parameters:

Name Type Description Default
warn bool

Issue a warning for non-invertible transforms.

True
ignore_intensity bool

Skip all intensity transforms.

False

Returns:

Type Description
Any

A Compose transform that undoes the history.

Source code in src/torchio/data/invertible.py
def get_inverse_transform(
    self,
    *,
    warn: bool = True,
    ignore_intensity: bool = False,
) -> Any:
    """Get a composed transform that inverts the applied history.

    Returns a [`Compose`][torchio.Compose] of the inverse of each
    applied transform, in reverse order. Non-invertible transforms
    are skipped (with a warning if `warn=True`).

    Args:
        warn: Issue a warning for non-invertible transforms.
        ignore_intensity: Skip all intensity transforms.

    Returns:
        A `Compose` transform that undoes the history.
    """
    from ..transforms.inverse import get_inverse_transform

    return get_inverse_transform(
        self.applied_transforms,
        warn=warn,
        ignore_intensity=ignore_intensity,
    )

apply_inverse_transform(**kwargs)

Apply the inverse of all applied transforms, in reverse order.

Non-invertible transforms are skipped. Intensity transforms can be ignored with ignore_intensity=True.

Parameters:

Name Type Description Default
**kwargs Any

Forwarded to get_inverse_transform() (warn, ignore_intensity).

{}

Returns:

Type Description
Self

Data with transforms undone.

Examples:

>>> transformed = transform(subject)
>>> restored = transformed.apply_inverse_transform()
Source code in src/torchio/data/invertible.py
def apply_inverse_transform(self, **kwargs: Any) -> Self:
    """Apply the inverse of all applied transforms, in reverse order.

    Non-invertible transforms are skipped. Intensity transforms
    can be ignored with `ignore_intensity=True`.

    Args:
        **kwargs: Forwarded to
            `get_inverse_transform()` (`warn`,
            `ignore_intensity`).

    Returns:
        Data with transforms undone.

    Examples:
        >>> transformed = transform(subject)
        >>> restored = transformed.apply_inverse_transform()
    """
    inverse_transform = self.get_inverse_transform(**kwargs)
    result = inverse_transform(self)
    if hasattr(result, "applied_transforms"):
        result.applied_transforms = []
    return result

clear_history()

Remove all applied transform records.

Source code in src/torchio/data/invertible.py
def clear_history(self) -> None:
    """Remove all applied transform records."""
    self.applied_transforms = []

all_points()

Collect points from both subject-level and image-level.

Subject-level points are keyed by their name (str). Image-level points are keyed by a (image_name, points_name) tuple.

Returns:

Type Description
dict[str | tuple[str, str], Points]

Merged dict of all points across both levels.

Source code in src/torchio/data/subject.py
def all_points(self) -> dict[str | tuple[str, str], Points]:
    """Collect points from both subject-level and image-level.

    Subject-level points are keyed by their name (`str`).
    Image-level points are keyed by a `(image_name, points_name)`
    tuple.

    Returns:
        Merged dict of all points across both levels.
    """
    result: dict[str | tuple[str, str], Points] = {}
    result.update(self._points)
    for image_name, image in self._images.items():
        for points_name, pts in image.points.items():
            result[(image_name, points_name)] = pts
    return result

all_bounding_boxes()

Collect bounding boxes from both subject-level and image-level.

Subject-level boxes are keyed by their name (str). Image-level boxes are keyed by a (image_name, boxes_name) tuple.

Returns:

Type Description
dict[str | tuple[str, str], BoundingBoxes]

Merged dict of all bounding boxes across both levels.

Source code in src/torchio/data/subject.py
def all_bounding_boxes(
    self,
) -> dict[str | tuple[str, str], BoundingBoxes]:
    """Collect bounding boxes from both subject-level and image-level.

    Subject-level boxes are keyed by their name (`str`).
    Image-level boxes are keyed by a `(image_name, boxes_name)`
    tuple.

    Returns:
        Merged dict of all bounding boxes across both levels.
    """
    result: dict[str | tuple[str, str], BoundingBoxes] = {}
    result.update(self._bounding_boxes)
    for image_name, image in self._images.items():
        for box_name, boxes in image.bounding_boxes.items():
            result[(image_name, box_name)] = boxes
    return result

load()

Load all images from disk.

Source code in src/torchio/data/subject.py
def load(self) -> None:
    """Load all images from disk."""
    for image in self._images.values():
        image.load()

to(*args, **kwargs)

Move all data to a device and/or cast to a dtype.

Calls .to() on every Image, Points, and BoundingBoxes.

Returns:

Type Description
Self

self (modified in-place).

Source code in src/torchio/data/subject.py
def to(self, *args: Any, **kwargs: Any) -> Self:
    """Move all data to a device and/or cast to a dtype.

    Calls `.to()` on every Image, Points, and BoundingBoxes.

    Returns:
        `self` (modified in-place).
    """
    for image in self._images.values():
        image.to(*args, **kwargs)
    for pts in self._points.values():
        pts.to(*args, **kwargs)
    for boxes in self._bounding_boxes.values():
        boxes.to(*args, **kwargs)
    return self

plot(**kwargs)

Plot all images as a grid of orthogonal slices.

Requires the [plot] extras (pip install torchio[plot]). See plot_subject for the full list of keyword arguments.

Source code in src/torchio/data/subject.py
def plot(self, **kwargs: Any) -> Any:
    """Plot all images as a grid of orthogonal slices.

    Requires the `[plot]` extras (`pip install torchio[plot]`).
    See [`plot_subject`][torchio.visualization.plot_subject] for the
    full list of keyword arguments.
    """
    from ..visualization import plot_subject

    return plot_subject(self, **kwargs)

Pediatric

Bases: SubjectMNI

MNI pediatric atlases.

See the MNI website <https://nist.mni.mcgill.ca/pediatric-atlases-4-5-18-5y/>_ for more information.

Parameters:

Name Type Description Default
years tuple[float, float]

Tuple of 2 ages. Possible values are: (4.5, 18.5), (4.5, 8.5), (7, 11), (7.5, 13.5), (10, 14) and (13, 18.5).

required
symmetric bool

If True, the left-right symmetric templates will be used. Otherwise, the asymmetric (natural) templates will be used.

False
Source code in src/torchio/datasets/mni/pediatric.py
class Pediatric(SubjectMNI):
    """MNI pediatric atlases.

    See `the MNI website
    <https://nist.mni.mcgill.ca/pediatric-atlases-4-5-18-5y/>`_
    for more information.

    Args:
        years: Tuple of 2 ages. Possible values are: `(4.5, 18.5)`,
            `(4.5, 8.5)`, `(7, 11)`, `(7.5, 13.5)`,
            `(10, 14)` and `(13, 18.5)`.
        symmetric: If `True`, the left-right symmetric templates will be
            used. Otherwise, the asymmetric (natural) templates will be used.
    """

    def __init__(
        self,
        years: tuple[float, float],
        symmetric: bool = False,
    ) -> None:
        self.url_dir = "http://www.bic.mni.mcgill.ca/~vfonov/nihpd/obj1/"
        sym_string = "sym" if symmetric else "asym"
        if not isinstance(years, tuple) or years not in SUPPORTED_YEARS:
            message = f"Years must be a tuple in {SUPPORTED_YEARS}"
            raise ValueError(message)
        a, b = years
        self.file_id = f"{sym_string}_{_format_age(a)}-{_format_age(b)}"
        self.name = f"nihpd_{self.file_id}_nifti"
        self.filename = f"{self.name}.zip"
        self.url = urllib.parse.urljoin(self.url_dir, self.filename)
        if not self.download_root.is_dir():
            download_and_extract_archive(
                self.url,
                download_root=self.download_root,
                filename=self.filename,
            )
            (self.download_root / self.filename).unlink()
            for path in self.download_root.glob("*.nii"):
                compress(path)
                path.unlink()

        subject_kwargs = self._get_subject_kwargs(".nii.gz")
        super().__init__(**subject_kwargs)

    def _get_subject_kwargs(self, extension: str) -> dict:
        root = self.download_root
        return {
            "t1": ScalarImage(root / f"nihpd_{self.file_id}_t1w{extension}"),
            "t2": ScalarImage(root / f"nihpd_{self.file_id}_t2w{extension}"),
            "pd": ScalarImage(root / f"nihpd_{self.file_id}_pdw{extension}"),
            "mask": LabelMap(root / f"nihpd_{self.file_id}_mask{extension}"),
        }

metadata property

Non-spatial metadata.

spatial_shape property

Spatial shape, checked for consistency across all images.

shape property

Shape of the first image, checked for consistency.

spacing property

Spacing from the first image, checked for consistency.

device property

Device of the data, checked for consistency across all entries.

images property

Dict of all Image entries.

points property

Dict of all Points entries.

bounding_boxes property

Dict of all BoundingBoxes entries.

download_root property

Return the download root directory for this atlas.

get_inverse_transform(*, warn=True, ignore_intensity=False)

Get a composed transform that inverts the applied history.

Returns a Compose of the inverse of each applied transform, in reverse order. Non-invertible transforms are skipped (with a warning if warn=True).

Parameters:

Name Type Description Default
warn bool

Issue a warning for non-invertible transforms.

True
ignore_intensity bool

Skip all intensity transforms.

False

Returns:

Type Description
Any

A Compose transform that undoes the history.

Source code in src/torchio/data/invertible.py
def get_inverse_transform(
    self,
    *,
    warn: bool = True,
    ignore_intensity: bool = False,
) -> Any:
    """Get a composed transform that inverts the applied history.

    Returns a [`Compose`][torchio.Compose] of the inverse of each
    applied transform, in reverse order. Non-invertible transforms
    are skipped (with a warning if `warn=True`).

    Args:
        warn: Issue a warning for non-invertible transforms.
        ignore_intensity: Skip all intensity transforms.

    Returns:
        A `Compose` transform that undoes the history.
    """
    from ..transforms.inverse import get_inverse_transform

    return get_inverse_transform(
        self.applied_transforms,
        warn=warn,
        ignore_intensity=ignore_intensity,
    )

apply_inverse_transform(**kwargs)

Apply the inverse of all applied transforms, in reverse order.

Non-invertible transforms are skipped. Intensity transforms can be ignored with ignore_intensity=True.

Parameters:

Name Type Description Default
**kwargs Any

Forwarded to get_inverse_transform() (warn, ignore_intensity).

{}

Returns:

Type Description
Self

Data with transforms undone.

Examples:

>>> transformed = transform(subject)
>>> restored = transformed.apply_inverse_transform()
Source code in src/torchio/data/invertible.py
def apply_inverse_transform(self, **kwargs: Any) -> Self:
    """Apply the inverse of all applied transforms, in reverse order.

    Non-invertible transforms are skipped. Intensity transforms
    can be ignored with `ignore_intensity=True`.

    Args:
        **kwargs: Forwarded to
            `get_inverse_transform()` (`warn`,
            `ignore_intensity`).

    Returns:
        Data with transforms undone.

    Examples:
        >>> transformed = transform(subject)
        >>> restored = transformed.apply_inverse_transform()
    """
    inverse_transform = self.get_inverse_transform(**kwargs)
    result = inverse_transform(self)
    if hasattr(result, "applied_transforms"):
        result.applied_transforms = []
    return result

clear_history()

Remove all applied transform records.

Source code in src/torchio/data/invertible.py
def clear_history(self) -> None:
    """Remove all applied transform records."""
    self.applied_transforms = []

all_points()

Collect points from both subject-level and image-level.

Subject-level points are keyed by their name (str). Image-level points are keyed by a (image_name, points_name) tuple.

Returns:

Type Description
dict[str | tuple[str, str], Points]

Merged dict of all points across both levels.

Source code in src/torchio/data/subject.py
def all_points(self) -> dict[str | tuple[str, str], Points]:
    """Collect points from both subject-level and image-level.

    Subject-level points are keyed by their name (`str`).
    Image-level points are keyed by a `(image_name, points_name)`
    tuple.

    Returns:
        Merged dict of all points across both levels.
    """
    result: dict[str | tuple[str, str], Points] = {}
    result.update(self._points)
    for image_name, image in self._images.items():
        for points_name, pts in image.points.items():
            result[(image_name, points_name)] = pts
    return result

all_bounding_boxes()

Collect bounding boxes from both subject-level and image-level.

Subject-level boxes are keyed by their name (str). Image-level boxes are keyed by a (image_name, boxes_name) tuple.

Returns:

Type Description
dict[str | tuple[str, str], BoundingBoxes]

Merged dict of all bounding boxes across both levels.

Source code in src/torchio/data/subject.py
def all_bounding_boxes(
    self,
) -> dict[str | tuple[str, str], BoundingBoxes]:
    """Collect bounding boxes from both subject-level and image-level.

    Subject-level boxes are keyed by their name (`str`).
    Image-level boxes are keyed by a `(image_name, boxes_name)`
    tuple.

    Returns:
        Merged dict of all bounding boxes across both levels.
    """
    result: dict[str | tuple[str, str], BoundingBoxes] = {}
    result.update(self._bounding_boxes)
    for image_name, image in self._images.items():
        for box_name, boxes in image.bounding_boxes.items():
            result[(image_name, box_name)] = boxes
    return result

load()

Load all images from disk.

Source code in src/torchio/data/subject.py
def load(self) -> None:
    """Load all images from disk."""
    for image in self._images.values():
        image.load()

to(*args, **kwargs)

Move all data to a device and/or cast to a dtype.

Calls .to() on every Image, Points, and BoundingBoxes.

Returns:

Type Description
Self

self (modified in-place).

Source code in src/torchio/data/subject.py
def to(self, *args: Any, **kwargs: Any) -> Self:
    """Move all data to a device and/or cast to a dtype.

    Calls `.to()` on every Image, Points, and BoundingBoxes.

    Returns:
        `self` (modified in-place).
    """
    for image in self._images.values():
        image.to(*args, **kwargs)
    for pts in self._points.values():
        pts.to(*args, **kwargs)
    for boxes in self._bounding_boxes.values():
        boxes.to(*args, **kwargs)
    return self

plot(**kwargs)

Plot all images as a grid of orthogonal slices.

Requires the [plot] extras (pip install torchio[plot]). See plot_subject for the full list of keyword arguments.

Source code in src/torchio/data/subject.py
def plot(self, **kwargs: Any) -> Any:
    """Plot all images as a grid of orthogonal slices.

    Requires the `[plot]` extras (`pip install torchio[plot]`).
    See [`plot_subject`][torchio.visualization.plot_subject] for the
    full list of keyword arguments.
    """
    from ..visualization import plot_subject

    return plot_subject(self, **kwargs)

Sheep

Bases: SubjectMNI

Ovine brain atlas at 0.5 mm resolution.

See the MNI website <https://nist.mni.mcgill.ca/?page_id=714>_ for more information.

Source code in src/torchio/datasets/mni/sheep.py
class Sheep(SubjectMNI):
    """Ovine brain atlas at 0.5 mm resolution.

    See `the MNI website
    <https://nist.mni.mcgill.ca/?page_id=714>`_ for more information.
    """

    def __init__(self) -> None:
        self.name = "NIFTI_ovine_05mm"
        self.url_dir = urllib.parse.urljoin(self.url_base, "sheep/")
        self.filename = f"{self.name}.zip"
        self.url = urllib.parse.urljoin(self.url_dir, self.filename)
        t1_nii_path = self.download_root / "ovine_model_05.nii"
        t1_niigz_path = self.download_root / "ovine_model_05.nii.gz"
        if not self.download_root.is_dir():
            download_and_extract_archive(
                self.url,
                download_root=self.download_root,
                filename=self.filename,
            )
            shutil.rmtree(self.download_root / "masks")
            for path in self.download_root.iterdir():
                if path == t1_nii_path:
                    compress(t1_nii_path, t1_niigz_path)
                path.unlink()
        super().__init__(t1=ScalarImage(t1_niigz_path))

metadata property

Non-spatial metadata.

spatial_shape property

Spatial shape, checked for consistency across all images.

shape property

Shape of the first image, checked for consistency.

spacing property

Spacing from the first image, checked for consistency.

device property

Device of the data, checked for consistency across all entries.

images property

Dict of all Image entries.

points property

Dict of all Points entries.

bounding_boxes property

Dict of all BoundingBoxes entries.

download_root property

Return the download root directory for this atlas.

get_inverse_transform(*, warn=True, ignore_intensity=False)

Get a composed transform that inverts the applied history.

Returns a Compose of the inverse of each applied transform, in reverse order. Non-invertible transforms are skipped (with a warning if warn=True).

Parameters:

Name Type Description Default
warn bool

Issue a warning for non-invertible transforms.

True
ignore_intensity bool

Skip all intensity transforms.

False

Returns:

Type Description
Any

A Compose transform that undoes the history.

Source code in src/torchio/data/invertible.py
def get_inverse_transform(
    self,
    *,
    warn: bool = True,
    ignore_intensity: bool = False,
) -> Any:
    """Get a composed transform that inverts the applied history.

    Returns a [`Compose`][torchio.Compose] of the inverse of each
    applied transform, in reverse order. Non-invertible transforms
    are skipped (with a warning if `warn=True`).

    Args:
        warn: Issue a warning for non-invertible transforms.
        ignore_intensity: Skip all intensity transforms.

    Returns:
        A `Compose` transform that undoes the history.
    """
    from ..transforms.inverse import get_inverse_transform

    return get_inverse_transform(
        self.applied_transforms,
        warn=warn,
        ignore_intensity=ignore_intensity,
    )

apply_inverse_transform(**kwargs)

Apply the inverse of all applied transforms, in reverse order.

Non-invertible transforms are skipped. Intensity transforms can be ignored with ignore_intensity=True.

Parameters:

Name Type Description Default
**kwargs Any

Forwarded to get_inverse_transform() (warn, ignore_intensity).

{}

Returns:

Type Description
Self

Data with transforms undone.

Examples:

>>> transformed = transform(subject)
>>> restored = transformed.apply_inverse_transform()
Source code in src/torchio/data/invertible.py
def apply_inverse_transform(self, **kwargs: Any) -> Self:
    """Apply the inverse of all applied transforms, in reverse order.

    Non-invertible transforms are skipped. Intensity transforms
    can be ignored with `ignore_intensity=True`.

    Args:
        **kwargs: Forwarded to
            `get_inverse_transform()` (`warn`,
            `ignore_intensity`).

    Returns:
        Data with transforms undone.

    Examples:
        >>> transformed = transform(subject)
        >>> restored = transformed.apply_inverse_transform()
    """
    inverse_transform = self.get_inverse_transform(**kwargs)
    result = inverse_transform(self)
    if hasattr(result, "applied_transforms"):
        result.applied_transforms = []
    return result

clear_history()

Remove all applied transform records.

Source code in src/torchio/data/invertible.py
def clear_history(self) -> None:
    """Remove all applied transform records."""
    self.applied_transforms = []

all_points()

Collect points from both subject-level and image-level.

Subject-level points are keyed by their name (str). Image-level points are keyed by a (image_name, points_name) tuple.

Returns:

Type Description
dict[str | tuple[str, str], Points]

Merged dict of all points across both levels.

Source code in src/torchio/data/subject.py
def all_points(self) -> dict[str | tuple[str, str], Points]:
    """Collect points from both subject-level and image-level.

    Subject-level points are keyed by their name (`str`).
    Image-level points are keyed by a `(image_name, points_name)`
    tuple.

    Returns:
        Merged dict of all points across both levels.
    """
    result: dict[str | tuple[str, str], Points] = {}
    result.update(self._points)
    for image_name, image in self._images.items():
        for points_name, pts in image.points.items():
            result[(image_name, points_name)] = pts
    return result

all_bounding_boxes()

Collect bounding boxes from both subject-level and image-level.

Subject-level boxes are keyed by their name (str). Image-level boxes are keyed by a (image_name, boxes_name) tuple.

Returns:

Type Description
dict[str | tuple[str, str], BoundingBoxes]

Merged dict of all bounding boxes across both levels.

Source code in src/torchio/data/subject.py
def all_bounding_boxes(
    self,
) -> dict[str | tuple[str, str], BoundingBoxes]:
    """Collect bounding boxes from both subject-level and image-level.

    Subject-level boxes are keyed by their name (`str`).
    Image-level boxes are keyed by a `(image_name, boxes_name)`
    tuple.

    Returns:
        Merged dict of all bounding boxes across both levels.
    """
    result: dict[str | tuple[str, str], BoundingBoxes] = {}
    result.update(self._bounding_boxes)
    for image_name, image in self._images.items():
        for box_name, boxes in image.bounding_boxes.items():
            result[(image_name, box_name)] = boxes
    return result

load()

Load all images from disk.

Source code in src/torchio/data/subject.py
def load(self) -> None:
    """Load all images from disk."""
    for image in self._images.values():
        image.load()

to(*args, **kwargs)

Move all data to a device and/or cast to a dtype.

Calls .to() on every Image, Points, and BoundingBoxes.

Returns:

Type Description
Self

self (modified in-place).

Source code in src/torchio/data/subject.py
def to(self, *args: Any, **kwargs: Any) -> Self:
    """Move all data to a device and/or cast to a dtype.

    Calls `.to()` on every Image, Points, and BoundingBoxes.

    Returns:
        `self` (modified in-place).
    """
    for image in self._images.values():
        image.to(*args, **kwargs)
    for pts in self._points.values():
        pts.to(*args, **kwargs)
    for boxes in self._bounding_boxes.values():
        boxes.to(*args, **kwargs)
    return self

plot(**kwargs)

Plot all images as a grid of orthogonal slices.

Requires the [plot] extras (pip install torchio[plot]). See plot_subject for the full list of keyword arguments.

Source code in src/torchio/data/subject.py
def plot(self, **kwargs: Any) -> Any:
    """Plot all images as a grid of orthogonal slices.

    Requires the `[plot]` extras (`pip install torchio[plot]`).
    See [`plot_subject`][torchio.visualization.plot_subject] for the
    full list of keyword arguments.
    """
    from ..visualization import plot_subject

    return plot_subject(self, **kwargs)

IXI

ixi

IXI dataset: ~600 brain MRIs from healthy subjects.

The Information eXtraction from Images (IXI) <https://brain-development.org/ixi-dataset/>_ dataset contains nearly 600 MR images from normal, healthy subjects.

This data is made available under the Creative Commons CC BY-SA 3.0 license. If you use it, please acknowledge the source.

ixi(root, *, download=False, modalities=('T1', 'T2'))

Download and load the full IXI dataset.

Parameters:

Name Type Description Default
root TypePath

Root directory for the dataset.

required
download bool

If True, download the data into root.

False
modalities Sequence[str]

Modalities to include. Must be a subset of ('T1', 'T2', 'PD', 'MRA', 'DTI').

('T1', 'T2')

Returns:

Type Description
list[Subject]

List of subjects, one per scan with all requested modalities.

Warning

The dataset is several GB. Downloading may take a while.

Source code in src/torchio/datasets/ixi.py
def ixi(
    root: TypePath,
    *,
    download: bool = False,
    modalities: Sequence[str] = ("T1", "T2"),
) -> list[Subject]:
    """Download and load the full IXI dataset.

    Args:
        root: Root directory for the dataset.
        download: If `True`, download the data into `root`.
        modalities: Modalities to include. Must be a subset of
            `('T1', 'T2', 'PD', 'MRA', 'DTI')`.

    Returns:
        List of subjects, one per scan with all requested modalities.

    Warning:
        The dataset is several GB. Downloading may take a while.
    """
    root = Path(root)
    md5s = _IXI_MD5
    for m in modalities:
        if m not in md5s:
            msg = f'Modality "{m}" must be one of {tuple(md5s.keys())}'
            raise ValueError(msg)
    if download:
        _download_ixi(root, modalities, md5s)
    if not all((root / m).is_dir() for m in modalities):
        msg = "Dataset not found. Use download=True to download it"
        raise RuntimeError(msg)
    return _load_ixi_subjects(root, modalities)

ixi_tiny(root, *, download=False)

Download and load IXITiny (566 \(T_1\) images + segmentations).

All images have shape \(83 \times 44 \times 55\). Useful as a medical image MNIST for quick experiments.

Parameters:

Name Type Description Default
root TypePath

Root directory for the dataset.

required
download bool

If True, download the data into root.

False

Returns:

Type Description
list[Subject]

List of subjects with image and label keys.

Source code in src/torchio/datasets/ixi.py
def ixi_tiny(
    root: TypePath,
    *,
    download: bool = False,
) -> list[Subject]:
    r"""Download and load IXITiny (566 $T_1$ images + segmentations).

    All images have shape $83 \times 44 \times 55$. Useful as a
    medical image MNIST for quick experiments.

    Args:
        root: Root directory for the dataset.
        download: If `True`, download the data into `root`.

    Returns:
        List of subjects with `image` and `label` keys.
    """
    root = Path(root)
    if download:
        _download_ixi_tiny(root)
    if not root.is_dir():
        msg = "Dataset not found. Use download=True to download it"
        raise RuntimeError(msg)
    return _load_ixi_tiny_subjects(root)

ixi_tiny(root, *, download=False)

Download and load IXITiny (566 \(T_1\) images + segmentations).

All images have shape \(83 \times 44 \times 55\). Useful as a medical image MNIST for quick experiments.

Parameters:

Name Type Description Default
root TypePath

Root directory for the dataset.

required
download bool

If True, download the data into root.

False

Returns:

Type Description
list[Subject]

List of subjects with image and label keys.

Source code in src/torchio/datasets/ixi.py
def ixi_tiny(
    root: TypePath,
    *,
    download: bool = False,
) -> list[Subject]:
    r"""Download and load IXITiny (566 $T_1$ images + segmentations).

    All images have shape $83 \times 44 \times 55$. Useful as a
    medical image MNIST for quick experiments.

    Args:
        root: Root directory for the dataset.
        download: If `True`, download the data into `root`.

    Returns:
        List of subjects with `image` and `label` keys.
    """
    root = Path(root)
    if download:
        _download_ixi_tiny(root)
    if not root.is_dir():
        msg = "Dataset not found. Use download=True to download it"
        raise RuntimeError(msg)
    return _load_ixi_tiny_subjects(root)

ITK-SNAP

BrainTumor

Bases: SubjectITKSNAP

BRATS brain tumor sample data.

Source code in src/torchio/datasets/itk_snap/itk_snap.py
class BrainTumor(SubjectITKSNAP):
    """BRATS brain tumor sample data."""

    def __init__(self) -> None:
        super().__init__("braintumor", "6161")

    def _get_kwargs(self) -> dict:
        t1, t1c, t2, flair, seg = (
            self.download_root / self.name / f"BRATS_HG0015_{name}.mha"
            for name in ("T1", "T1C", "T2", "FLAIR", "truth")
        )
        return {
            "t1": ScalarImage(t1),
            "t1c": ScalarImage(t1c),
            "t2": ScalarImage(t2),
            "flair": ScalarImage(flair),
            "seg": LabelMap(seg),
        }

metadata property

Non-spatial metadata.

spatial_shape property

Spatial shape, checked for consistency across all images.

shape property

Shape of the first image, checked for consistency.

spacing property

Spacing from the first image, checked for consistency.

device property

Device of the data, checked for consistency across all entries.

images property

Dict of all Image entries.

points property

Dict of all Points entries.

bounding_boxes property

Dict of all BoundingBoxes entries.

get_inverse_transform(*, warn=True, ignore_intensity=False)

Get a composed transform that inverts the applied history.

Returns a Compose of the inverse of each applied transform, in reverse order. Non-invertible transforms are skipped (with a warning if warn=True).

Parameters:

Name Type Description Default
warn bool

Issue a warning for non-invertible transforms.

True
ignore_intensity bool

Skip all intensity transforms.

False

Returns:

Type Description
Any

A Compose transform that undoes the history.

Source code in src/torchio/data/invertible.py
def get_inverse_transform(
    self,
    *,
    warn: bool = True,
    ignore_intensity: bool = False,
) -> Any:
    """Get a composed transform that inverts the applied history.

    Returns a [`Compose`][torchio.Compose] of the inverse of each
    applied transform, in reverse order. Non-invertible transforms
    are skipped (with a warning if `warn=True`).

    Args:
        warn: Issue a warning for non-invertible transforms.
        ignore_intensity: Skip all intensity transforms.

    Returns:
        A `Compose` transform that undoes the history.
    """
    from ..transforms.inverse import get_inverse_transform

    return get_inverse_transform(
        self.applied_transforms,
        warn=warn,
        ignore_intensity=ignore_intensity,
    )

apply_inverse_transform(**kwargs)

Apply the inverse of all applied transforms, in reverse order.

Non-invertible transforms are skipped. Intensity transforms can be ignored with ignore_intensity=True.

Parameters:

Name Type Description Default
**kwargs Any

Forwarded to get_inverse_transform() (warn, ignore_intensity).

{}

Returns:

Type Description
Self

Data with transforms undone.

Examples:

>>> transformed = transform(subject)
>>> restored = transformed.apply_inverse_transform()
Source code in src/torchio/data/invertible.py
def apply_inverse_transform(self, **kwargs: Any) -> Self:
    """Apply the inverse of all applied transforms, in reverse order.

    Non-invertible transforms are skipped. Intensity transforms
    can be ignored with `ignore_intensity=True`.

    Args:
        **kwargs: Forwarded to
            `get_inverse_transform()` (`warn`,
            `ignore_intensity`).

    Returns:
        Data with transforms undone.

    Examples:
        >>> transformed = transform(subject)
        >>> restored = transformed.apply_inverse_transform()
    """
    inverse_transform = self.get_inverse_transform(**kwargs)
    result = inverse_transform(self)
    if hasattr(result, "applied_transforms"):
        result.applied_transforms = []
    return result

clear_history()

Remove all applied transform records.

Source code in src/torchio/data/invertible.py
def clear_history(self) -> None:
    """Remove all applied transform records."""
    self.applied_transforms = []

all_points()

Collect points from both subject-level and image-level.

Subject-level points are keyed by their name (str). Image-level points are keyed by a (image_name, points_name) tuple.

Returns:

Type Description
dict[str | tuple[str, str], Points]

Merged dict of all points across both levels.

Source code in src/torchio/data/subject.py
def all_points(self) -> dict[str | tuple[str, str], Points]:
    """Collect points from both subject-level and image-level.

    Subject-level points are keyed by their name (`str`).
    Image-level points are keyed by a `(image_name, points_name)`
    tuple.

    Returns:
        Merged dict of all points across both levels.
    """
    result: dict[str | tuple[str, str], Points] = {}
    result.update(self._points)
    for image_name, image in self._images.items():
        for points_name, pts in image.points.items():
            result[(image_name, points_name)] = pts
    return result

all_bounding_boxes()

Collect bounding boxes from both subject-level and image-level.

Subject-level boxes are keyed by their name (str). Image-level boxes are keyed by a (image_name, boxes_name) tuple.

Returns:

Type Description
dict[str | tuple[str, str], BoundingBoxes]

Merged dict of all bounding boxes across both levels.

Source code in src/torchio/data/subject.py
def all_bounding_boxes(
    self,
) -> dict[str | tuple[str, str], BoundingBoxes]:
    """Collect bounding boxes from both subject-level and image-level.

    Subject-level boxes are keyed by their name (`str`).
    Image-level boxes are keyed by a `(image_name, boxes_name)`
    tuple.

    Returns:
        Merged dict of all bounding boxes across both levels.
    """
    result: dict[str | tuple[str, str], BoundingBoxes] = {}
    result.update(self._bounding_boxes)
    for image_name, image in self._images.items():
        for box_name, boxes in image.bounding_boxes.items():
            result[(image_name, box_name)] = boxes
    return result

load()

Load all images from disk.

Source code in src/torchio/data/subject.py
def load(self) -> None:
    """Load all images from disk."""
    for image in self._images.values():
        image.load()

to(*args, **kwargs)

Move all data to a device and/or cast to a dtype.

Calls .to() on every Image, Points, and BoundingBoxes.

Returns:

Type Description
Self

self (modified in-place).

Source code in src/torchio/data/subject.py
def to(self, *args: Any, **kwargs: Any) -> Self:
    """Move all data to a device and/or cast to a dtype.

    Calls `.to()` on every Image, Points, and BoundingBoxes.

    Returns:
        `self` (modified in-place).
    """
    for image in self._images.values():
        image.to(*args, **kwargs)
    for pts in self._points.values():
        pts.to(*args, **kwargs)
    for boxes in self._bounding_boxes.values():
        boxes.to(*args, **kwargs)
    return self

plot(**kwargs)

Plot all images as a grid of orthogonal slices.

Requires the [plot] extras (pip install torchio[plot]). See plot_subject for the full list of keyword arguments.

Source code in src/torchio/data/subject.py
def plot(self, **kwargs: Any) -> Any:
    """Plot all images as a grid of orthogonal slices.

    Requires the `[plot]` extras (`pip install torchio[plot]`).
    See [`plot_subject`][torchio.visualization.plot_subject] for the
    full list of keyword arguments.
    """
    from ..visualization import plot_subject

    return plot_subject(self, **kwargs)

T1T2

Bases: SubjectITKSNAP

Multi-site T1 and T2 brain MRI.

Source code in src/torchio/datasets/itk_snap/itk_snap.py
class T1T2(SubjectITKSNAP):
    """Multi-site T1 and T2 brain MRI."""

    def __init__(self) -> None:
        super().__init__("ashs_test", "10983")

    def _get_kwargs(self) -> dict:
        mprage = self.download_root / self.name / "mprage_3T_bet_dr.nii"
        tse = self.download_root / self.name / "tse_3t_dr.nii"
        return {
            "mprage": ScalarImage(mprage),
            "tse": ScalarImage(tse),
        }

metadata property

Non-spatial metadata.

spatial_shape property

Spatial shape, checked for consistency across all images.

shape property

Shape of the first image, checked for consistency.

spacing property

Spacing from the first image, checked for consistency.

device property

Device of the data, checked for consistency across all entries.

images property

Dict of all Image entries.

points property

Dict of all Points entries.

bounding_boxes property

Dict of all BoundingBoxes entries.

get_inverse_transform(*, warn=True, ignore_intensity=False)

Get a composed transform that inverts the applied history.

Returns a Compose of the inverse of each applied transform, in reverse order. Non-invertible transforms are skipped (with a warning if warn=True).

Parameters:

Name Type Description Default
warn bool

Issue a warning for non-invertible transforms.

True
ignore_intensity bool

Skip all intensity transforms.

False

Returns:

Type Description
Any

A Compose transform that undoes the history.

Source code in src/torchio/data/invertible.py
def get_inverse_transform(
    self,
    *,
    warn: bool = True,
    ignore_intensity: bool = False,
) -> Any:
    """Get a composed transform that inverts the applied history.

    Returns a [`Compose`][torchio.Compose] of the inverse of each
    applied transform, in reverse order. Non-invertible transforms
    are skipped (with a warning if `warn=True`).

    Args:
        warn: Issue a warning for non-invertible transforms.
        ignore_intensity: Skip all intensity transforms.

    Returns:
        A `Compose` transform that undoes the history.
    """
    from ..transforms.inverse import get_inverse_transform

    return get_inverse_transform(
        self.applied_transforms,
        warn=warn,
        ignore_intensity=ignore_intensity,
    )

apply_inverse_transform(**kwargs)

Apply the inverse of all applied transforms, in reverse order.

Non-invertible transforms are skipped. Intensity transforms can be ignored with ignore_intensity=True.

Parameters:

Name Type Description Default
**kwargs Any

Forwarded to get_inverse_transform() (warn, ignore_intensity).

{}

Returns:

Type Description
Self

Data with transforms undone.

Examples:

>>> transformed = transform(subject)
>>> restored = transformed.apply_inverse_transform()
Source code in src/torchio/data/invertible.py
def apply_inverse_transform(self, **kwargs: Any) -> Self:
    """Apply the inverse of all applied transforms, in reverse order.

    Non-invertible transforms are skipped. Intensity transforms
    can be ignored with `ignore_intensity=True`.

    Args:
        **kwargs: Forwarded to
            `get_inverse_transform()` (`warn`,
            `ignore_intensity`).

    Returns:
        Data with transforms undone.

    Examples:
        >>> transformed = transform(subject)
        >>> restored = transformed.apply_inverse_transform()
    """
    inverse_transform = self.get_inverse_transform(**kwargs)
    result = inverse_transform(self)
    if hasattr(result, "applied_transforms"):
        result.applied_transforms = []
    return result

clear_history()

Remove all applied transform records.

Source code in src/torchio/data/invertible.py
def clear_history(self) -> None:
    """Remove all applied transform records."""
    self.applied_transforms = []

all_points()

Collect points from both subject-level and image-level.

Subject-level points are keyed by their name (str). Image-level points are keyed by a (image_name, points_name) tuple.

Returns:

Type Description
dict[str | tuple[str, str], Points]

Merged dict of all points across both levels.

Source code in src/torchio/data/subject.py
def all_points(self) -> dict[str | tuple[str, str], Points]:
    """Collect points from both subject-level and image-level.

    Subject-level points are keyed by their name (`str`).
    Image-level points are keyed by a `(image_name, points_name)`
    tuple.

    Returns:
        Merged dict of all points across both levels.
    """
    result: dict[str | tuple[str, str], Points] = {}
    result.update(self._points)
    for image_name, image in self._images.items():
        for points_name, pts in image.points.items():
            result[(image_name, points_name)] = pts
    return result

all_bounding_boxes()

Collect bounding boxes from both subject-level and image-level.

Subject-level boxes are keyed by their name (str). Image-level boxes are keyed by a (image_name, boxes_name) tuple.

Returns:

Type Description
dict[str | tuple[str, str], BoundingBoxes]

Merged dict of all bounding boxes across both levels.

Source code in src/torchio/data/subject.py
def all_bounding_boxes(
    self,
) -> dict[str | tuple[str, str], BoundingBoxes]:
    """Collect bounding boxes from both subject-level and image-level.

    Subject-level boxes are keyed by their name (`str`).
    Image-level boxes are keyed by a `(image_name, boxes_name)`
    tuple.

    Returns:
        Merged dict of all bounding boxes across both levels.
    """
    result: dict[str | tuple[str, str], BoundingBoxes] = {}
    result.update(self._bounding_boxes)
    for image_name, image in self._images.items():
        for box_name, boxes in image.bounding_boxes.items():
            result[(image_name, box_name)] = boxes
    return result

load()

Load all images from disk.

Source code in src/torchio/data/subject.py
def load(self) -> None:
    """Load all images from disk."""
    for image in self._images.values():
        image.load()

to(*args, **kwargs)

Move all data to a device and/or cast to a dtype.

Calls .to() on every Image, Points, and BoundingBoxes.

Returns:

Type Description
Self

self (modified in-place).

Source code in src/torchio/data/subject.py
def to(self, *args: Any, **kwargs: Any) -> Self:
    """Move all data to a device and/or cast to a dtype.

    Calls `.to()` on every Image, Points, and BoundingBoxes.

    Returns:
        `self` (modified in-place).
    """
    for image in self._images.values():
        image.to(*args, **kwargs)
    for pts in self._points.values():
        pts.to(*args, **kwargs)
    for boxes in self._bounding_boxes.values():
        boxes.to(*args, **kwargs)
    return self

plot(**kwargs)

Plot all images as a grid of orthogonal slices.

Requires the [plot] extras (pip install torchio[plot]). See plot_subject for the full list of keyword arguments.

Source code in src/torchio/data/subject.py
def plot(self, **kwargs: Any) -> Any:
    """Plot all images as a grid of orthogonal slices.

    Requires the `[plot]` extras (`pip install torchio[plot]`).
    See [`plot_subject`][torchio.visualization.plot_subject] for the
    full list of keyword arguments.
    """
    from ..visualization import plot_subject

    return plot_subject(self, **kwargs)

AorticValve

Bases: SubjectITKSNAP

Cardiac aortic valve CT frames with segmentation.

Source code in src/torchio/datasets/itk_snap/itk_snap.py
class AorticValve(SubjectITKSNAP):
    """Cardiac aortic valve CT frames with segmentation."""

    def __init__(self) -> None:
        super().__init__("bav_example", "11021")

    def _get_kwargs(self) -> dict:
        b14, b14_seg, b25, b25_seg = (
            self.download_root / self.name / f"bav_frame_{name}.nii.gz"
            for name in ("14", "14_manseg", "25", "25_manseg")
        )
        return {
            "b14": ScalarImage(b14),
            "b14_seg": LabelMap(b14_seg),
            "b25": ScalarImage(b25),
            "b25_seg": LabelMap(b25_seg),
        }

metadata property

Non-spatial metadata.

spatial_shape property

Spatial shape, checked for consistency across all images.

shape property

Shape of the first image, checked for consistency.

spacing property

Spacing from the first image, checked for consistency.

device property

Device of the data, checked for consistency across all entries.

images property

Dict of all Image entries.

points property

Dict of all Points entries.

bounding_boxes property

Dict of all BoundingBoxes entries.

get_inverse_transform(*, warn=True, ignore_intensity=False)

Get a composed transform that inverts the applied history.

Returns a Compose of the inverse of each applied transform, in reverse order. Non-invertible transforms are skipped (with a warning if warn=True).

Parameters:

Name Type Description Default
warn bool

Issue a warning for non-invertible transforms.

True
ignore_intensity bool

Skip all intensity transforms.

False

Returns:

Type Description
Any

A Compose transform that undoes the history.

Source code in src/torchio/data/invertible.py
def get_inverse_transform(
    self,
    *,
    warn: bool = True,
    ignore_intensity: bool = False,
) -> Any:
    """Get a composed transform that inverts the applied history.

    Returns a [`Compose`][torchio.Compose] of the inverse of each
    applied transform, in reverse order. Non-invertible transforms
    are skipped (with a warning if `warn=True`).

    Args:
        warn: Issue a warning for non-invertible transforms.
        ignore_intensity: Skip all intensity transforms.

    Returns:
        A `Compose` transform that undoes the history.
    """
    from ..transforms.inverse import get_inverse_transform

    return get_inverse_transform(
        self.applied_transforms,
        warn=warn,
        ignore_intensity=ignore_intensity,
    )

apply_inverse_transform(**kwargs)

Apply the inverse of all applied transforms, in reverse order.

Non-invertible transforms are skipped. Intensity transforms can be ignored with ignore_intensity=True.

Parameters:

Name Type Description Default
**kwargs Any

Forwarded to get_inverse_transform() (warn, ignore_intensity).

{}

Returns:

Type Description
Self

Data with transforms undone.

Examples:

>>> transformed = transform(subject)
>>> restored = transformed.apply_inverse_transform()
Source code in src/torchio/data/invertible.py
def apply_inverse_transform(self, **kwargs: Any) -> Self:
    """Apply the inverse of all applied transforms, in reverse order.

    Non-invertible transforms are skipped. Intensity transforms
    can be ignored with `ignore_intensity=True`.

    Args:
        **kwargs: Forwarded to
            `get_inverse_transform()` (`warn`,
            `ignore_intensity`).

    Returns:
        Data with transforms undone.

    Examples:
        >>> transformed = transform(subject)
        >>> restored = transformed.apply_inverse_transform()
    """
    inverse_transform = self.get_inverse_transform(**kwargs)
    result = inverse_transform(self)
    if hasattr(result, "applied_transforms"):
        result.applied_transforms = []
    return result

clear_history()

Remove all applied transform records.

Source code in src/torchio/data/invertible.py
def clear_history(self) -> None:
    """Remove all applied transform records."""
    self.applied_transforms = []

all_points()

Collect points from both subject-level and image-level.

Subject-level points are keyed by their name (str). Image-level points are keyed by a (image_name, points_name) tuple.

Returns:

Type Description
dict[str | tuple[str, str], Points]

Merged dict of all points across both levels.

Source code in src/torchio/data/subject.py
def all_points(self) -> dict[str | tuple[str, str], Points]:
    """Collect points from both subject-level and image-level.

    Subject-level points are keyed by their name (`str`).
    Image-level points are keyed by a `(image_name, points_name)`
    tuple.

    Returns:
        Merged dict of all points across both levels.
    """
    result: dict[str | tuple[str, str], Points] = {}
    result.update(self._points)
    for image_name, image in self._images.items():
        for points_name, pts in image.points.items():
            result[(image_name, points_name)] = pts
    return result

all_bounding_boxes()

Collect bounding boxes from both subject-level and image-level.

Subject-level boxes are keyed by their name (str). Image-level boxes are keyed by a (image_name, boxes_name) tuple.

Returns:

Type Description
dict[str | tuple[str, str], BoundingBoxes]

Merged dict of all bounding boxes across both levels.

Source code in src/torchio/data/subject.py
def all_bounding_boxes(
    self,
) -> dict[str | tuple[str, str], BoundingBoxes]:
    """Collect bounding boxes from both subject-level and image-level.

    Subject-level boxes are keyed by their name (`str`).
    Image-level boxes are keyed by a `(image_name, boxes_name)`
    tuple.

    Returns:
        Merged dict of all bounding boxes across both levels.
    """
    result: dict[str | tuple[str, str], BoundingBoxes] = {}
    result.update(self._bounding_boxes)
    for image_name, image in self._images.items():
        for box_name, boxes in image.bounding_boxes.items():
            result[(image_name, box_name)] = boxes
    return result

load()

Load all images from disk.

Source code in src/torchio/data/subject.py
def load(self) -> None:
    """Load all images from disk."""
    for image in self._images.values():
        image.load()

to(*args, **kwargs)

Move all data to a device and/or cast to a dtype.

Calls .to() on every Image, Points, and BoundingBoxes.

Returns:

Type Description
Self

self (modified in-place).

Source code in src/torchio/data/subject.py
def to(self, *args: Any, **kwargs: Any) -> Self:
    """Move all data to a device and/or cast to a dtype.

    Calls `.to()` on every Image, Points, and BoundingBoxes.

    Returns:
        `self` (modified in-place).
    """
    for image in self._images.values():
        image.to(*args, **kwargs)
    for pts in self._points.values():
        pts.to(*args, **kwargs)
    for boxes in self._bounding_boxes.values():
        boxes.to(*args, **kwargs)
    return self

plot(**kwargs)

Plot all images as a grid of orthogonal slices.

Requires the [plot] extras (pip install torchio[plot]). See plot_subject for the full list of keyword arguments.

Source code in src/torchio/data/subject.py
def plot(self, **kwargs: Any) -> Any:
    """Plot all images as a grid of orthogonal slices.

    Requires the `[plot]` extras (`pip install torchio[plot]`).
    See [`plot_subject`][torchio.visualization.plot_subject] for the
    full list of keyword arguments.
    """
    from ..visualization import plot_subject

    return plot_subject(self, **kwargs)

3D Slicer

Slicer

Bases: Subject

Sample data provided by 3D Slicer <https://www.slicer.org/>_.

See the Slicer wiki <https://www.slicer.org/wiki/SampleData>_ for more information.

For information about licensing and permissions, check the Sample Data module <https://github.com/Slicer/Slicer/blob/31c89f230919a953e56f6722718281ce6da49e06/Modules/Scripted/SampleData/SampleData.py#L75-L81>_.

Parameters:

Name Type Description Default
name str

One of the keys in torchio.datasets.slicer.URLS_DICT.

'MRHead'
Source code in src/torchio/datasets/slicer.py
class Slicer(Subject):
    """Sample data provided by `3D Slicer <https://www.slicer.org/>`_.

    See `the Slicer wiki <https://www.slicer.org/wiki/SampleData>`_
    for more information.

    For information about licensing and permissions, check the `Sample Data
    module <https://github.com/Slicer/Slicer/blob/31c89f230919a953e56f6722718281ce6da49e06/Modules/Scripted/SampleData/SampleData.py#L75-L81>`_.

    Args:
        name: One of the keys in
            `torchio.datasets.slicer.URLS_DICT`.
    """

    def __init__(self, name: str = "MRHead") -> None:
        try:
            filenames, url_files = URLS_DICT[name]
        except KeyError as e:
            message = f'Invalid name "{name}". Valid names are: {", ".join(URLS_DICT)}'
            raise ValueError(message) from e
        download_root = get_torchio_cache_dir() / "slicer"
        for filename, url_file in zip(filenames, url_files, strict=True):
            filename = filename.replace("-", "_")
            url = urllib.parse.urljoin(SLICER_URL, url_file)
            download_url(url, download_root, filename=filename)
        stem = filename.split(".")[0]
        super().__init__(**{stem: ScalarImage(download_root / filename)})

metadata property

Non-spatial metadata.

spatial_shape property

Spatial shape, checked for consistency across all images.

shape property

Shape of the first image, checked for consistency.

spacing property

Spacing from the first image, checked for consistency.

device property

Device of the data, checked for consistency across all entries.

images property

Dict of all Image entries.

points property

Dict of all Points entries.

bounding_boxes property

Dict of all BoundingBoxes entries.

get_inverse_transform(*, warn=True, ignore_intensity=False)

Get a composed transform that inverts the applied history.

Returns a Compose of the inverse of each applied transform, in reverse order. Non-invertible transforms are skipped (with a warning if warn=True).

Parameters:

Name Type Description Default
warn bool

Issue a warning for non-invertible transforms.

True
ignore_intensity bool

Skip all intensity transforms.

False

Returns:

Type Description
Any

A Compose transform that undoes the history.

Source code in src/torchio/data/invertible.py
def get_inverse_transform(
    self,
    *,
    warn: bool = True,
    ignore_intensity: bool = False,
) -> Any:
    """Get a composed transform that inverts the applied history.

    Returns a [`Compose`][torchio.Compose] of the inverse of each
    applied transform, in reverse order. Non-invertible transforms
    are skipped (with a warning if `warn=True`).

    Args:
        warn: Issue a warning for non-invertible transforms.
        ignore_intensity: Skip all intensity transforms.

    Returns:
        A `Compose` transform that undoes the history.
    """
    from ..transforms.inverse import get_inverse_transform

    return get_inverse_transform(
        self.applied_transforms,
        warn=warn,
        ignore_intensity=ignore_intensity,
    )

apply_inverse_transform(**kwargs)

Apply the inverse of all applied transforms, in reverse order.

Non-invertible transforms are skipped. Intensity transforms can be ignored with ignore_intensity=True.

Parameters:

Name Type Description Default
**kwargs Any

Forwarded to get_inverse_transform() (warn, ignore_intensity).

{}

Returns:

Type Description
Self

Data with transforms undone.

Examples:

>>> transformed = transform(subject)
>>> restored = transformed.apply_inverse_transform()
Source code in src/torchio/data/invertible.py
def apply_inverse_transform(self, **kwargs: Any) -> Self:
    """Apply the inverse of all applied transforms, in reverse order.

    Non-invertible transforms are skipped. Intensity transforms
    can be ignored with `ignore_intensity=True`.

    Args:
        **kwargs: Forwarded to
            `get_inverse_transform()` (`warn`,
            `ignore_intensity`).

    Returns:
        Data with transforms undone.

    Examples:
        >>> transformed = transform(subject)
        >>> restored = transformed.apply_inverse_transform()
    """
    inverse_transform = self.get_inverse_transform(**kwargs)
    result = inverse_transform(self)
    if hasattr(result, "applied_transforms"):
        result.applied_transforms = []
    return result

clear_history()

Remove all applied transform records.

Source code in src/torchio/data/invertible.py
def clear_history(self) -> None:
    """Remove all applied transform records."""
    self.applied_transforms = []

all_points()

Collect points from both subject-level and image-level.

Subject-level points are keyed by their name (str). Image-level points are keyed by a (image_name, points_name) tuple.

Returns:

Type Description
dict[str | tuple[str, str], Points]

Merged dict of all points across both levels.

Source code in src/torchio/data/subject.py
def all_points(self) -> dict[str | tuple[str, str], Points]:
    """Collect points from both subject-level and image-level.

    Subject-level points are keyed by their name (`str`).
    Image-level points are keyed by a `(image_name, points_name)`
    tuple.

    Returns:
        Merged dict of all points across both levels.
    """
    result: dict[str | tuple[str, str], Points] = {}
    result.update(self._points)
    for image_name, image in self._images.items():
        for points_name, pts in image.points.items():
            result[(image_name, points_name)] = pts
    return result

all_bounding_boxes()

Collect bounding boxes from both subject-level and image-level.

Subject-level boxes are keyed by their name (str). Image-level boxes are keyed by a (image_name, boxes_name) tuple.

Returns:

Type Description
dict[str | tuple[str, str], BoundingBoxes]

Merged dict of all bounding boxes across both levels.

Source code in src/torchio/data/subject.py
def all_bounding_boxes(
    self,
) -> dict[str | tuple[str, str], BoundingBoxes]:
    """Collect bounding boxes from both subject-level and image-level.

    Subject-level boxes are keyed by their name (`str`).
    Image-level boxes are keyed by a `(image_name, boxes_name)`
    tuple.

    Returns:
        Merged dict of all bounding boxes across both levels.
    """
    result: dict[str | tuple[str, str], BoundingBoxes] = {}
    result.update(self._bounding_boxes)
    for image_name, image in self._images.items():
        for box_name, boxes in image.bounding_boxes.items():
            result[(image_name, box_name)] = boxes
    return result

load()

Load all images from disk.

Source code in src/torchio/data/subject.py
def load(self) -> None:
    """Load all images from disk."""
    for image in self._images.values():
        image.load()

to(*args, **kwargs)

Move all data to a device and/or cast to a dtype.

Calls .to() on every Image, Points, and BoundingBoxes.

Returns:

Type Description
Self

self (modified in-place).

Source code in src/torchio/data/subject.py
def to(self, *args: Any, **kwargs: Any) -> Self:
    """Move all data to a device and/or cast to a dtype.

    Calls `.to()` on every Image, Points, and BoundingBoxes.

    Returns:
        `self` (modified in-place).
    """
    for image in self._images.values():
        image.to(*args, **kwargs)
    for pts in self._points.values():
        pts.to(*args, **kwargs)
    for boxes in self._bounding_boxes.values():
        boxes.to(*args, **kwargs)
    return self

plot(**kwargs)

Plot all images as a grid of orthogonal slices.

Requires the [plot] extras (pip install torchio[plot]). See plot_subject for the full list of keyword arguments.

Source code in src/torchio/data/subject.py
def plot(self, **kwargs: Any) -> Any:
    """Plot all images as a grid of orthogonal slices.

    Requires the `[plot]` extras (`pip install torchio[plot]`).
    See [`plot_subject`][torchio.visualization.plot_subject] for the
    full list of keyword arguments.
    """
    from ..visualization import plot_subject

    return plot_subject(self, **kwargs)

FPG

FPG

Bases: Subject

3T :math:T_1-weighted brain MRI and corresponding parcellation.

Parameters:

Name Type Description Default
load_all bool

If True, three more images will be loaded: a :math:T_2-weighted MRI, a diffusion MRI and a functional MRI.

False
Source code in src/torchio/datasets/fpg.py
class FPG(Subject):
    r"""3T :math:`T_1`-weighted brain MRI and corresponding parcellation.

    Args:
        load_all: If `True`, three more images will be loaded: a
            :math:`T_2`-weighted MRI, a diffusion MRI and a functional MRI.
    """

    def __init__(self, load_all: bool = False) -> None:
        repo_dir = urllib.parse.urljoin(DATA_REPO, "fernando/")

        filenames: dict[str, str] = {
            "t1": "t1.nii.gz",
            "seg": "t1_seg_gif.nii.gz",
            "rigid": "t1_to_mni.tfm",
            "affine": "t1_to_mni_affine.h5",
        }
        if load_all:
            filenames["t2"] = "t2.nii.gz"
            filenames["fmri"] = "fmri.nrrd"
            filenames["dmri"] = "dmri.nrrd"

        download_root = get_torchio_cache_dir() / "fpg"

        for filename in filenames.values():
            download_url(
                urllib.parse.urljoin(repo_dir, filename),
                download_root,
                filename=filename,
            )

        rigid = read_matrix(download_root / filenames["rigid"])
        affine_matrix = read_matrix(download_root / filenames["affine"])

        subject_dict: dict[str, ScalarImage | LabelMap] = {
            "t1": ScalarImage(
                download_root / filenames["t1"],
                rigid_matrix=rigid,
                affine_matrix=affine_matrix,
            ),
            "seg": LabelMap(
                download_root / filenames["seg"],
                rigid_matrix=rigid,
                affine_matrix=affine_matrix,
                color_map=FPG.GIF_COLORS,
            ),
        }
        if load_all:
            subject_dict["t2"] = ScalarImage(download_root / filenames["t2"])
            subject_dict["fmri"] = ScalarImage(
                download_root / filenames["fmri"],
            )
            subject_dict["dmri"] = ScalarImage(
                download_root / filenames["dmri"],
            )
        super().__init__(**subject_dict)

    def plot(self, **kwargs: Any) -> Any:
        """Plot with GIF parcellation colors for the seg image."""
        kwargs.setdefault("cmap_dict", {"seg": self.GIF_COLORS})
        return super().plot(**kwargs)

    GIF_COLORS: ClassVar[dict[int, tuple[int, int, int]]] = {
        0: (0, 0, 0),
        1: (0, 0, 0),
        5: (127, 255, 212),
        12: (240, 230, 140),
        16: (176, 48, 96),
        24: (48, 176, 96),
        31: (48, 176, 96),
        32: (103, 255, 255),
        33: (103, 255, 255),
        35: (238, 186, 243),
        36: (119, 159, 176),
        37: (122, 186, 220),
        38: (122, 186, 220),
        39: (96, 204, 96),
        40: (96, 204, 96),
        41: (220, 247, 164),
        42: (220, 247, 164),
        43: (205, 62, 78),
        44: (205, 62, 78),
        45: (225, 225, 225),
        46: (225, 225, 225),
        47: (60, 60, 60),
        48: (220, 216, 20),
        49: (220, 216, 20),
        50: (196, 58, 250),
        51: (196, 58, 250),
        52: (120, 18, 134),
        53: (120, 18, 134),
        54: (255, 165, 0),
        55: (255, 165, 0),
        56: (12, 48, 255),
        57: (12, 48, 225),
        58: (236, 13, 176),
        59: (236, 13, 176),
        60: (0, 118, 14),
        61: (0, 118, 14),
        62: (165, 42, 42),
        63: (165, 42, 42),
        64: (160, 32, 240),
        65: (160, 32, 240),
        66: (56, 192, 255),
        67: (56, 192, 255),
        70: (255, 225, 225),
        72: (184, 237, 194),
        73: (180, 231, 250),
        74: (225, 183, 231),
        76: (180, 180, 180),
        77: (180, 180, 180),
        81: (245, 255, 200),
        82: (255, 230, 255),
        83: (245, 245, 245),
        84: (220, 255, 220),
        85: (220, 220, 220),
        86: (200, 255, 255),
        87: (250, 220, 200),
        89: (245, 255, 200),
        90: (255, 230, 255),
        91: (245, 245, 245),
        92: (220, 255, 220),
        93: (220, 220, 220),
        94: (200, 255, 255),
        96: (140, 125, 255),
        97: (140, 125, 255),
        101: (255, 62, 150),
        102: (255, 62, 150),
        103: (160, 82, 45),
        104: (160, 82, 45),
        105: (165, 42, 42),
        106: (165, 42, 42),
        107: (205, 91, 69),
        108: (205, 91, 69),
        109: (100, 149, 237),
        110: (100, 149, 237),
        113: (135, 206, 235),
        114: (135, 206, 235),
        115: (250, 128, 114),
        116: (250, 128, 114),
        117: (255, 255, 0),
        118: (255, 255, 0),
        119: (221, 160, 221),
        120: (221, 160, 221),
        121: (0, 238, 0),
        122: (0, 238, 0),
        123: (205, 92, 92),
        124: (205, 92, 92),
        125: (176, 48, 96),
        126: (176, 48, 96),
        129: (152, 251, 152),
        130: (152, 251, 152),
        133: (50, 205, 50),
        134: (50, 205, 50),
        135: (0, 100, 0),
        136: (0, 100, 0),
        137: (173, 216, 230),
        138: (173, 216, 230),
        139: (153, 50, 204),
        140: (153, 50, 204),
        141: (160, 32, 240),
        142: (160, 32, 240),
        143: (0, 206, 208),
        144: (0, 206, 208),
        145: (51, 50, 135),
        146: (51, 50, 135),
        147: (135, 50, 74),
        148: (135, 50, 74),
        149: (218, 112, 214),
        150: (218, 112, 214),
        151: (240, 230, 140),
        152: (240, 230, 140),
        153: (255, 255, 0),
        154: (255, 255, 0),
        155: (255, 110, 180),
        156: (255, 110, 180),
        157: (0, 255, 255),
        158: (0, 255, 255),
        161: (100, 50, 100),
        162: (100, 50, 100),
        163: (178, 34, 34),
        164: (178, 34, 34),
        165: (255, 0, 255),
        166: (255, 0, 255),
        167: (39, 64, 139),
        168: (39, 64, 139),
        169: (255, 99, 71),
        170: (255, 99, 71),
        171: (255, 69, 0),
        172: (255, 69, 0),
        173: (210, 180, 140),
        174: (210, 180, 140),
        175: (0, 255, 127),
        176: (0, 255, 127),
        177: (74, 155, 60),
        178: (74, 155, 60),
        179: (255, 215, 0),
        180: (255, 215, 0),
        181: (238, 0, 0),
        182: (238, 0, 0),
        183: (46, 139, 87),
        184: (46, 139, 87),
        185: (238, 201, 0),
        186: (238, 201, 0),
        187: (102, 205, 170),
        188: (102, 205, 170),
        191: (255, 218, 185),
        192: (255, 218, 185),
        193: (238, 130, 238),
        194: (238, 130, 238),
        195: (255, 165, 0),
        196: (255, 165, 0),
        197: (255, 192, 203),
        198: (255, 192, 203),
        199: (244, 222, 179),
        200: (244, 222, 179),
        201: (208, 32, 144),
        202: (208, 32, 144),
        203: (34, 139, 34),
        204: (34, 139, 34),
        205: (125, 255, 212),
        206: (127, 255, 212),
        207: (0, 0, 128),
        208: (0, 0, 128),
    }

metadata property

Non-spatial metadata.

spatial_shape property

Spatial shape, checked for consistency across all images.

shape property

Shape of the first image, checked for consistency.

spacing property

Spacing from the first image, checked for consistency.

device property

Device of the data, checked for consistency across all entries.

images property

Dict of all Image entries.

points property

Dict of all Points entries.

bounding_boxes property

Dict of all BoundingBoxes entries.

get_inverse_transform(*, warn=True, ignore_intensity=False)

Get a composed transform that inverts the applied history.

Returns a Compose of the inverse of each applied transform, in reverse order. Non-invertible transforms are skipped (with a warning if warn=True).

Parameters:

Name Type Description Default
warn bool

Issue a warning for non-invertible transforms.

True
ignore_intensity bool

Skip all intensity transforms.

False

Returns:

Type Description
Any

A Compose transform that undoes the history.

Source code in src/torchio/data/invertible.py
def get_inverse_transform(
    self,
    *,
    warn: bool = True,
    ignore_intensity: bool = False,
) -> Any:
    """Get a composed transform that inverts the applied history.

    Returns a [`Compose`][torchio.Compose] of the inverse of each
    applied transform, in reverse order. Non-invertible transforms
    are skipped (with a warning if `warn=True`).

    Args:
        warn: Issue a warning for non-invertible transforms.
        ignore_intensity: Skip all intensity transforms.

    Returns:
        A `Compose` transform that undoes the history.
    """
    from ..transforms.inverse import get_inverse_transform

    return get_inverse_transform(
        self.applied_transforms,
        warn=warn,
        ignore_intensity=ignore_intensity,
    )

apply_inverse_transform(**kwargs)

Apply the inverse of all applied transforms, in reverse order.

Non-invertible transforms are skipped. Intensity transforms can be ignored with ignore_intensity=True.

Parameters:

Name Type Description Default
**kwargs Any

Forwarded to get_inverse_transform() (warn, ignore_intensity).

{}

Returns:

Type Description
Self

Data with transforms undone.

Examples:

>>> transformed = transform(subject)
>>> restored = transformed.apply_inverse_transform()
Source code in src/torchio/data/invertible.py
def apply_inverse_transform(self, **kwargs: Any) -> Self:
    """Apply the inverse of all applied transforms, in reverse order.

    Non-invertible transforms are skipped. Intensity transforms
    can be ignored with `ignore_intensity=True`.

    Args:
        **kwargs: Forwarded to
            `get_inverse_transform()` (`warn`,
            `ignore_intensity`).

    Returns:
        Data with transforms undone.

    Examples:
        >>> transformed = transform(subject)
        >>> restored = transformed.apply_inverse_transform()
    """
    inverse_transform = self.get_inverse_transform(**kwargs)
    result = inverse_transform(self)
    if hasattr(result, "applied_transforms"):
        result.applied_transforms = []
    return result

clear_history()

Remove all applied transform records.

Source code in src/torchio/data/invertible.py
def clear_history(self) -> None:
    """Remove all applied transform records."""
    self.applied_transforms = []

all_points()

Collect points from both subject-level and image-level.

Subject-level points are keyed by their name (str). Image-level points are keyed by a (image_name, points_name) tuple.

Returns:

Type Description
dict[str | tuple[str, str], Points]

Merged dict of all points across both levels.

Source code in src/torchio/data/subject.py
def all_points(self) -> dict[str | tuple[str, str], Points]:
    """Collect points from both subject-level and image-level.

    Subject-level points are keyed by their name (`str`).
    Image-level points are keyed by a `(image_name, points_name)`
    tuple.

    Returns:
        Merged dict of all points across both levels.
    """
    result: dict[str | tuple[str, str], Points] = {}
    result.update(self._points)
    for image_name, image in self._images.items():
        for points_name, pts in image.points.items():
            result[(image_name, points_name)] = pts
    return result

all_bounding_boxes()

Collect bounding boxes from both subject-level and image-level.

Subject-level boxes are keyed by their name (str). Image-level boxes are keyed by a (image_name, boxes_name) tuple.

Returns:

Type Description
dict[str | tuple[str, str], BoundingBoxes]

Merged dict of all bounding boxes across both levels.

Source code in src/torchio/data/subject.py
def all_bounding_boxes(
    self,
) -> dict[str | tuple[str, str], BoundingBoxes]:
    """Collect bounding boxes from both subject-level and image-level.

    Subject-level boxes are keyed by their name (`str`).
    Image-level boxes are keyed by a `(image_name, boxes_name)`
    tuple.

    Returns:
        Merged dict of all bounding boxes across both levels.
    """
    result: dict[str | tuple[str, str], BoundingBoxes] = {}
    result.update(self._bounding_boxes)
    for image_name, image in self._images.items():
        for box_name, boxes in image.bounding_boxes.items():
            result[(image_name, box_name)] = boxes
    return result

load()

Load all images from disk.

Source code in src/torchio/data/subject.py
def load(self) -> None:
    """Load all images from disk."""
    for image in self._images.values():
        image.load()

to(*args, **kwargs)

Move all data to a device and/or cast to a dtype.

Calls .to() on every Image, Points, and BoundingBoxes.

Returns:

Type Description
Self

self (modified in-place).

Source code in src/torchio/data/subject.py
def to(self, *args: Any, **kwargs: Any) -> Self:
    """Move all data to a device and/or cast to a dtype.

    Calls `.to()` on every Image, Points, and BoundingBoxes.

    Returns:
        `self` (modified in-place).
    """
    for image in self._images.values():
        image.to(*args, **kwargs)
    for pts in self._points.values():
        pts.to(*args, **kwargs)
    for boxes in self._bounding_boxes.values():
        boxes.to(*args, **kwargs)
    return self

plot(**kwargs)

Plot with GIF parcellation colors for the seg image.

Source code in src/torchio/datasets/fpg.py
def plot(self, **kwargs: Any) -> Any:
    """Plot with GIF parcellation colors for the seg image."""
    kwargs.setdefault("cmap_dict", {"seg": self.GIF_COLORS})
    return super().plot(**kwargs)

MedMNIST

3D datasets from MedMNIST v2. Each function returns a list of subjects for the requested split.

organ_mnist_3d(split='train')

3D organ segmentation dataset.

Parameters:

Name Type Description Default
split str

'train', 'val', or 'test'.

'train'
Source code in src/torchio/datasets/medmnist.py
def organ_mnist_3d(split: str = "train") -> list[Subject]:
    """3D organ segmentation dataset.

    Args:
        split: `'train'`, `'val'`, or `'test'`.
    """
    return _load_medmnist("organmnist3d", split)

nodule_mnist_3d(split='train')

3D lung nodule dataset.

Parameters:

Name Type Description Default
split str

'train', 'val', or 'test'.

'train'
Source code in src/torchio/datasets/medmnist.py
def nodule_mnist_3d(split: str = "train") -> list[Subject]:
    """3D lung nodule dataset.

    Args:
        split: `'train'`, `'val'`, or `'test'`.
    """
    return _load_medmnist("nodulemnist3d", split)

adrenal_mnist_3d(split='train')

3D adrenal gland dataset.

Parameters:

Name Type Description Default
split str

'train', 'val', or 'test'.

'train'
Source code in src/torchio/datasets/medmnist.py
def adrenal_mnist_3d(split: str = "train") -> list[Subject]:
    """3D adrenal gland dataset.

    Args:
        split: `'train'`, `'val'`, or `'test'`.
    """
    return _load_medmnist("adrenalmnist3d", split)

fracture_mnist_3d(split='train')

3D bone fracture dataset.

Parameters:

Name Type Description Default
split str

'train', 'val', or 'test'.

'train'
Source code in src/torchio/datasets/medmnist.py
def fracture_mnist_3d(split: str = "train") -> list[Subject]:
    """3D bone fracture dataset.

    Args:
        split: `'train'`, `'val'`, or `'test'`.
    """
    return _load_medmnist("fracturemnist3d", split)

vessel_mnist_3d(split='train')

3D vessel dataset.

Parameters:

Name Type Description Default
split str

'train', 'val', or 'test'.

'train'
Source code in src/torchio/datasets/medmnist.py
def vessel_mnist_3d(split: str = "train") -> list[Subject]:
    """3D vessel dataset.

    Args:
        split: `'train'`, `'val'`, or `'test'`.
    """
    return _load_medmnist("vesselmnist3d", split)

synapse_mnist_3d(split='train')

3D synapse dataset.

Parameters:

Name Type Description Default
split str

'train', 'val', or 'test'.

'train'
Source code in src/torchio/datasets/medmnist.py
def synapse_mnist_3d(split: str = "train") -> list[Subject]:
    """3D synapse dataset.

    Args:
        split: `'train'`, `'val'`, or `'test'`.
    """
    return _load_medmnist("synapsemnist3d", split)