Skip to content

oxytcmri.domain.entities.mri

This module contains all the classes related to MRI data.

Classes:

Name Description
DTIMetric

Different metrics derived from diffusion tensor imaging.

Atlas

An atlas is a set of labels that can be used to segment the brain.

RegionOfInterest

Represents a Region of Interest (ROI) in medical imaging.

VoxelData

Protocol defining the interface for voxel data access.

MRIExamId

Value Object representing an MRI examination identifier.

MRIData

Represents a 3D MRI data volume.

DTIMap

Represents a map of DTI metric (FA, MD, RA, RD).

Mask

Represents a binary mask for a specific region of interest.

AtlasSegmentation

Represents a segmentation of an atlas.

MRIExam

A complete MRI examination.

AbnormalValueType

Enum for the type of abnormal values.

DTIAbnormalValues

Class to store the abnormal values in DTI images.

AbnormalVoxelData

Implementation of VoxelData for abnormal DTI values.

Attributes:

Name Type Description
T

T = TypeVar('T') module-attribute

DTIMetric

Bases: Enum

Different metrics derived from diffusion tensor imaging.

Methods:

Name Description
from_acronym

Get a DTIMetric enum value from its acronym.

Attributes:

Name Type Description
MD
FA
AD
RD

MD = 'Mean Diffusivity' class-attribute instance-attribute

FA = 'Fractional Anisotropy' class-attribute instance-attribute

AD = 'Axial Diffusivity' class-attribute instance-attribute

RD = 'Radial Diffusivity' class-attribute instance-attribute

from_acronym(acronym) classmethod

Get a DTIMetric enum value from its acronym.

Parameters:

Name Type Description Default
acronym str

The acronym (e.g., 'MD', 'FA')

required

Returns:

Type Description
DTIMetric

The corresponding enum value

Raises:

Type Description
ValueError

If no enum value matches the given acronym

Source code in oxytcmri/domain/entities/mri.py
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
@classmethod
def from_acronym(cls, acronym: str):
    """
    Get a DTIMetric enum value from its acronym.

    Parameters
    ----------
    acronym : str
        The acronym (e.g., 'MD', 'FA')

    Returns
    -------
    DTIMetric
        The corresponding enum value

    Raises
    ------
    ValueError
        If no enum value matches the given acronym
    """
    for metric in cls:
        if metric.name == acronym:
            return metric
    raise ValueError(f"No DTIMetric found for acronym: {acronym}")

Atlas(id, labels, name=None) dataclass

An atlas is a set of labels that can be used to segment the brain.

Parameters:

Name Type Description Default
id int

Unique identifier for the atlas

required
labels List[int]

List of labels within the atlas

required
name str

Name of the atlas (e.g. "Atlas1", "Atlas2")

None

Attributes:

Name Type Description
id int
labels List[int]
name Optional[str]

id instance-attribute

labels instance-attribute

name = None class-attribute instance-attribute

RegionOfInterest(atlas, labels, name=None) dataclass

Represents a Region of Interest (ROI) in medical imaging.

Parameters:

Name Type Description Default
atlas Atlas

The atlas used to define the region

required
labels List[int]

The list of labels within the atlas defining the region

required
name Optional[str]

Optional name for the region of interest, defaults to None

None

Attributes:

Name Type Description
atlas Atlas
labels List[int]
name Optional[str]

atlas instance-attribute

labels instance-attribute

name = None class-attribute instance-attribute

VoxelData

Bases: ABC, Generic[T]

Protocol defining the interface for voxel data access.

Methods:

Name Description
get_value_at

Get the value of a voxel at a specific position.

set_value_at

Set the value of a voxel at a specific position.

get_dimensions

Get the dimensions of the voxel data.

get_voxel_volume_in_ml

Get the volume of a voxel in milliliters (mL).

filter_values

Create a boolean representation of voxel data based on a filtering condition.

filter_by_values

Create a boolean representation where voxels with values in the provided

isin

Check if values are in the provided collection.

Attributes:

Name Type Description
value_type type[T]

Returns the type parameter T of this VoxelData[T]

value_type abstractmethod property

Returns the type parameter T of this VoxelData[T]

get_value_at(x, y, z) abstractmethod

Get the value of a voxel at a specific position.

Parameters:

Name Type Description Default
x int

x-coordinate of the voxel

required
y int

y-coordinate of the voxel

required
z int

z-coordinate of the voxel

required

Returns:

Type Description
T

Value of the voxel

Source code in oxytcmri/domain/entities/mri.py
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
@abstractmethod
def get_value_at(self, x: int, y: int, z: int) -> T:
    """
    Get the value of a voxel at a specific position.

    Parameters
    ----------
    x : int
        x-coordinate of the voxel
    y : int
        y-coordinate of the voxel
    z : int
        z-coordinate of the voxel

    Returns
    -------
    T
        Value of the voxel
    """

set_value_at(x, y, z, value) abstractmethod

Set the value of a voxel at a specific position.

Parameters:

Name Type Description Default
x int

x-coordinate of the voxel

required
y int

y-coordinate of the voxel

required
z int

z-coordinate of the voxel

required
value T

Value to set for the voxel

required

Returns:

