Source code for lesion_metrics.volume

"""Calculate total lesion burden in a segmentation mask

calculation of lesion burden/volume given some
type of medical image in a designated volume unit

Author: Jacob Reinhold (jcreinhold@gmail.com)
Created on: 16 Aug 2021
"""

from __future__ import annotations

import enum
import functools
import operator

import lesion_metrics.typing as lmt


[docs]class UnitOfVolume(enum.Enum): microlitre = "micro" microliter = "micro" milliliter = "milli" millilitre = "milli" liter = "litre" litre = "litre"
[docs]class SegmentationVolume: def __init__( self, label: lmt.LabelWithSpacing, unit: UnitOfVolume = UnitOfVolume.microliter, ): self.label = label self.unit = unit
[docs] @classmethod def from_filename(cls, path: lmt.PathLike) -> SegmentationVolume: try: import medio.image as mioi except ImportError as imp_exn: msg = "Require pymedio with 'all' extras to use this method" raise RuntimeError(msg) from imp_exn label = mioi.Image.from_path(path) return cls(label)
[docs] def volume(self) -> float: vol_in_micro = self.volume_in_microliters() if self.unit == UnitOfVolume.microliter: return vol_in_micro elif self.unit == UnitOfVolume.milliliter: return vol_in_micro / 1e3 elif self.unit == UnitOfVolume.liter: return vol_in_micro / 1e6 else: raise ValueError(f"Invalid unit: {self.unit}")
[docs] def volume_in_microlitres(self) -> float: return self.volume_in_microliters()
[docs] def volume_in_microliters(self) -> float: # per_voxel_volume will be in microliters per_voxel_volume = functools.reduce(operator.mul, self.label.spacing, 1.0) n_positive_voxels = (self.label > 0.0).sum() volume_in_microliters: float = n_positive_voxels * per_voxel_volume return volume_in_microliters