Browse Source

move/rename parse_hippocampal_volume_file_path() -> freesurfer.HippocampalSubfieldsVolumeFile.__init__()

Fabian Peter Hammerle 5 years ago
parent
commit
c2c741e339

+ 4 - 4
README.md

@@ -31,11 +31,11 @@ freesurfer-volume-reader /my/freesurfer/subjects /other/freesurfer/subjects
 or
 
 ```python
-from freesurfer_volume_reader import find_hippocampal_volume_files, \
-                                     read_hippocampal_volume_file_dataframe
+from freesurfer_volume_reader.freesurfer import HippocampalSubfieldsVolumeFile
+from freesurfer_volume_reader import read_hippocampal_volume_file_dataframe
 
-for volume_file_path in find_hippocampal_volume_files('/my/freesurfer/subjects'):
-    print(read_hippocampal_volume_file_dataframe(volume_file_path))
+for volume_file in HippocampalSubfieldsVolumeFile.find('/my/freesurfer/subjects'):
+    print(read_hippocampal_volume_file_dataframe(volume_file))
 ```
 
 ## Tests

+ 2 - 2
examples/barplot.py

@@ -17,8 +17,8 @@ def main():
     argparser.add_argument('--subject', required=True)
     argparser.add_argument('--subjects-dir', dest='subjects_dir_path', required=True)
     args = argparser.parse_args()