Type Description
None
Source code in oxytcmri/domain/entities/mri.py
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
@abstractmethod
def set_value_at(self, x: int, y: int, z: int, value: T) -> None:
    """
    Set the value of a voxel at a specific position.

    Parameters
    ----------
    x : int
        x-coordinate of the voxel
    y : int
        y-coordinate of the voxel
    z : int
        z-coordinate of the voxel
    value : T
        Value to set for the voxel

    Returns
    -------
    None
    """

get_dimensions() abstractmethod

Get the dimensions of the voxel data.

Returns:

Type Description
tuple[int, int, int]

Dimensions of the voxel data

Source code in oxytcmri/domain/entities/mri.py
170
171
172
173
174
175
176
177
178
179
@abstractmethod
def get_dimensions(self) -> tuple[int, int, int]:
    """
    Get the dimensions of the voxel data.

    Returns
    -------
    tuple[int, int, int]
        Dimensions of the voxel data
    """

get_voxel_volume_in_ml() abstractmethod

Get the volume of a voxel in milliliters (mL).

Returns:

Type Description
float

Volume of a voxel, in mL.

Source code in oxytcmri/domain/entities/mri.py
181
182
183
184
185
186
187
188
189
190
@abstractmethod
def get_voxel_volume_in_ml(self) -> float:
    """
    Get the volume of a voxel in milliliters (mL).

    Returns
    -------
    float
        Volume of a voxel, in mL.
    """

filter_values(condition) abstractmethod

Create a boolean representation of voxel data based on a filtering condition.

Parameters:

Name Type Description Default
condition Callable[[T], bool]

Function that takes a voxel value and returns True if the voxel should be included in the filter

required

Returns:

Type Description
VoxelData[bool]

A boolean representation where voxels are True if they match the condition

Source code in oxytcmri/domain/entities/mri.py
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
@abstractmethod
def filter_values(self, condition: Callable[[T], bool]) -> VoxelData[bool]:
    """
    Create a boolean representation of voxel data based on a filtering condition.

    Parameters
    ----------
    condition : Callable[[T], bool]
        Function that takes a voxel value and returns True if the voxel
        should be included in the filter

    Returns
    -------
    VoxelData[bool]
        A boolean representation where voxels are True if they match the condition
    """

filter_by_values(values_to_include)

Create a boolean representation where voxels with values in the provided collection are True.

Parameters:

Name Type Description Default
values_to_include Collection[T]

Collection of values to include in the filter

required

Returns:

Type Description
VoxelData[bool]

A boolean representation where voxels are True if their value is in values_to_include

Source code in oxytcmri/domain/entities/mri.py
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
def filter_by_values(self, values_to_include: Collection[T]) -> VoxelData[bool]:
    """
    Create a boolean representation where voxels with values in the provided
    collection are True.

    Parameters
    ----------
    values_to_include : Collection[T]
        Collection of values to include in the filter

    Returns
    -------
    VoxelData[bool]
        A boolean representation where voxels are True if their value
        is in values_to_include
    """
    return self.filter_values(lambda x: x in values_to_include)

isin(values) abstractmethod

Check if values are in the provided collection.

Parameters:

Name Type Description Default
values Collection[T]

Collection of values to check against

required

Returns:

Type Description
VoxelData[bool]

Boolean mask where True indicates values present in the collection

Source code in oxytcmri/domain/entities/mri.py
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
@abstractmethod
def isin(self, values: Collection[T]) -> VoxelData[bool]:
    """
    Check if values are in the provided collection.

    Parameters
    ----------
    values : Collection[T]
        Collection of values to check against

    Returns
    -------
    VoxelData[bool]
        Boolean mask where True indicates values present in the collection
    """

MRIExamId(id) dataclass

Value Object representing an MRI examination identifier.

The ID can have different formats in the database: - "06-08P-MR-170918" - "10_03V_MR301015" - "13-03P-190717"

Methods:

Name Description
to_subject_id

Convert the MRIExamId to a subject ID.

Attributes:

Name Type Description
id str

id instance-attribute

to_subject_id()

Convert the MRIExamId to a subject ID.

For example: - "06-08P-MR-170918" -> "06-08-P" - "10_03V_MR301015" -> "10-03-V" - "13-03P-190717" -> "13-03-P"

Returns:

Type Description
SubjectId

The subject ID derived from the MRIExamId

Source code in oxytcmri/domain/entities/mri.py
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
def to_subject_id(self) -> SubjectId:
    """
    Convert the MRIExamId to a subject ID.

    For example:
    - "06-08P-MR-170918" -> "06-08-P"
    - "10_03V_MR301015" -> "10-03-V"
    - "13-03P-190717" -> "13-03-P"

    Returns
    -------
    SubjectId
        The subject ID derived from the MRIExamId
    """
    cleaned = re.sub(r"[-_]", "", self.id.upper())

    if len(cleaned) < 5:
        raise ValueError(f"Invalid MRIExamId format (too short): {self.id}")

    center = cleaned[0:2]
    subject = cleaned[2:4]
    subject_type = cleaned[4]

    if not center.isdigit() or not subject.isdigit():
        raise ValueError(f"Invalid center or subject number in ID: {self.id}")
    if subject_type not in {"P", "V", "T"}:
        raise ValueError(f"Invalid subject type (expected P, V or T) in ID: {self.id}")

    return SubjectId(f"{center}-{subject}-{subject_type}")

