From 7071f00e84b1728a1cdfc402fee1e2bebc50b3d4 Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Tue, 19 Sep 2023 15:18:02 -0400 Subject: [PATCH 1/2] ENH: Expand CIFTI2 constants to use a synonym recoder --- nibabel/cifti2/cifti2.py | 93 ++++++++++++++++++++++------------- nibabel/cifti2/cifti2_axes.py | 8 +-- 2 files changed, 63 insertions(+), 38 deletions(-) diff --git a/nibabel/cifti2/cifti2.py b/nibabel/cifti2/cifti2.py index b41521f0c..9970e941f 100644 --- a/nibabel/cifti2/cifti2.py +++ b/nibabel/cifti2/cifti2.py @@ -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): @@ -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'), ) diff --git a/nibabel/cifti2/cifti2_axes.py b/nibabel/cifti2/cifti2_axes.py index bc6069a16..6443a34fb 100644 --- a/nibabel/cifti2/cifti2_axes.py +++ b/nibabel/cifti2/cifti2_axes.py @@ -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] @@ -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 From 20bffc3241085f6d94982ae0217724e25e8bfc7b Mon Sep 17 00:00:00 2001 From: Chris Markiewicz Date: Tue, 19 Sep 2023 20:24:55 -0400 Subject: [PATCH 2/2] Update nibabel/cifti2/cifti2.py Co-authored-by: Mathias Goncalves --- nibabel/cifti2/cifti2.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nibabel/cifti2/cifti2.py b/nibabel/cifti2/cifti2.py index 9970e941f..34aed5a9e 100644 --- a/nibabel/cifti2/cifti2.py +++ b/nibabel/cifti2/cifti2.py @@ -81,7 +81,7 @@ class Cifti2HeaderError(Exception): ) -def _full_structure(struct): +def _full_structure(struct: str): """Expands STRUCT_NAME into: STRUCT_NAME, CIFTI_STRUCTURE_STRUCT_NAME, StructName