-    volume_frame = pandas.concat(read_hippocampal_volume_file_dataframe(p)
-                                 for p in HippocampalSubfieldsVolumeFile.find(args.subjects_dir_path))
+    volume_frame = pandas.concat(read_hippocampal_volume_file_dataframe(f)
+                                 for f in HippocampalSubfieldsVolumeFile.find(args.subjects_dir_path))
     volume_frame = volume_frame[volume_frame['subject'] == args.subject]
     volume_frame['subfield_segmentation_mode'] = volume_frame.apply(
         lambda row: ' & '.join(filter(None, ('T1' if row['T1_input'] else None,

+ 13 - 27
freesurfer_volume_reader/__init__.py

@@ -13,8 +13,6 @@ import pandas
 
 from freesurfer_volume_reader.freesurfer import HippocampalSubfieldsVolumeFile
 
-VOLUME_FILENAME_HEMISPHERE_MAP = {'l': 'left', 'r': 'right'}
-
 
 def remove_group_names_from_regex(regex_pattern: str) -> str:
     return re.sub(r'\?P<.+?>', '', regex_pattern)
@@ -31,29 +29,17 @@ def read_hippocampal_volumes_mm3(volume_file_path: str) -> dict:
     return subfield_volumes
 
 
-def parse_hippocampal_volume_file_path(volume_file_path: str) -> dict:
-    subject_dir_path = os.path.dirname(os.path.dirname(os.path.abspath(volume_file_path)))
-    filename_match = HippocampalSubfieldsVolumeFile.FILENAME_REGEX.match(
-        os.path.basename(volume_file_path))
-    assert filename_match, volume_file_path
-    filename_groups = filename_match.groupdict()
-    assert filename_groups['T1'] or filename_groups['analysis_id'], volume_file_path
-    return {
-        'subject': os.path.basename(subject_dir_path),
-        'hemisphere': VOLUME_FILENAME_HEMISPHERE_MAP[filename_groups['h']],
-        'T1_input': filename_groups['T1'] is not None,
-        'analysis_id': filename_groups['analysis_id'],
-    }
-
-
-def read_hippocampal_volume_file_dataframe(volume_file_path: str) -> pandas.DataFrame:
+def read_hippocampal_volume_file_dataframe(volume_file: HippocampalSubfieldsVolumeFile,
+                                           ) -> pandas.DataFrame:
     volumes_frame = pandas.DataFrame([
         {'subfield': s, 'volume_mm^3': v}
-        for s, v in read_hippocampal_volumes_mm3(volume_file_path).items()
+        for s, v in read_hippocampal_volumes_mm3(volume_file.absolute_path).items()
     ])
-    for key, value in parse_hippocampal_volume_file_path(volume_file_path).items():
-        volumes_frame[key] = value
+    volumes_frame['subject'] = volume_file.subject
+    volumes_frame['hemisphere'] = volume_file.hemisphere
     # volumes_frame['hemisphere'] = volumes_frame['hemisphere'].astype('category')
+    volumes_frame['T1_input'] = volume_file.t1_input
+    volumes_frame['analysis_id'] = volume_file.analysis_id
     return volumes_frame
 
 
@@ -72,13 +58,13 @@ def main():
                            default=[subjects_dir_path],
                            help='default: $SUBJECTS_DIR ({})'.format(subjects_dir_path))
     args = argparser.parse_args()
-    volume_file_paths = [p for d in args.root_dir_paths
-                         for p in HippocampalSubfieldsVolumeFile.find(
-                             root_dir_path=d, filename_regex=args.filename_regex)]
+    volume_files = [f for d in args.root_dir_paths
+                    for f in HippocampalSubfieldsVolumeFile.find(
+                        root_dir_path=d, filename_regex=args.filename_regex)]
     volume_frames = []
-    for volume_file_path in volume_file_paths:
-        volume_frame = read_hippocampal_volume_file_dataframe(volume_file_path)
-        volume_frame['source_path'] = os.path.abspath(volume_file_path)
+    for volume_file in volume_files:
+        volume_frame = read_hippocampal_volume_file_dataframe(volume_file)
+        volume_frame['source_path'] = volume_file.absolute_path
         volume_frames.append(volume_frame)
     united_volume_frame = pandas.concat(volume_frames, ignore_index=True)
     print(united_volume_frame.to_csv(index=False))

+ 21 - 4
freesurfer_volume_reader/freesurfer.py

@@ -2,7 +2,6 @@ import os
 import re
 import typing
 
-
 # pylint: disable=too-few-public-methods
 class HippocampalSubfieldsVolumeFile:
 
@@ -11,9 +10,27 @@ class HippocampalSubfieldsVolumeFile:
                        r'(?P<T1>-T1)?(-(?P<analysis_id>.+?))?\.v10.txt$'
     FILENAME_REGEX = re.compile(FILENAME_PATTERN)
 
-    @staticmethod
-    def find(root_dir_path: str,
+    FILENAME_HEMISPHERE_PREFIX_MAP = {'l': 'left', 'r': 'right'}
+
+    def __init__(self, path: str):
+        self._absolute_path = os.path.abspath(path)
+        subject_dir_path = os.path.dirname(os.path.dirname(self._absolute_path))
+        self.subject = os.path.basename(subject_dir_path)
+        filename_match = self.FILENAME_REGEX.match(os.path.basename(path))
+        assert filename_match, self._absolute_path
+        filename_groups = filename_match.groupdict()
+        assert filename_groups['T1'] or filename_groups['analysis_id'], self._absolute_path
+        self.hemisphere = self.FILENAME_HEMISPHERE_PREFIX_MAP[filename_groups['h']]
+        self.t1_input = filename_groups['T1'] is not None
+        self.analysis_id = filename_groups['analysis_id']
+
+    @property
+    def absolute_path(self):
+        return self._absolute_path
+
+    @classmethod
+    def find(cls, root_dir_path: str,
              filename_regex: typing.Pattern = FILENAME_REGEX) -> typing.Iterator[str]:
         for dirpath, _, filenames in os.walk(root_dir_path):
             for filename in filter(filename_regex.search, filenames):
-                yield os.path.join(dirpath, filename)
+                yield cls(path=os.path.join(dirpath, filename))

+ 48 - 7
tests/freesurfer_test.py

@@ -8,6 +8,46 @@ from freesurfer_volume_reader.freesurfer import HippocampalSubfieldsVolumeFile
 SUBJECTS_DIR = os.path.join(os.path.dirname(__file__), 'subjects')
 
 
+@pytest.mark.parametrize(('volume_file_path', 'expected_attrs'), [
+    ('bert/mri/lh.hippoSfVolumes-T1.v10.txt',
+     {'subject': 'bert', 'hemisphere': 'left', 't1_input': True, 'analysis_id': None}),
+    ('bert/mri/lh.hippoSfVolumes-T1-T2.v10.txt',
+     {'subject': 'bert', 'hemisphere': 'left', 't1_input': True, 'analysis_id': 'T2'}),
+    ('bert/mri/lh.hippoSfVolumes-T2.v10.txt',
+     {'subject': 'bert', 'hemisphere': 'left', 't1_input': False, 'analysis_id': 'T2'}),
+    ('bert/mri/lh.hippoSfVolumes-T1-T2-high-res.v10.txt',
+     {'subject': 'bert', 'hemisphere': 'left', 't1_input': True, 'analysis_id': 'T2-high-res'}),
+    ('bert/mri/lh.hippoSfVolumes-T2-high-res.v10.txt',
+     {'subject': 'bert', 'hemisphere': 'left', 't1_input': False, 'analysis_id': 'T2-high-res'}),
+    ('bert/mri/lh.hippoSfVolumes-PD.v10.txt',
+     {'subject': 'bert', 'hemisphere': 'left', 't1_input': False, 'analysis_id': 'PD'}),
+    ('bert/mri/rh.hippoSfVolumes-T1.v10.txt',
+     {'subject': 'bert', 'hemisphere': 'right', 't1_input': True, 'analysis_id': None}),
+    ('bert/mri/rh.hippoSfVolumes-T1-T2.v10.txt',
+     {'subject': 'bert', 'hemisphere': 'right', 't1_input': True, 'analysis_id': 'T2'}),
+    ('freesurfer/subjects/bert/mri/lh.hippoSfVolumes-T1.v10.txt',
+     {'subject': 'bert', 'hemisphere': 'left', 't1_input': True, 'analysis_id': None}),
+    ('../../bert/mri/lh.hippoSfVolumes-T1.v10.txt',
+     {'subject': 'bert', 'hemisphere': 'left', 't1_input': True, 'analysis_id': None}),
+])
+def test_hippocampal_subfields_volume_file_init(volume_file_path, expected_attrs):
+    volume_file = HippocampalSubfieldsVolumeFile(path=volume_file_path)
+    assert os.path.basename(volume_file_path) == os.path.basename(volume_file.absolute_path)
+    for attr, value in expected_attrs.items():
+        assert value == getattr(volume_file, attr)
+
+
+@pytest.mark.parametrize('volume_file_path', [
+    'bert/mri/lh.hippoSfLabels-T1.v10.mgz',
+    'bert/mri/lh.hippoSfVolumes-T1.v9.txt',
+    'bert/mri/lh.hippoSfVolumes.v10.txt',
+    'bert/mri/mh.hippoSfVolumes-T1.v10.txt',
+])
+def test_hippocampal_subfields_volume_file_init_invalid(volume_file_path):
+    with pytest.raises(Exception):
+        HippocampalSubfieldsVolumeFile(path=volume_file_path)
+
+
 @pytest.mark.parametrize(('root_dir_path', 'expected_file_paths'), [
     (SUBJECTS_DIR,
      {os.path.join(SUBJECTS_DIR, 'alice', 'mri', 'lh.hippoSfVolumes-T1.v10.txt'),
@@ -20,9 +60,9 @@ SUBJECTS_DIR = os.path.join(os.path.dirname(__file__), 'subjects')
      {os.path.join(SUBJECTS_DIR, 'bert', 'mri', 'lh.hippoSfVolumes-T1-T2.v10.txt'),
       os.path.join(SUBJECTS_DIR, 'bert', 'mri', 'lh.hippoSfVolumes-T1.v10.txt')}),
 ])
-def test_find_hippocampal_volume_files(root_dir_path, expected_file_paths):
-    assert expected_file_paths == set(
-        HippocampalSubfieldsVolumeFile.find(root_dir_path=root_dir_path))
+def test_hippocampal_subfields_volume_file_find(root_dir_path, expected_file_paths):
+    volume_files_iterator = HippocampalSubfieldsVolumeFile.find(root_dir_path=root_dir_path)
+    assert expected_file_paths == set(f.absolute_path for f in volume_files_iterator)
 
 
 @pytest.mark.parametrize(('root_dir_path', 'filename_pattern', 'expected_file_paths'), [
@@ -34,7 +74,8 @@ def test_find_hippocampal_volume_files(root_dir_path, expected_file_paths):
      r'hippoSfVolumes-T1-T2',
      {os.path.join(SUBJECTS_DIR, 'bert', 'mri', 'lh.hippoSfVolumes-T1-T2.v10.txt')}),
 ])
-def test_find_hippocampal_volume_files_pattern(root_dir_path, filename_pattern,
-                                               expected_file_paths):
-    assert expected_file_paths == set(HippocampalSubfieldsVolumeFile.find(
-        root_dir_path=root_dir_path, filename_regex=re.compile(filename_pattern)))
+def test_hippocampal_subfields_volume_file_find_pattern(root_dir_path, filename_pattern,
+                                                        expected_file_paths):
+    assert expected_file_paths == set(
+        f.absolute_path for f in HippocampalSubfieldsVolumeFile.find(
+            root_dir_path=root_dir_path, filename_regex=re.compile(filename_pattern)))

+ 4 - 40
tests/hippocampus_test.py

@@ -8,6 +8,7 @@ import pandas.util.testing
 import pytest
 
 import freesurfer_volume_reader
+import freesurfer_volume_reader.freesurfer
 
 SUBJECTS_DIR = os.path.join(os.path.dirname(__file__), 'subjects')
 
@@ -49,45 +50,6 @@ def test_read_hippocampal_volumes_mm3_not_found():
             os.path.join(SUBJECTS_DIR, 'non-existing', 'lh.hippoSfVolumes-T1.v10.txt'))
 
 
-@pytest.mark.parametrize(('volume_file_path', 'expected_attrs'), [
-    ('bert/mri/lh.hippoSfVolumes-T1.v10.txt',
-     {'subject': 'bert', 'hemisphere': 'left', 'T1_input': True, 'analysis_id': None}),
-    ('bert/mri/lh.hippoSfVolumes-T1-T2.v10.txt',
-     {'subject': 'bert', 'hemisphere': 'left', 'T1_input': True, 'analysis_id': 'T2'}),
-    ('bert/mri/lh.hippoSfVolumes-T2.v10.txt',
-     {'subject': 'bert', 'hemisphere': 'left', 'T1_input': False, 'analysis_id': 'T2'}),
-    ('bert/mri/lh.hippoSfVolumes-T1-T2-high-res.v10.txt',
-     {'subject': 'bert', 'hemisphere': 'left', 'T1_input': True, 'analysis_id': 'T2-high-res'}),
-    ('bert/mri/lh.hippoSfVolumes-T2-high-res.v10.txt',
-     {'subject': 'bert', 'hemisphere': 'left', 'T1_input': False, 'analysis_id': 'T2-high-res'}),
-    ('bert/mri/lh.hippoSfVolumes-PD.v10.txt',
-     {'subject': 'bert', 'hemisphere': 'left', 'T1_input': False, 'analysis_id': 'PD'}),
-    ('bert/mri/rh.hippoSfVolumes-T1.v10.txt',
-     {'subject': 'bert', 'hemisphere': 'right', 'T1_input': True, 'analysis_id': None}),
-    ('bert/mri/rh.hippoSfVolumes-T1-T2.v10.txt',
-     {'subject': 'bert', 'hemisphere': 'right', 'T1_input': True, 'analysis_id': 'T2'}),
-    ('freesurfer/subjects/bert/mri/lh.hippoSfVolumes-T1.v10.txt',
-     {'subject': 'bert', 'hemisphere': 'left', 'T1_input': True, 'analysis_id': None}),
-    ('../../bert/mri/lh.hippoSfVolumes-T1.v10.txt',
-     {'subject': 'bert', 'hemisphere': 'left', 'T1_input': True, 'analysis_id': None}),
-])
-def test_parse_hippocampal_volume_file_path(volume_file_path, expected_attrs):
-    assert expected_attrs == freesurfer_volume_reader.parse_hippocampal_volume_file_path(
-        volume_file_path=volume_file_path)
-
-
-@pytest.mark.parametrize('volume_file_path', [
-    'bert/mri/lh.hippoSfLabels-T1.v10.mgz',
-    'bert/mri/lh.hippoSfVolumes-T1.v9.txt',
-    'bert/mri/lh.hippoSfVolumes.v10.txt',
-    'bert/mri/mh.hippoSfVolumes-T1.v10.txt',
-])
-def test_parse_hippocampal_volume_file_path_invalid(volume_file_path):
-    with pytest.raises(Exception):
-        freesurfer_volume_reader.parse_hippocampal_volume_file_path(
-            volume_file_path=volume_file_path)
-
-
 @pytest.mark.parametrize(('volume_file_path', 'expected_dataframe'), [
     (os.path.join(SUBJECTS_DIR, 'alice', 'mri', 'lh.hippoSfVolumes-T1.v10.txt'),
      pandas.DataFrame({
@@ -104,10 +66,12 @@ def test_parse_hippocampal_volume_file_path_invalid(volume_file_path):
      })),
 ])
 def test_read_hippocampal_volume_file_dataframe(volume_file_path, expected_dataframe):
+    volume_file = freesurfer_volume_reader.freesurfer.HippocampalSubfieldsVolumeFile(
+        path=volume_file_path)
     assert_volume_frames_equal(
         left=expected_dataframe,
         right=freesurfer_volume_reader.read_hippocampal_volume_file_dataframe(
-            volume_file_path=volume_file_path),
+            volume_file=volume_file),
     )