MRIData(*, voxel_data, mri_exam_id, name=None) dataclass

Bases: Generic[T]

Represents a 3D MRI data volume.

This can be: - An anatomical sequence (T1, T2, FLAIR) - A DTI-derived map (MD, FA) - An atlas or segmentation mask

Attributes:

Name Type Description
voxel_data VoxelData[T]

Provider for voxel data

mri_exam_id MRIExamId

Unique identifier of the MRI exam which this data belongs to

name Optional[str]

Optional name of the MRI data

Methods:

Name Description
get_voxel_data

Get the voxel data of this MRI volume.

voxel_data instance-attribute

mri_exam_id instance-attribute

name = None class-attribute instance-attribute

get_voxel_data()

Get the voxel data of this MRI volume.

Returns:

Type Description
VoxelData[T]

Interface to access the underlying voxel data

Source code in oxytcmri/domain/entities/mri.py
393
394
395
396
397
398
399
400
401
402
def get_voxel_data(self) -> VoxelData[T]:
    """
    Get the voxel data of this MRI volume.

    Returns
    -------
    VoxelData[T]
        Interface to access the underlying voxel data
    """
    return self.voxel_data

DTIMap(*, voxel_data, mri_exam_id, name=None, dti_metric) dataclass

Bases: MRIData[float]

Represents a map of DTI metric (FA, MD, RA, RD).

Parameters:

Name Type Description Default
voxel_data VoxelData[float]

Provider for voxel data

required
mri_exam_id MRIExamId

Identifier of the MRI exam

required
dti_metric DTIMetric

The type of DTI metric (MD, FA, etc.)

required
name Optional[str]

Optional name of the DTI map, defaults to "{dti_metric}_map" if not provided

None

Methods:

Name Description
get_mask_of_values_above_threshold

Get all voxel values above a specified threshold.

get_mask_of_values_below_threshold

Get all voxel values below a specified threshold.

Attributes:

Name Type Description
dti_metric DTIMetric

dti_metric instance-attribute

get_mask_of_values_above_threshold(threshold)

Get all voxel values above a specified threshold.

Parameters:

Name Type Description Default
threshold float

The threshold value to filter the voxel data

required

Returns:

Type Description
Mask

A mask where voxels with values above the threshold are True

Source code in oxytcmri/domain/entities/mri.py
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
def get_mask_of_values_above_threshold(self, threshold: float) -> Mask:
    """
    Get all voxel values above a specified threshold.

    Parameters
    ----------
    threshold : float
        The threshold value to filter the voxel data

    Returns
    -------
    Mask
        A mask where voxels with values above the threshold are True
    """
    return Mask(mri_exam_id=self.mri_exam_id, voxel_data=self.get_voxel_data() > threshold)

get_mask_of_values_below_threshold(threshold)

Get all voxel values below a specified threshold.

Parameters:

Name Type Description Default
threshold float

The threshold value to filter the voxel data

required

Returns:

Type Description
Mask

A mask where voxels with values below the threshold are True

Source code in oxytcmri/domain/entities/mri.py
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
def get_mask_of_values_below_threshold(self, threshold: float) -> Mask:
    """
    Get all voxel values below a specified threshold.

    Parameters
    ----------
    threshold : float
        The threshold value to filter the voxel data

    Returns
    -------
    Mask
        A mask where voxels with values below the threshold are True
    """
    return Mask(mri_exam_id=self.mri_exam_id, voxel_data= self.get_voxel_data() < threshold)

Mask(*, voxel_data, mri_exam_id, name=None) dataclass

Bases: MRIData[bool]

Represents a binary mask for a specific region of interest.

Parameters:

Name Type Description Default
mri_exam_id MRIExamId

Unique identifier of the MRI exam which this data belongs to

required
voxel_data VoxelData[bool]

Provider for voxel data

required

Methods:

Name Description
extract_values_from

Extract values from an MRI data object where this mask is True.

get_true_voxel_coordinates

Get the coordinates of all voxels where this mask is True.

mask_with

Combine this mask with another mask using logical AND operation.

extract_values_from(mri_data)

Extract values from an MRI data object where this mask is True.

Parameters:

Name Type Description Default
mri_data MRIData[T]

The MRI data from which to extract values

required

Returns:

Type Description
List[T]

List of values from voxels where this mask is True

Source code in oxytcmri/domain/entities/mri.py
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
def extract_values_from(self, mri_data: MRIData[T]) -> List[T]:
    """
    Extract values from an MRI data object where this mask is True.

    Parameters
    ----------
    mri_data : MRIData[T]
        The MRI data from which to extract values

    Returns
    -------
    List[T]
        List of values from voxels where this mask is True
    """
    # Result list to store the extracted values
    values = []

    # Get the voxel data from the mask and the source MRI data
    mask_voxel_data = self.get_voxel_data()
    source_voxel_data = mri_data.get_voxel_data()

    # Check if the dimensions of the mask and source data match
    mask_dimensions = mask_voxel_data.get_dimensions()
    source_dimensions = source_voxel_data.get_dimensions()
    if mask_dimensions != source_dimensions:
        raise ValueError(
            f"Dimensions mismatch: mask {mask_dimensions} vs source {source_dimensions}"
        )

    # Iterate through the mask dimensions
    for x in range(mask_dimensions[0]):
        for y in range(mask_dimensions[1]):
            for z in range(mask_dimensions[2]):
                # If the mask is True, get the corresponding value from the source data
                if mask_voxel_data.get_value_at(x, y, z):
                    values.append(source_voxel_data.get_value_at(x, y, z))

    return values

