Skip to content

Commit

Permalink
[ENH] Add enumeration for hemispheres (#1236)
Browse files Browse the repository at this point in the history
* add new HemiSphere enumeration

* use it in code base (not in pet surface)
  • Loading branch information
NicolasGensollen authored Jul 16, 2024
1 parent 73e32fb commit ef73502
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 14 deletions.
13 changes: 9 additions & 4 deletions clinica/pipelines/anatomical/freesurfer/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

import pandas as pd

from clinica.utils.image import HemiSphere

__all__ = [
"ImageID",
"extract_image_id_from_freesurfer_id",
Expand Down Expand Up @@ -192,8 +194,10 @@ def _generate_tsv_for_parcellation(
}
for info, col_name in info_dict.items():
# Secondary information are common to left and right hemispheres
stats_df = _get_secondary_stats(hemi_to_stats_filename["lh"], info)
for hemi in ("lh", "rh"):
stats_df = _get_secondary_stats(
hemi_to_stats_filename[HemiSphere.LEFT], info
)
for hemi in HemiSphere:
stats_df = pd.concat(
[
stats_df,
Expand Down Expand Up @@ -226,13 +230,14 @@ def _get_stats_filename_for_atlas(stats_folder: Path, atlas: str) -> dict:
-------
dict :
Dictionary mapping hemispheres to statistics file names.
Indexes are 'lh' for 'left hemisphere', and 'rh' for 'right hemisphere'.
Indexes are HemiSphere.LEFT for 'left hemisphere', and HemiSphere.RIGHT for 'right hemisphere'.
"""
atlas_dict = {"desikan": "aparc", "destrieux": "aparc.a2009s", "ba": "BA_exvivo"}
atlas_filename = atlas_dict.get(atlas, atlas)

return {
hemi: stats_folder / f"{hemi}.{atlas_filename}.stats" for hemi in ("lh", "rh")
hemi: stats_folder / f"{hemi.value}.{atlas_filename}.stats"
for hemi in HemiSphere
}


Expand Down
9 changes: 9 additions & 0 deletions clinica/utils/image.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from dataclasses import dataclass
from enum import Enum
from os import PathLike
from pathlib import Path
from typing import Callable, Optional, Tuple, Union
Expand All @@ -8,6 +9,7 @@
from nibabel.nifti1 import Nifti1Image

__all__ = [
"HemiSphere",
"compute_aggregated_volume",
"get_new_image_like",
"merge_nifti_images_in_time_dimension",
Expand All @@ -18,6 +20,13 @@
]


class HemiSphere(str, Enum):
"""Possible values for hemispheres."""

LEFT = "lh"
RIGHT = "rh"


def compute_aggregated_volume(
image_filename: PathLike,
aggregator: Optional[Callable] = None,
Expand Down
25 changes: 19 additions & 6 deletions test/nonregression/pipelines/pet/test_pet_surface.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import numpy as np
import pytest

from clinica.utils.image import HemiSphere
from clinica.utils.pet import SUVRReferenceRegion, Tracer


Expand Down Expand Up @@ -45,7 +46,7 @@ def run_pet_surface(
pipeline.build()
pipeline.run(bypass_check=True)

for hemisphere in ("lh", "rh"):
for hemisphere in HemiSphere:
for fwhm in (0, 5, 10, 15, 20, 25):
output_folder = (
output_dir
Expand All @@ -58,11 +59,17 @@ def run_pet_surface(
)
out = fspath(
output_folder
/ f"sub-ADNI011S4105_ses-M000_trc-{tracer.value}_pet_space-fsaverage_suvr-{region.value}_pvc-iy_hemi-{hemisphere}_fwhm-{fwhm}_projection.mgh"
/ (
f"sub-ADNI011S4105_ses-M000_trc-{tracer.value}_pet_space-fsaverage_suvr-{region.value}_"
f"pvc-iy_hemi-{hemisphere.value}_fwhm-{fwhm}_projection.mgh"
)
)
ref = fspath(
ref_dir
/ f"sub-ADNI011S4105_ses-M000_trc-{tracer.value}_pet_space-fsaverage_suvr-{region.value}_pvc-iy_hemi-{hemisphere}_fwhm-{fwhm}_projection.mgh"
/ (
f"sub-ADNI011S4105_ses-M000_trc-{tracer.value}_pet_space-fsaverage_suvr-{region.value}_"
f"pvc-iy_hemi-{hemisphere.value}_fwhm-{fwhm}_projection.mgh"
)
)
assert np.allclose(
np.squeeze(nib.load(out).get_fdata(dtype="float32")),
Expand Down Expand Up @@ -122,15 +129,21 @@ def run_pet_surface_longitudinal(
/ long_id
/ "surface_longitudinal"
)
for hemisphere in ("lh", "rh"):
for hemisphere in HemiSphere:
for fwhm in (0, 5, 10, 15, 20, 25):
out = fspath(
output_folder
/ f"{image_id}_trc-{tracer.value}_pet_space-fsaverage_suvr-{region.value}_pvc-iy_hemi-{hemisphere}_fwhm-{fwhm}_projection.mgh"
/ (
f"{image_id}_trc-{tracer.value}_pet_space-fsaverage_suvr-{region.value}_"
f"pvc-iy_hemi-{hemisphere.value}_fwhm-{fwhm}_projection.mgh"
)
)
ref = fspath(
ref_dir
/ f"{image_id}_trc-{tracer.value}_pet_space-fsaverage_suvr-{region.value}_pvc-iy_hemi-{hemisphere}_fwhm-{fwhm}_projection.mgh"
/ (
f"{image_id}_trc-{tracer.value}_pet_space-fsaverage_suvr-{region.value}_"
f"pvc-iy_hemi-{hemisphere.value}_fwhm-{fwhm}_projection.mgh"
)
)
assert np.allclose(
np.squeeze(nib.load(out).get_fdata(dtype="float32")),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
ImageID, # noqa
InfoType, # noqa
)
from clinica.utils.image import HemiSphere


@pytest.mark.parametrize(
Expand Down Expand Up @@ -108,8 +109,8 @@ def test_get_stats_filename_for_atlas(tmp_path, atlas, expected):
)

df = _get_stats_filename_for_atlas(tmp_path, atlas)
for hemi in ("lh", "rh"):
assert df[hemi] == tmp_path / f"{hemi}.{expected}"
for hemi in HemiSphere:
assert df[hemi.value] == tmp_path / f"{hemi.value}.{expected}"


def test_generate_tsv_for_parcellation_errors(tmp_path):
Expand Down Expand Up @@ -301,8 +302,8 @@ def test_generate_tsv_for_parcellation(tmp_path, prefix):
stats_folder = tmp_path / "stats"
stats_folder.mkdir()
for filename in ("aparc", "aparc.a2009s", "BA_exvivo"):
for hemi in ("lh", "rh"):
with open(stats_folder / f"{hemi}.{filename}.stats", "w") as fp:
for hemi in HemiSphere:
with open(stats_folder / f"{hemi.value}.{filename}.stats", "w") as fp:
fp.write(
generate_fake_parcellation_stats_file_content(dummy_number=42.0)
)
Expand Down

0 comments on commit ef73502

Please sign in to comment.