Skip to content

ENH: Expand CIFTI2 constants to use a synonym recoder #1256

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 22, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 59 additions & 34 deletions nibabel/cifti2/cifti2.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
from ..filebasedimages import FileBasedHeader, SerializableImage
from ..nifti1 import Nifti1Extensions
from ..nifti2 import Nifti2Header, Nifti2Image
from ..volumeutils import make_dt_codes
from ..volumeutils import Recoder, make_dt_codes


def _float_01(val):
Expand Down Expand Up @@ -80,39 +80,64 @@ class Cifti2HeaderError(Exception):
'RADIAN',
)

CIFTI_BRAIN_STRUCTURES = (
'CIFTI_STRUCTURE_ACCUMBENS_LEFT',
'CIFTI_STRUCTURE_ACCUMBENS_RIGHT',
'CIFTI_STRUCTURE_ALL_WHITE_MATTER',
'CIFTI_STRUCTURE_ALL_GREY_MATTER',
'CIFTI_STRUCTURE_AMYGDALA_LEFT',
'CIFTI_STRUCTURE_AMYGDALA_RIGHT',
'CIFTI_STRUCTURE_BRAIN_STEM',
'CIFTI_STRUCTURE_CAUDATE_LEFT',
'CIFTI_STRUCTURE_CAUDATE_RIGHT',
'CIFTI_STRUCTURE_CEREBELLAR_WHITE_MATTER_LEFT',
'CIFTI_STRUCTURE_CEREBELLAR_WHITE_MATTER_RIGHT',
'CIFTI_STRUCTURE_CEREBELLUM',
'CIFTI_STRUCTURE_CEREBELLUM_LEFT',
'CIFTI_STRUCTURE_CEREBELLUM_RIGHT',
'CIFTI_STRUCTURE_CEREBRAL_WHITE_MATTER_LEFT',
'CIFTI_STRUCTURE_CEREBRAL_WHITE_MATTER_RIGHT',
'CIFTI_STRUCTURE_CORTEX',
'CIFTI_STRUCTURE_CORTEX_LEFT',
'CIFTI_STRUCTURE_CORTEX_RIGHT',
'CIFTI_STRUCTURE_DIENCEPHALON_VENTRAL_LEFT',
'CIFTI_STRUCTURE_DIENCEPHALON_VENTRAL_RIGHT',
'CIFTI_STRUCTURE_HIPPOCAMPUS_LEFT',
'CIFTI_STRUCTURE_HIPPOCAMPUS_RIGHT',
'CIFTI_STRUCTURE_OTHER',
'CIFTI_STRUCTURE_OTHER_GREY_MATTER',
'CIFTI_STRUCTURE_OTHER_WHITE_MATTER',
'CIFTI_STRUCTURE_PALLIDUM_LEFT',
'CIFTI_STRUCTURE_PALLIDUM_RIGHT',
'CIFTI_STRUCTURE_PUTAMEN_LEFT',
'CIFTI_STRUCTURE_PUTAMEN_RIGHT',
'CIFTI_STRUCTURE_THALAMUS_LEFT',
'CIFTI_STRUCTURE_THALAMUS_RIGHT',

def _full_structure(struct):
"""Expands STRUCT_NAME into:

STRUCT_NAME, CIFTI_STRUCTURE_STRUCT_NAME, StructName
"""
return (
struct,
f'CIFTI_STRUCTURE_{struct}',
''.join(word.capitalize() for word in struct.split('_')),
)


CIFTI_BRAIN_STRUCTURES = Recoder(
(
# For simplicity of comparison, use the ordering from:
# https://github.com/Washington-University/workbench/blob/b985f5d/src/Common/StructureEnum.cxx
# (name, ciftiname, guiname)
# ('CORTEX_LEFT', 'CIFTI_STRUCTURE_CORTEX_LEFT', 'CortexLeft')
_full_structure('CORTEX_LEFT'),
_full_structure('CORTEX_RIGHT'),
_full_structure('CEREBELLUM'),
_full_structure('ACCUMBENS_LEFT'),
_full_structure('ACCUMBENS_RIGHT'),
_full_structure('ALL'),
_full_structure('ALL_GREY_MATTER'),
_full_structure('ALL_WHITE_MATTER'),
_full_structure('AMYGDALA_LEFT'),
_full_structure('AMYGDALA_RIGHT'),
_full_structure('BRAIN_STEM'),
_full_structure('CAUDATE_LEFT'),
_full_structure('CAUDATE_RIGHT'),
_full_structure('CEREBELLAR_WHITE_MATTER_LEFT'),
_full_structure('CEREBELLAR_WHITE_MATTER_RIGHT'),
_full_structure('CEREBELLUM_LEFT'),
_full_structure('CEREBELLUM_RIGHT'),
_full_structure('CEREBRAL_WHITE_MATTER_LEFT'),
_full_structure('CEREBRAL_WHITE_MATTER_RIGHT'),
_full_structure('CORTEX'),
_full_structure('DIENCEPHALON_VENTRAL_LEFT'),
_full_structure('DIENCEPHALON_VENTRAL_RIGHT'),
_full_structure('HIPPOCAMPUS_LEFT'),
_full_structure('HIPPOCAMPUS_RIGHT'),
_full_structure('INVALID'),
_full_structure('OTHER'),
_full_structure('OTHER_GREY_MATTER'),
_full_structure('OTHER_WHITE_MATTER'),
_full_structure('PALLIDUM_LEFT'),
_full_structure('PALLIDUM_RIGHT'),
_full_structure('PUTAMEN_LEFT'),
_full_structure('PUTAMEN_RIGHT'),
## Also commented out in connectome_wb; unclear if deprecated, planned, or what
# _full_structure("SUBCORTICAL_WHITE_MATTER_LEFT")
# _full_structure("SUBCORTICAL_WHITE_MATTER_RIGHT")
_full_structure('THALAMUS_LEFT'),
_full_structure('THALAMUS_RIGHT'),
),
fields=('name', 'ciftiname', 'guiname'),
)


Expand Down
8 changes: 4 additions & 4 deletions nibabel/cifti2/cifti2_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ def to_cifti_brain_structure_name(name):
ValueError: raised if the input name does not match a known anatomical structure in CIFTI-2
"""
if name in cifti2.CIFTI_BRAIN_STRUCTURES:
return name
return cifti2.CIFTI_BRAIN_STRUCTURES.ciftiname[name]
if not isinstance(name, str):
if len(name) == 1:
structure = name[0]
Expand Down Expand Up @@ -554,10 +554,10 @@ def to_cifti_brain_structure_name(name):
proposed_name = f'CIFTI_STRUCTURE_{structure.upper()}'
else:
proposed_name = f'CIFTI_STRUCTURE_{structure.upper()}_{orientation.upper()}'
if proposed_name not in cifti2.CIFTI_BRAIN_STRUCTURES:
if proposed_name not in cifti2.CIFTI_BRAIN_STRUCTURES.ciftiname:
raise ValueError(
f'{name} was interpreted as {proposed_name}, which is not '
'a valid CIFTI brain structure'
f'{name} was interpreted as {proposed_name}, '
'which is not a valid CIFTI brain structure'
)
return proposed_name

Expand Down