get_true_voxel_coordinates()

Get the coordinates of all voxels where this mask is True.

This method iterates through all voxels in the mask and returns the coordinates (x, y, z) where the value is True.

Returns:

Type Description
List[Tuple[int, int, int]]

List of (x, y, z) coordinates where the mask has True values

Source code in oxytcmri/domain/entities/mri.py
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
def get_true_voxel_coordinates(self) -> List[Tuple[int, int, int]]:
    """
    Get the coordinates of all voxels where this mask is True.

    This method iterates through all voxels in the mask and returns
    the coordinates (x, y, z) where the value is True.

    Returns
    -------
    List[Tuple[int, int, int]]
        List of (x, y, z) coordinates where the mask has True values
    """
    # List to store coordinates
    coordinates = []

    # Get the mask's voxel data
    mask_voxel_data = self.get_voxel_data()

    # Get dimensions
    dimensions = mask_voxel_data.get_dimensions()

    # Iterate through all dimensions of the mask
    for x in range(dimensions[0]):
        for y in range(dimensions[1]):
            for z in range(dimensions[2]):
                # If the mask is True at this position, add the coordinates
                if mask_voxel_data.get_value_at(x, y, z):
                    coordinates.append((x, y, z))

    return coordinates

mask_with(other_mask)

Combine this mask with another mask using logical AND operation.

Parameters:

Name Type Description Default
other_mask Mask

The other mask to combine with

required

Returns:

Type Description
Mask

A new mask where both this mask and the other mask are True

Source code in oxytcmri/domain/entities/mri.py
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
def mask_with(self, other_mask: Mask) -> Mask:
    """
    Combine this mask with another mask using logical AND operation.

    Parameters
    ----------
    other_mask : Mask
        The other mask to combine with

    Returns
    -------
    Mask
        A new mask where both this mask and the other mask are True
    """
    if self.mri_exam_id != other_mask.mri_exam_id:
        raise ValueError("Masks belong to different MRI exams")

    return Mask(mri_exam_id=self.mri_exam_id,
                voxel_data=self.get_voxel_data() & other_mask.get_voxel_data())

AtlasSegmentation(voxel_data, mri_exam_id, atlas)

Bases: MRIData[int]

Represents a segmentation of an atlas.

Parameters:

Name Type Description Default
mri_exam_id MRIExamId

Unique identifier of the MRI exam which this data belongs to

required
voxel_data VoxelData[int]

Provider for voxel data

required
atlas Atlas

The atlas used for segmentation

required

Methods:

Name Description
create_mask

Create a mask for the specified labels.

Attributes:

Name Type Description
atlas
Source code in oxytcmri/domain/entities/mri.py
591
592
593
594
595
596
597
598
def __init__(self,
             voxel_data: VoxelData[int],
             mri_exam_id: MRIExamId,
             atlas: Atlas) -> None:
    super().__init__(voxel_data=voxel_data,
                     mri_exam_id=mri_exam_id,
                     name=f"{atlas.name}_segmentation")
    self.atlas = atlas

atlas = atlas instance-attribute

create_mask(labels)

Create a mask for the specified labels.

Parameters:

Name Type Description Default
labels List[int]

The labels to include in the mask

required

Returns:

Type Description
Mask

A mask representing the specified labels

Source code in oxytcmri/domain/entities/mri.py
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
def create_mask(self, labels: List[int]) -> Mask:
    """
    Create a mask for the specified labels.

    Parameters
    ----------
    labels : List[int]
        The labels to include in the mask

    Returns
    -------
    Mask
        A mask representing the specified labels
    """
    return Mask(mri_exam_id=self.mri_exam_id, voxel_data=self.get_voxel_data().isin(labels))

MRIExam(id, subject_id, data=list()) dataclass

A complete MRI examination.

Contains all the MRI data (sequences, maps, masks) associated with a subject's exam.

Parameters:

Name Type Description Default
id MRIExamId

Unique identifier of the exam

required
subject_id SubjectId

Identifier of the subject who underwent the exam

required
data List[MRIData]

List of all MRI data associated with this exam

list()

Methods:

Name Description
from_string_exam_id

Factory method that creates an MRIExam from a string exam id.

get_all_mri_data

Get all MRI data associated with this exam.

get_dti_map

Retrieve the DTI map for a specific metric.

get_segmented_dti_abnormal_values

Retrieve the segmented DTI abnormal values for a specific metric.

get_atlas_segmentation

Retrieve the segmentation for a specific atlas.

get_mask

Create a mask for a given region of interest.

extract_dti_values_for_region

Extract DTI metric values for a specific region of interest.

add_mri_data

Add MRI data to the MRI exam

Attributes:

Name Type Description
id MRIExamId
subject_id SubjectId
data List[MRIData]

id instance-attribute

subject_id instance-attribute

data = field(default_factory=list) class-attribute instance-attribute

