Skip to content

mri

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.

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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
@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) 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

Attributes:

Name Type Description
atlas Atlas
labels List[int]

atlas instance-attribute

labels instance-attribute

VoxelData

Bases: ABC, Generic[T]

Protocol defining the interface for voxel data access.

This interface abstracts the underlying data representation (numpy arrays, etc.) to keep the domain layer independent from technical implementations.

Methods:

Name Description
get_value_at

Get 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

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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
@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
    """

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
130
131
132
133
134
135
136
137
138
139
@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
141
142
143
144
145
146
147
148
149
150
@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
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
@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
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
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)

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
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
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(id, name, voxel_data) 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
id str

Unique identifier

name str

Name of the data (e.g. "Atlas3", "FA_map", etc.)

voxel_data VoxelData[T]

Provider for voxel data

mri_exam_id MRIExamId

Unique identifier of the MRI exam which this data belongs to

Initialize the MRIData object.

Parameters:

Name Type Description Default
id str

Unique identifier

required
name str

Name of the data (e.g. "Atlas3", "FA_map", etc.)

required
voxel_data VoxelData[T]

Provider for voxel data

required

Methods:

Name Description
get_voxel_data

Get the voxel data of this MRI volume.

Source code in oxytcmri/domain/entities/mri.py
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
def __init__(self, id: str, name: str, voxel_data: VoxelData[T]) -> None:
    """
    Initialize the MRIData object.

    Parameters
    ----------
    id : str
        Unique identifier
    name : str
        Name of the data (e.g. "Atlas3", "FA_map", etc.)
    voxel_data : VoxelData[T]
        Provider for voxel data
    """
    self.id = id
    self.name = name
    self.voxel_data = voxel_data
    # extract MRIExamId from the id: "{MRIExamId}_{name}"
    string_to_substract = f"_{self.name}"
    mri_exam_id_str = self.id.replace(string_to_substract, "")
    self.mri_exam_id = MRIExamId(mri_exam_id_str)

id = id instance-attribute

name = name instance-attribute

voxel_data = voxel_data instance-attribute

mri_exam_id = MRIExamId(mri_exam_id_str) 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
298
299
300
301
302
303
304
305
306
307
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(id, name, voxel_data, dti_metric)

Bases: MRIData[float]

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

Parameters:

Name Type Description Default
id str

Unique identifier

required
name str

Name of the data (e.g. "MD_map", "FA_map", etc.)

required
voxel_data VoxelData[float]

Provider for voxel data

required
dti_metric DTIMetric

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

required

Attributes:

Name Type Description
dti_metric
Source code in oxytcmri/domain/entities/mri.py
329
330
331
332
333
334
335
def __init__(self,
             id: str,
             name: str,
             voxel_data: VoxelData[float],
             dti_metric: DTIMetric) -> None:
    super().__init__(id, name, voxel_data)
    self.dti_metric = dti_metric

dti_metric = dti_metric instance-attribute

Mask(id, name, voxel_data)

Bases: MRIData[bool]

Represents a binary mask for a specific region of interest.

Parameters:

Name Type Description Default
id str

Unique identifier

required
name str

Name of the data (e.g. "mask1", "mask2", etc.)

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.

Source code in oxytcmri/domain/entities/mri.py
355
356
357
358
359
def __init__(self,
             id: str,
             name: str,
             voxel_data: VoxelData[bool]) -> None:
    super().__init__(id, name, voxel_data)

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
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
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

AtlasSegmentation(id, name, voxel_data, atlas)

Bases: MRIData[int]

Represents a segmentation of an atlas.

Parameters:

Name Type Description Default
id str

Unique identifier

required
name str

Name of the data (e.g. "MD_map", "FA_map", etc.)

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
420
421
422
423
424
425
426
def __init__(self,
             id: str,
             name: str,
             voxel_data: VoxelData[int],
             atlas: Atlas) -> None:
    super().__init__(id, name, voxel_data)
    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
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
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
    """
    mask_voxel_data = self.get_voxel_data().filter_by_values(labels)
    return Mask(id=f"{self.id}_mask",
                name=f"{self.name}_mask",
                voxel_data=mask_voxel_data)

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_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
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
@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
488
489
490
491
492
493
494
495
496
497
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
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
def get_dti_map(self, metric: DTIMetric) -> MRIData:
    """
    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_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
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
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
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
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
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
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
593
594
595
596
597
598
599
600
601
602
603
604
605
606
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)