from_string_exam_id(exam_id, data=None) classmethod

Factory method that creates an MRIExam from a string exam id.

Parameters:

Name Type Description Default
exam_id str

Unique identifier of the exam

required
data Optional[List[MRIData]]

List of all MRI data associated with this exam

None
Source code in oxytcmri/domain/entities/mri.py
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
@classmethod
def from_string_exam_id(cls, exam_id: str, data: Optional[List[MRIData]] = None) -> MRIExam:
    """
    Factory method that creates an MRIExam from a string exam id.

    Parameters
    ----------
    exam_id : str
        Unique identifier of the exam
    data : Optional[List[MRIData]]
        List of all MRI data associated with this exam
    """
    mri_exam_id = MRIExamId(exam_id)
    subject_id = mri_exam_id.to_subject_id()
    return cls(mri_exam_id, subject_id, data or [])

get_all_mri_data()

Get all MRI data associated with this exam.

Returns:

Type Description
Optional[MRIData]

The requested data if found, None otherwise

Source code in oxytcmri/domain/entities/mri.py
665
666
667
668
669
670
671
672
673
674
def get_all_mri_data(self) -> list[MRIData]:
    """
    Get all MRI data associated with this exam.

    Returns
    -------
    Optional[MRIData]
        The requested data if found, None otherwise
    """
    return self.data

get_dti_map(metric)

Retrieve the DTI map for a specific metric.

Parameters:

Name Type Description Default
metric DTIMetric

The type of DTI metric to retrieve

required

Returns:

Type Description
MRIData

The DTI map for the specified metric

Source code in oxytcmri/domain/entities/mri.py
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
def get_dti_map(self, metric: DTIMetric) -> DTIMap:
    """
    Retrieve the DTI map for a specific metric.

    Parameters
    ----------
    metric : DTIMetric
        The type of DTI metric to retrieve

    Returns
    -------
    MRIData
        The DTI map for the specified metric
    """
    for mri_data in self.data:
        if isinstance(mri_data, DTIMap) and mri_data.dti_metric == metric:
            return mri_data

    raise LookupError(f"DTI map not found for metric '{metric}' in MRI exam '{self.id}'")

get_segmented_dti_abnormal_values(dti_metric)

Retrieve the segmented DTI abnormal values for a specific metric.

Parameters:

Name Type Description Default
dti_metric DTIMetric

The type of DTI metric to retrieve abnormal values for

required

Returns:

Type Description
DTIAbnormalValues

The segmented DTI abnormal values for the specified metric

Source code in oxytcmri/domain/entities/mri.py
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
def get_segmented_dti_abnormal_values(self, dti_metric: DTIMetric) -> DTIAbnormalValues:
    """
    Retrieve the segmented DTI abnormal values for a specific metric.

    Parameters
    ----------
    dti_metric : DTIMetric
        The type of DTI metric to retrieve abnormal values for

    Returns
    -------
    DTIAbnormalValues
        The segmented DTI abnormal values for the specified metric
    """
    for mri_data in self.data:
        if isinstance(mri_data, DTIAbnormalValues) and mri_data.source_dti_map.dti_metric == dti_metric:
            return mri_data

    raise LookupError(f"Segmented DTI abnormal values not found for metric '{dti_metric}' in MRI exam '{self.id}'")

get_atlas_segmentation(atlas)

Retrieve the segmentation for a specific atlas.

Parameters:

Name Type Description Default
atlas Atlas
required

Returns:

Type Description
AtlasSegmentation

The atlas segmentation data

Source code in oxytcmri/domain/entities/mri.py
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
def get_atlas_segmentation(self, atlas: Atlas) -> AtlasSegmentation:
    """
    Retrieve the segmentation for a specific atlas.

    Parameters
    ----------
    atlas : Atlas

    Returns
    -------
    AtlasSegmentation
        The atlas segmentation data
    """
    # look for atlas by atlas id
    for mri_data in self.data:
        if isinstance(mri_data, AtlasSegmentation) and mri_data.atlas.id == atlas.id:
            return mri_data

    raise LookupError(f"Atlas segmentation not found for atlas '{atlas.id}' in MRI exam '{self.id}'")

get_mask(roi)

Create a mask for a given region of interest.

Parameters:

Name Type Description Default
roi RegionOfInterest

The region of interest to create a mask for

required

Returns:

Type Description
Mask

A mask representing the specified region of interest

Source code in oxytcmri/domain/entities/mri.py
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
def get_mask(self, roi: RegionOfInterest) -> Mask:
    """
    Create a mask for a given region of interest.

    Parameters
    ----------
    roi : RegionOfInterest
        The region of interest to create a mask for

    Returns
    -------
    Mask
        A mask representing the specified region of interest
    """
    # Get the atlas segmentation data for the ROI's atlas
    atlas_segmentation = self.get_atlas_segmentation(roi.atlas)
    if atlas_segmentation is None:
        raise LookupError(f"Atlas segmentation not found for atlas "
                          f"'{roi.atlas.id}' in MRI exam '{self.id}'")

    # Create a mask that includes all specified labels
    mask = atlas_segmentation.create_mask(roi.labels)

    return mask

extract_dti_values_for_region(dti_metric, roi)

Extract DTI metric values for a specific region of interest.

Parameters:

Name Type Description Default
dti_metric DTIMetric

The type of DTI metric to extract (MD, FA, etc.)

required
roi RegionOfInterest

The region of interest to extract values from

required

Returns:

Type Description
List[float]

DTI values corresponding to the specified ROI

Source code in oxytcmri/domain/entities/mri.py
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
def extract_dti_values_for_region(
        self, dti_metric: DTIMetric, roi: RegionOfInterest
) -> List[float]:
    """
    Extract DTI metric values for a specific region of interest.

    Parameters
    ----------
    dti_metric : DTIMetric
        The type of DTI metric to extract (MD, FA, etc.)
    roi : RegionOfInterest
        The region of interest to extract values from

    Returns
    -------
    List[float]
        DTI values corresponding to the specified ROI
    """
    # Get the DTI metric data for the specified metric
    dti_map = self.get_dti_map(dti_metric)

    # Create a mask for the ROI
    mask = self.get_mask(roi)

    # Extract values using the mask
    dti_values = mask.extract_values_from(dti_map)

    return dti_values

add_mri_data(mri_data)

Add MRI data to the MRI exam

Parameters:

Name Type Description Default
mri_data MRIData

The MRI data to add to the exam

required

Returns:

Type Description
None
Source code in oxytcmri/domain/entities/mri.py
790
791
792
793
794
795
796
797
798
799
800
801
802
803
def add_mri_data(self, mri_data: MRIData) -> None:
    """
    Add MRI data to the MRI exam

    Parameters
    ----------
    mri_data : MRIData
        The MRI data to add to the exam

    Returns
    -------
    None
    """
    self.data.append(mri_data)

AbnormalValueType

Bases: Enum

Enum for the type of abnormal values.

Methods:

Name Description
from_integer

Convert an integer value to AbnormalValueType.

to_integer

Convert AbnormalValueType to integer.

Attributes:

Name Type Description
HIGH
LOW

HIGH = 'high' class-attribute instance-attribute

LOW = 'low' class-attribute instance-attribute

from_integer(value) classmethod

Convert an integer value to AbnormalValueType.

Parameters:

Name Type Description Default
value int

Integer value to convert (0, 1, or 2)

required

Returns:

Type Description
Optional[AbnormalValueType]

Corresponding AbnormalValueType or None if value is 0

Raises:

Type Description
ValueError

If the value is not 0, 1, or 2

Source code in oxytcmri/domain/entities/mri.py
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
@classmethod
def from_integer(cls, value: int) -> Optional['AbnormalValueType']:
    """
    Convert an integer value to AbnormalValueType.

    Parameters
    ----------
    value : int
        Integer value to convert (0, 1, or 2)

    Returns
    -------
    Optional[AbnormalValueType]
        Corresponding AbnormalValueType or None if value is 0

    Raises
    ------
    ValueError
        If the value is not 0, 1, or 2
    """
    if value == 0:
        return None
    elif value == 1:
        return cls.HIGH
    elif value == 2:
        return cls.LOW
    else:
        raise ValueError(f"Invalid integer value for conversion to AbnormalValueType: {value}")

to_integer()

Convert AbnormalValueType to integer.

Returns:

Type Description
int

1 for LOW, 2 for HIGH

Source code in oxytcmri/domain/entities/mri.py
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
def to_integer(self) -> int:
    """
    Convert AbnormalValueType to integer.

    Returns
    -------
    int
        1 for LOW, 2 for HIGH
    """
    if self == self.HIGH:
        return 1
    elif self == self.LOW:
        return 2
    else:
        # This should never happen as we only have LOW and HIGH
        raise ValueError(f"Unknown AbnormalValueType: {self}")

DTIAbnormalValues(mri_exam_id, voxel_data, source_dti_map, name=None)

Bases: MRIData[AbnormalValueType]

Class to store the abnormal values in DTI images.

Methods:

Name Description
from_dti_map

Create a DTIAbnormalValues object from a DTIMap.

Attributes:

Name Type Description
mri_exam_id
voxel_data
source_dti_map
name
Source code in oxytcmri/domain/entities/mri.py
876
877
878
879
880
881
882
883
884
885
def __init__(self,
             mri_exam_id: MRIExamId,
             voxel_data: AbnormalVoxelData,
             source_dti_map: DTIMap,
             name: Optional[str] = None,
             ) -> None:
    self.mri_exam_id = mri_exam_id
    self.voxel_data = voxel_data
    self.source_dti_map = source_dti_map
    self.name = name or f"abnormal_values_{source_dti_map.name}"

mri_exam_id = mri_exam_id instance-attribute

voxel_data = voxel_data instance-attribute

source_dti_map = source_dti_map instance-attribute

name = name or f'abnormal_values_{source_dti_map.name}' instance-attribute

from_dti_map(dti_map, name=None) classmethod

Create a DTIAbnormalValues object from a DTIMap.

Source code in oxytcmri/domain/entities/mri.py
887
888
889
890
891
892
893
894
895
896
@classmethod
def from_dti_map(cls, dti_map: DTIMap, name: Optional[str] = None) -> DTIAbnormalValues:
    """
    Create a DTIAbnormalValues object from a DTIMap.
    """
    return cls(mri_exam_id=dti_map.mri_exam_id,
               voxel_data=AbnormalVoxelData.from_source_voxel_data(dti_map.voxel_data),
               source_dti_map=dti_map,
               name=name or f"abnormal_values_{dti_map.name}",
               )

AbnormalVoxelData(source_voxel_data)

Bases: VoxelData[AbnormalValueType]

Implementation of VoxelData for abnormal DTI values.

This class stores abnormal voxels in a dictionary, where only abnormal voxels are stored. Voxels not present in the dictionary are considered normal.

Attributes:

Name Type Description
source_voxel_data VoxelData[float]

The source voxel data from which the abnormal values are derived.

Initialize with dimensions from the source voxel data.

Parameters:

Name Type Description Default
source_voxel_data VoxelData[float]

The source voxel data from which the abnormal values are derived.

required

Methods:

Name Description
from_source_voxel_data

Create an AbnormalVoxelData object from source VoxelData.

get_source_voxel_data

Get the source voxel data.

get_abnormal_voxels_coordinates

Get the coordinates of all abnormal voxels with a specific type.

set_value_at

Set an abnormal value at the specified coordinates.

get_value_at

Get the abnormal value at the specified coordinates.

is_abnormal

Check if a voxel is marked as abnormal.

get_dimensions

Get the dimensions of the voxel data.

get_voxel_volume_in_ml

Get the volume of a voxel in milliliters.

mark_voxels_as

Mark all voxels in the mask as abnormal with the specified type.

filter_values

Raise NotImplementedError as this method is not used for abnormal voxel data.

isin

Raise NotImplementedError as this method is not used for the moment.

Source code in oxytcmri/domain/entities/mri.py
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
def __init__(self,
             source_voxel_data: VoxelData[float]
             ) -> None:
    """
    Initialize with dimensions from the source voxel data.

    Parameters
    ----------
    source_voxel_data : VoxelData[float]
        The source voxel data from which the abnormal values are derived.
    """
    self.source_voxel_data = source_voxel_data

    # Dictionary to store abnormal voxels
    # Key: tuple (x, y, z), Value: AbnormalValueType (HIGH or LOW)
    self.abnormal_voxels: dict[tuple[int, int, int], AbnormalValueType] = {}

source_voxel_data = source_voxel_data instance-attribute

abnormal_voxels = {} instance-attribute

value_type property

Get the type of values stored in this VoxelData.

Returns:

Type Description
type[T]

The type of values, which is AbnormalValueType

from_source_voxel_data(source_voxel_data) classmethod

Create an AbnormalVoxelData object from source VoxelData.

Parameters:

Name Type Description Default
source_voxel_data VoxelData[float]

The source voxel data from which the abnormal values are derived.

required

Returns:

Type Description
AbnormalVoxelData

The created AbnormalVoxelData object

Source code in oxytcmri/domain/entities/mri.py
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
@classmethod
def from_source_voxel_data(cls, source_voxel_data: VoxelData[float]) -> AbnormalVoxelData:
    """
    Create an AbnormalVoxelData object from source VoxelData.

    Parameters
    ----------
    source_voxel_data: VoxelData[float]
        The source voxel data from which the abnormal values are derived.

    Returns
    -------
    AbnormalVoxelData
        The created AbnormalVoxelData object
    """
    return cls(source_voxel_data=source_voxel_data)

get_source_voxel_data()

Get the source voxel data.

Returns:

Type Description
VoxelData[float]

The source voxel data

Source code in oxytcmri/domain/entities/mri.py
958
959
960
961
962
963
964
965
966
967
def get_source_voxel_data(self) -> VoxelData[float]:
    """
    Get the source voxel data.

    Returns
    -------
    VoxelData[float]
        The source voxel data
    """
    return self.source_voxel_data

get_abnormal_voxels_coordinates(abnormal_value_type)

Get the coordinates of all abnormal voxels with a specific type.

Parameters:

Name Type Description Default
abnormal_value_type AbnormalValueType

The type of abnormality (HIGH or LOW)

required

Returns:

Type Description
List[Tuple[int, int, int]]

List of coordinates (x, y, z) for the specified abnormal value type

Source code in oxytcmri/domain/entities/mri.py
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
def get_abnormal_voxels_coordinates(self, abnormal_value_type: AbnormalValueType) -> List[Tuple[int, int, int]]:
    """
    Get the coordinates of all abnormal voxels with a specific type.

    Parameters
    ----------
    abnormal_value_type : AbnormalValueType
        The type of abnormality (HIGH or LOW)

    Returns
    -------
    List[Tuple[int, int, int]]
        List of coordinates (x, y, z) for the specified abnormal value type
    """
    return [coords for coords, value in self.abnormal_voxels.items() if value == abnormal_value_type]

set_value_at(x, y, z, value)

Set an abnormal value at the specified coordinates.

Parameters:

Name Type Description Default
x int

X coordinate

required
y int

Y coordinate

required
z int

Z coordinate

required
value AbnormalValueType

The type of abnormality (HIGH or LOW)

required

Raises:

Type Description
ValueError

If coordinates are out of bounds

Source code in oxytcmri/domain/entities/mri.py
 985
 986
 987
 988
 989
 990
 991
 992
 993
 994
 995
 996
 997
 998
 999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
def set_value_at(self, x: int, y: int, z: int, value: AbnormalValueType) -> None:
    """
    Set an abnormal value at the specified coordinates.

    Parameters
    ----------
    x : int
        X coordinate
    y : int
        Y coordinate
    z : int
        Z coordinate
    value : AbnormalValueType
        The type of abnormality (HIGH or LOW)

    Raises
    ------
    ValueError
        If coordinates are out of bounds
    """
    if not self._is_in_bounds(x, y, z):
        raise ValueError(f"Coordinates ({x}, {y}, {z}) out of bounds. Dimensions: {self.get_dimensions()}")

    # Add to dictionary
    self.abnormal_voxels[(x, y, z)] = value

get_value_at(x, y, z)

Get the abnormal value at the specified coordinates.

Parameters:

Name Type Description Default
x int

X coordinate

required
y int

Y coordinate

required
z int

Z coordinate

required

Returns:

Type Description
AbnormalValueType

The abnormal value type (HIGH or LOW)

Raises:

Type Description
ValueError

If coordinates are out of bounds or if voxel is not abnormal

Source code in oxytcmri/domain/entities/mri.py
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
def get_value_at(self, x: int, y: int, z: int) -> Optional[AbnormalValueType]:
    """
    Get the abnormal value at the specified coordinates.

    Parameters
    ----------
    x : int
        X coordinate
    y : int
        Y coordinate
    z : int
        Z coordinate

    Returns
    -------
    AbnormalValueType
        The abnormal value type (HIGH or LOW)

    Raises
    ------
    ValueError
        If coordinates are out of bounds or if voxel is not abnormal
    """
    coords = (x, y, z)
    if not self._is_in_bounds(x, y, z):
        raise ValueError(f"Coordinates ({x}, {y}, {z}) out of bounds. Dimensions: {self.get_dimensions()}")

    if coords not in self.abnormal_voxels:
        return None

    return self.abnormal_voxels[coords]

is_abnormal(x, y, z)

Check if a voxel is marked as abnormal.

Parameters:

Name Type Description Default
x int

X coordinate

required
y int

Y coordinate

required
z int

Z coordinate

required

Returns:

Type Description
bool

True if voxel is abnormal, False otherwise

Source code in oxytcmri/domain/entities/mri.py
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
def is_abnormal(self, x: int, y: int, z: int) -> bool:
    """
    Check if a voxel is marked as abnormal.

    Parameters
    ----------
    x : int
        X coordinate
    y : int
        Y coordinate
    z : int
        Z coordinate

    Returns
    -------
    bool
        True if voxel is abnormal, False otherwise
    """
    return (x, y, z) in self.abnormal_voxels

get_dimensions()

Get the dimensions of the voxel data.

Returns:

Type Description
Tuple[int, int, int]

Dimensions as (x, y, z)

Source code in oxytcmri/domain/entities/mri.py
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
def get_dimensions(self) -> Tuple[int, int, int]:
    """
    Get the dimensions of the voxel data.

    Returns
    -------
    Tuple[int, int, int]
        Dimensions as (x, y, z)
    """
    return self.source_voxel_data.get_dimensions()

get_voxel_volume_in_ml()

Get the volume of a voxel in milliliters.

Returns:

Type Description
float

Volume in milliliters

Source code in oxytcmri/domain/entities/mri.py
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
def get_voxel_volume_in_ml(self) -> float:
    """
    Get the volume of a voxel in milliliters.

    Returns
    -------
    float
        Volume in milliliters
    """
    return self.source_voxel_data.get_voxel_volume_in_ml()

mark_voxels_as(mask, abnormal_value_type)

Mark all voxels in the mask as abnormal with the specified type.

Parameters:

Name Type Description Default
mask Mask

The mask containing the voxels to mark

required
abnormal_value_type AbnormalValueType

The type of abnormality to assign (HIGH or LOW)

required
Source code in oxytcmri/domain/entities/mri.py
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
def mark_voxels_as(self, mask: Mask, abnormal_value_type: AbnormalValueType) -> None:
    """
    Mark all voxels in the mask as abnormal with the specified type.

    Parameters
    ----------
    mask : Mask
        The mask containing the voxels to mark
    abnormal_value_type : AbnormalValueType
        The type of abnormality to assign (HIGH or LOW)
    """
    for x, y, z in mask.get_true_voxel_coordinates():
        self.set_value_at(x, y, z, abnormal_value_type)

filter_values(condition)

Raise NotImplementedError as this method is not used for abnormal voxel data.

Source code in oxytcmri/domain/entities/mri.py
1122
1123
1124
1125
1126
def filter_values(self, condition: Callable[[AbnormalValueType], bool]) -> VoxelData[bool]:
    """
    Raise NotImplementedError as this method is not used for abnormal voxel data.
    """
    raise NotImplementedError("AbnormalVoxelData.filter_values")

isin(values)

Raise NotImplementedError as this method is not used for the moment.

Source code in oxytcmri/domain/entities/mri.py
1152
1153
1154
1155
1156
def isin(self, values: Collection[T]) -> VoxelData[bool]:
    """
    Raise NotImplementedError as this method is not used for the moment.
    """
    raise NotImplementedError("AbnormalVoxelData.isin")