Browse Source

format code with black

Fabian Peter Hammerle 3 years ago
parent
commit
c68e57e71c
4 changed files with 336 additions and 262 deletions
  1. 2 0
      README.rst
  2. 45 35
      freesurfer_stats/__init__.py
  3. 23 28
      setup.py
  4. 266 199
      tests/test_cortical_parcellation_stats.py

+ 2 - 0
README.rst

@@ -1,6 +1,8 @@
 freesurfer-stats
 ================
 
+.. image:: https://img.shields.io/badge/code%20style-black-000000.svg
+   :target: https://github.com/psf/black
 .. image:: https://travis-ci.org/fphammerle/freesurfer-stats.svg?branch=master
    :target: https://travis-ci.org/fphammerle/freesurfer-stats
 .. image:: https://coveralls.io/repos/github/fphammerle/freesurfer-stats/badge.svg?branch=master

+ 45 - 35
freesurfer_stats/__init__.py

@@ -60,34 +60,38 @@ from freesurfer_stats.version import __version__
 
 class CorticalParcellationStats:
 
-    _HEMISPHERE_PREFIX_TO_SIDE = {'lh': 'left', 'rh': 'right'}
+    _HEMISPHERE_PREFIX_TO_SIDE = {"lh": "left", "rh": "right"}
     _GENERAL_MEASUREMENTS_REGEX = re.compile(
-        r'^Measure \S+, ([^,\s]+),? ([^,]+), ([\d\.]+), (\S+)$')
-    _COLUMN_NAMES_NON_SAFE_REGEX = re.compile(r'\s+')
+        r"^Measure \S+, ([^,\s]+),? ([^,]+), ([\d\.]+), (\S+)$"
+    )
+    _COLUMN_NAMES_NON_SAFE_REGEX = re.compile(r"\s+")
 
     def __init__(self):
-        self.headers \
-            = {}  # type: typing.Dict[str, typing.Union[str, datetime.datetime]]
-        self.whole_brain_measurements \
-            = {}  # type: typing.Dict[str, typing.Tuple[float, int]]
-        self.structural_measurements \
-            = {}  # type: typing.Union[pandas.DataFrame, None]
+        self.headers = (
+            {}
+        )  # type: typing.Dict[str, typing.Union[str, datetime.datetime]]
+        self.whole_brain_measurements = (
+            {}
+        )  # type: typing.Dict[str, typing.Tuple[float, int]]
+        self.structural_measurements = {}  # type: typing.Union[pandas.DataFrame, None]
 
     @property
     def hemisphere(self) -> str:
-        return self._HEMISPHERE_PREFIX_TO_SIDE[self.headers['hemi']]
+        return self._HEMISPHERE_PREFIX_TO_SIDE[self.headers["hemi"]]
 
     @staticmethod
     def _read_header_line(stream: typing.TextIO) -> str:
         line = stream.readline()
-        assert line.startswith('# ')
+        assert line.startswith("# ")
         return line[2:].rstrip()
 
     @classmethod
-    def _read_column_header_line(cls, stream: typing.TextIO) -> typing.Tuple[int, str, str]:
+    def _read_column_header_line(
+        cls, stream: typing.TextIO,
+    ) -> typing.Tuple[int, str, str]:
         line = cls._read_header_line(stream)
-        assert line.startswith('TableCol'), line
-        line = line[len('TableCol '):].lstrip()
+        assert line.startswith("TableCol"), line
+        line = line[len("TableCol ") :].lstrip()
         index, key, value = line.split(maxsplit=2)
         return int(index), key, value
 
@@ -95,23 +99,25 @@ class CorticalParcellationStats:
         self.headers = {}
         while True:
             line = self._read_header_line(stream)
-            if line.startswith('Measure'):
+            if line.startswith("Measure"):
                 break
             if line:
                 attr_name, attr_value = line.split(" ", maxsplit=1)
                 attr_value = attr_value.lstrip()
-                if attr_name in ['cvs_version', 'mrisurf.c-cvs_version']:
-                    attr_value = attr_value.strip('$').rstrip()
-                if attr_name == 'CreationTime':
+                if attr_name in ["cvs_version", "mrisurf.c-cvs_version"]:
+                    attr_value = attr_value.strip("$").rstrip()
+                if attr_name == "CreationTime":
                     attr_dt = datetime.datetime.strptime(
-                        attr_value, '%Y/%m/%d-%H:%M:%S-%Z')
+                        attr_value, "%Y/%m/%d-%H:%M:%S-%Z",
+                    )
                     if attr_dt.tzinfo is None:
-                        assert attr_value.endswith('-GMT')
+                        assert attr_value.endswith("-GMT")
                         attr_dt = attr_dt.replace(tzinfo=datetime.timezone.utc)
                     attr_value = attr_dt
-                if attr_name == 'AnnotationFileTimeStamp':
+                if attr_name == "AnnotationFileTimeStamp":
                     attr_value = datetime.datetime.strptime(
-                        attr_value, '%Y/%m/%d %H:%M:%S')
+                        attr_value, "%Y/%m/%d %H:%M:%S",
+                    )
                 self.headers[attr_name] = attr_value
 
     @classmethod
@@ -138,14 +144,14 @@ class CorticalParcellationStats:
         return column_name, pandas.to_numeric([value], errors="raise")
 
     @classmethod
-    def _read_column_attributes(cls, num: int, stream: typing.TextIO) \
-            -> typing.List[typing.Dict[str, str]]:
+    def _read_column_attributes(
+        cls, num: int, stream: typing.TextIO,
+    ) -> typing.List[typing.Dict[str, str]]:
         columns = []
         for column_index in range(1, int(num) + 1):
             column_attrs = {}
             for _ in range(3):
-                column_index_line, key, value \
-                    = cls._read_column_header_line(stream)
+                column_index_line, key, value = cls._read_column_header_line(stream)
                 assert column_index_line == column_index
                 assert key not in column_attrs
                 column_attrs[key] = value
@@ -153,9 +159,11 @@ class CorticalParcellationStats:
         return columns
 
     def _read(self, stream: typing.TextIO) -> None:
-        assert stream.readline().rstrip() \
-            == '# Table of FreeSurfer cortical parcellation anatomical statistics'
-        assert stream.readline().rstrip() == '#'
+        assert (
+            stream.readline().rstrip()
+            == "# Table of FreeSurfer cortical parcellation anatomical statistics"
+        )
+        assert stream.readline().rstrip() == "#"
         self._read_headers(stream)
         self.whole_brain_measurements = pandas.DataFrame()
         line = self._read_header_line(stream)
@@ -172,14 +180,16 @@ class CorticalParcellationStats:
                 assert column_name not in self.whole_brain_measurements, column_name
                 self.whole_brain_measurements[column_name] = value
             line = self._read_header_line(stream)
-        columns = self._read_column_attributes(
-            int(line[len('NTableCols '):]), stream)
-        assert self._read_header_line(stream) \
-            == 'ColHeaders ' + ' '.join(c['ColHeader'] for c in columns)
+        columns = self._read_column_attributes(int(line[len("NTableCols ") :]), stream)
+        assert self._read_header_line(stream) == "ColHeaders " + " ".join(
+            c["ColHeader"] for c in columns
+        )
         self.structural_measurements = pandas.DataFrame(
             (line.rstrip().split() for line in stream),
-            columns=[self._format_column_name(c['FieldName'], c['Units']) for c in columns]) \
-            .apply(pandas.to_numeric, errors='ignore')
+            columns=[
+                self._format_column_name(c["FieldName"], c["Units"]) for c in columns
+            ],
+        ).apply(pandas.to_numeric, errors="ignore")
 
     @classmethod
     def read(cls, path: typing.Union[str, pathlib.Path]) -> "CorticalParcellationStats":

+ 23 - 28
setup.py

@@ -19,38 +19,38 @@ import os
 
 import setuptools
 
-with open('README.rst', 'r') as readme:
+with open("README.rst", "r") as readme:
     LONG_DESCRIPTION = readme.read()
 
 setuptools.setup(
     name="freesurfer-stats",
     use_scm_version={
-        'write_to': os.path.join('freesurfer_stats', 'version.py'),
+        "write_to": os.path.join("freesurfer_stats", "version.py"),
         # `version` triggers pylint C0103
-        'write_to_template': "__version__ = '{version}'\n",
+        "write_to_template": "__version__ = '{version}'\n",
     },
     description="Python Library to Read FreeSurfer's cortical parcellation anatomical statistics",
     long_description=LONG_DESCRIPTION,
-    author='Fabian Peter Hammerle',
-    author_email='fabian@hammerle.me',
-    url='https://github.com/fphammerle/freesurfer-stats',
+    author="Fabian Peter Hammerle",
+    author_email="fabian@hammerle.me",
+    url="https://github.com/fphammerle/freesurfer-stats",
     license="GPLv3+",
     keywords=[
-        'anatomy',
-        'aparc',
-        'area',
-        'brain',
-        'cortex',
-        'dataframe',
-        'freesurfer',
-        'mris_anatomical_stats',
-        'neuroimaging',
-        'pandas',
-        'parcellation',
-        'reader',
-        'statistics',
-        'surface',
-        'volume',
+        "anatomy",
+        "aparc",
+        "area",
+        "brain",
+        "cortex",
+        "dataframe",
+        "freesurfer",
+        "mris_anatomical_stats",
+        "neuroimaging",
+        "pandas",
+        "parcellation",
+        "reader",
+        "statistics",
+        "surface",
+        "volume",
     ],
     classifiers=[
         "Development Status :: 4 - Beta",
@@ -72,11 +72,6 @@ setuptools.setup(
         # TODO verify lower version constraint
         "pandas>=0.21,<2",
     ],
-    setup_requires=[
-        'setuptools_scm',
-    ],
-    tests_require=[
-        'pytest-cov<3,>=2',
-        'pytest<5',
-    ],
+    setup_requires=["setuptools_scm"],
+    tests_require=["pytest<5"],
 )

+ 266 - 199
tests/test_cortical_parcellation_stats.py

@@ -30,183 +30,242 @@ from freesurfer_stats import CorticalParcellationStats
 
 
 @pytest.mark.parametrize(
-    ('path', 'headers', 'hemisphere',
-     'whole_brain_measurements', 'structural_measurements_length',
-     'structural_measurements_subset'),
-    [(os.path.join(SUBJECTS_DIR, 'fabian', 'stats', 'lh.aparc.DKTatlas.stats.short'),
-      {'CreationTime': datetime.datetime(2019, 5, 9, 21, 5, 54, tzinfo=datetime.timezone.utc),
-       'generating_program': 'mris_anatomical_stats',
-       'cvs_version': 'Id: mris_anatomical_stats.c,v 1.79 2016/03/14 15:15:34 greve Exp',
-       'mrisurf.c-cvs_version': 'Id: mrisurf.c,v 1.781.2.6 2016/12/27 16:47:14 zkaufman Exp',
-       'cmdline': 'mris_anatomical_stats -th3 -mgz -cortex ../label/lh.cortex.label'
-                  ' -f ../stats/lh.aparc.DKTatlas.stats -b -a ../label/lh.aparc.DKTatlas.annot'
-                  ' -c ../label/aparc.annot.DKTatlas.ctab fabian lh white',
-       'sysname': 'Linux',
-       'hostname': 'another-hostname',
-       'machine': 'x86_64',
-       'user': 'some-username',
-       'SUBJECTS_DIR': '/home/some-username/freesurfer-subjects',
-       'anatomy_type': 'surface',
-       'subjectname': 'fabian',
-       'hemi': 'lh',
-       'AnnotationFile': '../label/lh.aparc.DKTatlas.annot',
-       'AnnotationFileTimeStamp': datetime.datetime(2019, 5, 9, 23, 5, 40)},
-      'left',
-      {'white_surface_total_area_mm^2': 98553,
-       'mean_thickness_mm': 2.50462,
-       'brain_segmentation_volume_mm^3': 1327432.000000,
-       'brain_segmentation_volume_without_ventricles_mm^3': 1316285.000000,
-       'brain_segmentation_volume_without_ventricles_from_surf_mm^3': 1315572.548920,
-       'total_cortical_gray_matter_volume_mm^3': 553998.311189,
-       'supratentorial_volume_mm^3': 1172669.548920,
-       'supratentorial_volume_without_ventricles_mm^3': 1164180.548920,
-       'estimated_total_intracranial_volume_mm^3': 1670487.274486},
-      3,
-      [{'structure_name': 'caudalanteriorcingulate',
-        'number_of_vertices': 2061,
-        'surface_area_mm^2': 1472,
-        'gray_matter_volume_mm^3': 4258,
-        'average_thickness_mm': 2.653,
-        'thickness_stddev_mm': 0.644,
-        'integrated_rectified_mean_curvature_mm^-1': 0.135,
-        'integrated_rectified_gaussian_curvature_mm^-2': 0.020,
-        'folding_index': 27,
-        'intrinsic_curvature_index': 1.6},
-       {'structure_name': 'caudalmiddlefrontal',
-        'number_of_vertices': 4451,
-        'surface_area_mm^2': 3039,
-        'gray_matter_volume_mm^3': 8239,
-        'average_thickness_mm': 2.456,
-        'thickness_stddev_mm': 0.486,
-        'integrated_rectified_mean_curvature_mm^-1': 0.116,
-        'integrated_rectified_gaussian_curvature_mm^-2': 0.020,
-        'folding_index': 42,
-        'intrinsic_curvature_index': 3.7},
-       {'structure_name': 'insula',
-        'number_of_vertices': 3439,
-        'surface_area_mm^2': 2304,
-        'gray_matter_volume_mm^3': 7594,
-        'average_thickness_mm': 3.193,
-        'thickness_stddev_mm': 0.620,
-        'integrated_rectified_mean_curvature_mm^-1': 0.116,
-        'integrated_rectified_gaussian_curvature_mm^-2': 0.027,
-        'folding_index': 33,
-        'intrinsic_curvature_index': 3.5}]),
-     (os.path.join(
-         SUBJECTS_DIR, 'fabian', 'stats', 'rh.aparc.pial.stats.short'),
-      {'CreationTime': datetime.datetime(2019, 5, 9, 21, 3, 42, tzinfo=datetime.timezone.utc),
-       'generating_program': 'mris_anatomical_stats',
-       'cvs_version': 'Id: mris_anatomical_stats.c,v 1.79 2016/03/14 15:15:34 greve Exp',
-       'mrisurf.c-cvs_version': 'Id: mrisurf.c,v 1.781.2.6 2016/12/27 16:47:14 zkaufman Exp',
-       'cmdline': 'mris_anatomical_stats -th3 -mgz -cortex ../label/rh.cortex.label'
-                  ' -f ../stats/rh.aparc.pial.stats -b -a ../label/rh.aparc.annot'
-                  ' -c ../label/aparc.annot.ctab fabian rh pial',
-       'sysname': 'Linux',
-       'hostname': 'some-hostname',
-       'machine': 'x86_64',
-       'user': 'some-username',
-       'SUBJECTS_DIR': '/home/some-username/freesurfer-subjects',
-       'anatomy_type': 'surface',
-       'subjectname': 'fabian',
-       'hemi': 'rh',
-       'AnnotationFile': '../label/rh.aparc.annot',
-       'AnnotationFileTimeStamp': datetime.datetime(2019, 5, 9, 22, 27, 28)},
-      'right',
-      {'pial_surface_total_area_mm^2': 121260,
-       'mean_thickness_mm': 2.4817,
-       'brain_segmentation_volume_mm^3': 1327432.000000,
-       'brain_segmentation_volume_without_ventricles_mm^3': 1316285.000000,
-       'brain_segmentation_volume_without_ventricles_from_surf_mm^3': 1315572.548920,
-       'total_cortical_gray_matter_volume_mm^3': 553998.311189,
-       'supratentorial_volume_mm^3': 1172669.548920,
-       'supratentorial_volume_without_ventricles_mm^3': 1164180.548920,
-       'estimated_total_intracranial_volume_mm^3': 1670487.274486},
-      2,
-      [{'structure_name': 'bankssts',
-        'number_of_vertices': 1344,
-        'surface_area_mm^2': 825,
-        'gray_matter_volume_mm^3': 2171,
-        'average_thickness_mm': 2.436,
-        'thickness_stddev_mm': 0.381,
-        'integrated_rectified_mean_curvature_mm^-1': 0.115,
-        'integrated_rectified_gaussian_curvature_mm^-2': 0.028,
-        'folding_index': 19,
-        'intrinsic_curvature_index': 1.7},
-       {'structure_name': 'transversetemporal',
-        'number_of_vertices': 651,
-        'surface_area_mm^2': 545,
-        'gray_matter_volume_mm^3': 1061,
-        'average_thickness_mm': 2.251,
-        'thickness_stddev_mm': 0.317,
-        'integrated_rectified_mean_curvature_mm^-1': 0.110,
-        'integrated_rectified_gaussian_curvature_mm^-2': 0.021,
-        'folding_index': 3,
-        'intrinsic_curvature_index': 0.6}]),
-     (os.path.join(
-         SUBJECTS_DIR, 'soichi', 'stats', 'rh.aparc.stats'),
-      {'CreationTime': datetime.datetime(2020, 5, 4, 22, 20, 26, tzinfo=datetime.timezone.utc),
-       'AnnotationFileTimeStamp': datetime.datetime(2020, 5, 4, 21, 58, 13),
-       'AnnotationFile': '../label/rh.aparc.annot',
-       'SUBJECTS_DIR': '/N/dc2/scratch/hayashis/bigred3-workflows'
-                       '/5eb0689676c10ead933d673c/5eb068b076c10e7b013d673f',
-       'anatomy_type': 'surface',
-       'cmdline': 'mris_anatomical_stats -th3 -mgz -cortex ../label/rh.cortex.label '
-                  '-f ../stats/rh.aparc.stats -b -a ../label/rh.aparc.annot -c '
-                  '../label/aparc.annot.ctab output rh white',
-       'cvs_version': '7.0.0',
-       'generating_program': 'mris_anatomical_stats',
-       'hemi': 'rh',
-       'hostname': 'nid00762',
-       'machine': 'x86_64',
-       'mrisurf.c-cvs_version': '7.0.0',
-       'subjectname': 'output',
-       'sysname': 'Linux',
-       'user': 'hayashis',
-       'BrainVolStatsFixed': 'NotNeeded because voxelvolume=1mm3'},
-      'right',
-      {'white_surface_total_area_mm^2': 83579.2,
-       'mean_thickness_mm': 2.35815,
-       'brain_segmentation_volume_mm^3': 1169408.0,
-       'brain_segmentation_volume_without_ventricles_mm^3': 1157593.0,
-       'brain_segmentation_volume_without_ventricles_from_surf_mm^3': 1157593.0,
-       'total_cortical_gray_matter_volume_mm^3': 454587.696158,
-       'supratentorial_volume_mm^3': 1023873.0,
-       'supratentorial_volume_without_ventricles_mm^3': 1012058.0,
-       'estimated_total_intracranial_volume_mm^3': 1420434.160521},
-      34,
-      [{'structure_name': 'bankssts',
-        'number_of_vertices': 1094,
-        'surface_area_mm^2': 757,
-        'gray_matter_volume_mm^3': 1725,
-        'average_thickness_mm': 2.215,
-        'thickness_stddev_mm': 0.544,
-        'integrated_rectified_mean_curvature_mm^-1': 0.109,
-        'integrated_rectified_gaussian_curvature_mm^-2': 0.025,
-        'folding_index': 9,
-        'intrinsic_curvature_index': 1.1},
-       {'structure_name': 'caudalanteriorcingulate',
-        'number_of_vertices': 1137,
-        'surface_area_mm^2': 780,
-        'gray_matter_volume_mm^3': 2327,
-        'average_thickness_mm': 2.842,
-        'thickness_stddev_mm': 0.667,
-        'integrated_rectified_mean_curvature_mm^-1': 0.116,
-        'integrated_rectified_gaussian_curvature_mm^-2': 0.021,
-        'folding_index': 11,
-        'intrinsic_curvature_index': 1.0},
-       {'structure_name': 'caudalmiddlefrontal',
-        'number_of_vertices': 3126,
-        'surface_area_mm^2': 2218,
-        'gray_matter_volume_mm^3': 5978,
-        'average_thickness_mm': 2.447,
-        'thickness_stddev_mm': 0.605,
-        'integrated_rectified_mean_curvature_mm^-1': 0.122,
-        'integrated_rectified_gaussian_curvature_mm^-2': 0.024,
-        'folding_index': 28,
-        'intrinsic_curvature_index': 3.1}])],
+    (
+        "path",
+        "headers",
+        "hemisphere",
+        "whole_brain_measurements",
+        "structural_measurements_length",
+        "structural_measurements_subset",
+    ),
+    [
+        (
+            os.path.join(
+                SUBJECTS_DIR, "fabian", "stats", "lh.aparc.DKTatlas.stats.short"
+            ),
+            {
+                "CreationTime": datetime.datetime(
+                    2019, 5, 9, 21, 5, 54, tzinfo=datetime.timezone.utc
+                ),
+                "generating_program": "mris_anatomical_stats",
+                "cvs_version": "Id: mris_anatomical_stats.c,v 1.79 2016/03/14 15:15:34 greve Exp",
+                "mrisurf.c-cvs_version": "Id: mrisurf.c,v 1.781.2.6 2016/12/27 16:47:14 zkaufman Exp",
+                "cmdline": "mris_anatomical_stats -th3 -mgz -cortex ../label/lh.cortex.label"
+                " -f ../stats/lh.aparc.DKTatlas.stats -b -a ../label/lh.aparc.DKTatlas.annot"
+                " -c ../label/aparc.annot.DKTatlas.ctab fabian lh white",
+                "sysname": "Linux",
+                "hostname": "another-hostname",
+                "machine": "x86_64",
+                "user": "some-username",
+                "SUBJECTS_DIR": "/home/some-username/freesurfer-subjects",
+                "anatomy_type": "surface",
+                "subjectname": "fabian",
+                "hemi": "lh",
+                "AnnotationFile": "../label/lh.aparc.DKTatlas.annot",
+                "AnnotationFileTimeStamp": datetime.datetime(2019, 5, 9, 23, 5, 40),
+            },
+            "left",
+            {
+                "white_surface_total_area_mm^2": 98553,
+                "mean_thickness_mm": 2.50462,
+                "brain_segmentation_volume_mm^3": 1327432.000000,
+                "brain_segmentation_volume_without_ventricles_mm^3": 1316285.000000,
+                "brain_segmentation_volume_without_ventricles_from_surf_mm^3": 1315572.548920,
+                "total_cortical_gray_matter_volume_mm^3": 553998.311189,
+                "supratentorial_volume_mm^3": 1172669.548920,
+                "supratentorial_volume_without_ventricles_mm^3": 1164180.548920,
+                "estimated_total_intracranial_volume_mm^3": 1670487.274486,
+            },
+            3,
+            [
+                {
+                    "structure_name": "caudalanteriorcingulate",
+                    "number_of_vertices": 2061,
+                    "surface_area_mm^2": 1472,
+                    "gray_matter_volume_mm^3": 4258,
+                    "average_thickness_mm": 2.653,
+                    "thickness_stddev_mm": 0.644,
+                    "integrated_rectified_mean_curvature_mm^-1": 0.135,
+                    "integrated_rectified_gaussian_curvature_mm^-2": 0.020,
+                    "folding_index": 27,
+                    "intrinsic_curvature_index": 1.6,
+                },
+                {
+                    "structure_name": "caudalmiddlefrontal",
+                    "number_of_vertices": 4451,
+                    "surface_area_mm^2": 3039,
+                    "gray_matter_volume_mm^3": 8239,
+                    "average_thickness_mm": 2.456,
+                    "thickness_stddev_mm": 0.486,
+                    "integrated_rectified_mean_curvature_mm^-1": 0.116,
+                    "integrated_rectified_gaussian_curvature_mm^-2": 0.020,
+                    "folding_index": 42,
+                    "intrinsic_curvature_index": 3.7,
+                },
+                {
+                    "structure_name": "insula",
+                    "number_of_vertices": 3439,
+                    "surface_area_mm^2": 2304,
+                    "gray_matter_volume_mm^3": 7594,
+                    "average_thickness_mm": 3.193,
+                    "thickness_stddev_mm": 0.620,
+                    "integrated_rectified_mean_curvature_mm^-1": 0.116,
+                    "integrated_rectified_gaussian_curvature_mm^-2": 0.027,
+                    "folding_index": 33,
+                    "intrinsic_curvature_index": 3.5,
+                },
+            ],
+        ),
+        (
+            os.path.join(SUBJECTS_DIR, "fabian", "stats", "rh.aparc.pial.stats.short"),
+            {
+                "CreationTime": datetime.datetime(
+                    2019, 5, 9, 21, 3, 42, tzinfo=datetime.timezone.utc
+                ),
+                "generating_program": "mris_anatomical_stats",
+                "cvs_version": "Id: mris_anatomical_stats.c,v 1.79 2016/03/14 15:15:34 greve Exp",
+                "mrisurf.c-cvs_version": "Id: mrisurf.c,v 1.781.2.6 2016/12/27 16:47:14 zkaufman Exp",
+                "cmdline": "mris_anatomical_stats -th3 -mgz -cortex ../label/rh.cortex.label"
+                " -f ../stats/rh.aparc.pial.stats -b -a ../label/rh.aparc.annot"
+                " -c ../label/aparc.annot.ctab fabian rh pial",
+                "sysname": "Linux",
+                "hostname": "some-hostname",
+                "machine": "x86_64",
+                "user": "some-username",
+                "SUBJECTS_DIR": "/home/some-username/freesurfer-subjects",
+                "anatomy_type": "surface",
+                "subjectname": "fabian",
+                "hemi": "rh",
+                "AnnotationFile": "../label/rh.aparc.annot",
+                "AnnotationFileTimeStamp": datetime.datetime(2019, 5, 9, 22, 27, 28),
+            },
+            "right",
+            {
+                "pial_surface_total_area_mm^2": 121260,
+                "mean_thickness_mm": 2.4817,
+                "brain_segmentation_volume_mm^3": 1327432.000000,
+                "brain_segmentation_volume_without_ventricles_mm^3": 1316285.000000,
+                "brain_segmentation_volume_without_ventricles_from_surf_mm^3": 1315572.548920,
+                "total_cortical_gray_matter_volume_mm^3": 553998.311189,
+                "supratentorial_volume_mm^3": 1172669.548920,
+                "supratentorial_volume_without_ventricles_mm^3": 1164180.548920,
+                "estimated_total_intracranial_volume_mm^3": 1670487.274486,
+            },
+            2,
+            [
+                {
+                    "structure_name": "bankssts",
+                    "number_of_vertices": 1344,
+                    "surface_area_mm^2": 825,
+                    "gray_matter_volume_mm^3": 2171,
+                    "average_thickness_mm": 2.436,
+                    "thickness_stddev_mm": 0.381,
+                    "integrated_rectified_mean_curvature_mm^-1": 0.115,
+                    "integrated_rectified_gaussian_curvature_mm^-2": 0.028,
+                    "folding_index": 19,
+                    "intrinsic_curvature_index": 1.7,
+                },
+                {
+                    "structure_name": "transversetemporal",
+                    "number_of_vertices": 651,
+                    "surface_area_mm^2": 545,
+                    "gray_matter_volume_mm^3": 1061,
+                    "average_thickness_mm": 2.251,
+                    "thickness_stddev_mm": 0.317,
+                    "integrated_rectified_mean_curvature_mm^-1": 0.110,
+                    "integrated_rectified_gaussian_curvature_mm^-2": 0.021,
+                    "folding_index": 3,
+                    "intrinsic_curvature_index": 0.6,
+                },
+            ],
+        ),
+        (
+            os.path.join(SUBJECTS_DIR, "soichi", "stats", "rh.aparc.stats"),
+            {
+                "CreationTime": datetime.datetime(
+                    2020, 5, 4, 22, 20, 26, tzinfo=datetime.timezone.utc
+                ),
+                "AnnotationFileTimeStamp": datetime.datetime(2020, 5, 4, 21, 58, 13),
+                "AnnotationFile": "../label/rh.aparc.annot",
+                "SUBJECTS_DIR": "/N/dc2/scratch/hayashis/bigred3-workflows"
+                "/5eb0689676c10ead933d673c/5eb068b076c10e7b013d673f",
+                "anatomy_type": "surface",
+                "cmdline": "mris_anatomical_stats -th3 -mgz -cortex ../label/rh.cortex.label "
+                "-f ../stats/rh.aparc.stats -b -a ../label/rh.aparc.annot -c "
+                "../label/aparc.annot.ctab output rh white",
+                "cvs_version": "7.0.0",
+                "generating_program": "mris_anatomical_stats",
+                "hemi": "rh",
+                "hostname": "nid00762",
+                "machine": "x86_64",
+                "mrisurf.c-cvs_version": "7.0.0",
+                "subjectname": "output",
+                "sysname": "Linux",
+                "user": "hayashis",
+                "BrainVolStatsFixed": "NotNeeded because voxelvolume=1mm3",
+            },
+            "right",
+            {
+                "white_surface_total_area_mm^2": 83579.2,
+                "mean_thickness_mm": 2.35815,
+                "brain_segmentation_volume_mm^3": 1169408.0,
+                "brain_segmentation_volume_without_ventricles_mm^3": 1157593.0,
+                "brain_segmentation_volume_without_ventricles_from_surf_mm^3": 1157593.0,
+                "total_cortical_gray_matter_volume_mm^3": 454587.696158,
+                "supratentorial_volume_mm^3": 1023873.0,
+                "supratentorial_volume_without_ventricles_mm^3": 1012058.0,
+                "estimated_total_intracranial_volume_mm^3": 1420434.160521,
+            },
+            34,
+            [
+                {
+                    "structure_name": "bankssts",
+                    "number_of_vertices": 1094,
+                    "surface_area_mm^2": 757,
+                    "gray_matter_volume_mm^3": 1725,
+                    "average_thickness_mm": 2.215,
+                    "thickness_stddev_mm": 0.544,
+                    "integrated_rectified_mean_curvature_mm^-1": 0.109,
+                    "integrated_rectified_gaussian_curvature_mm^-2": 0.025,
+                    "folding_index": 9,
+                    "intrinsic_curvature_index": 1.1,
+                },
+                {
+                    "structure_name": "caudalanteriorcingulate",
+                    "number_of_vertices": 1137,
+                    "surface_area_mm^2": 780,
+                    "gray_matter_volume_mm^3": 2327,
+                    "average_thickness_mm": 2.842,
+                    "thickness_stddev_mm": 0.667,
+                    "integrated_rectified_mean_curvature_mm^-1": 0.116,
+                    "integrated_rectified_gaussian_curvature_mm^-2": 0.021,
+                    "folding_index": 11,
+                    "intrinsic_curvature_index": 1.0,
+                },
+                {
+                    "structure_name": "caudalmiddlefrontal",
+                    "number_of_vertices": 3126,
+                    "surface_area_mm^2": 2218,
+                    "gray_matter_volume_mm^3": 5978,
+                    "average_thickness_mm": 2.447,
+                    "thickness_stddev_mm": 0.605,
+                    "integrated_rectified_mean_curvature_mm^-1": 0.122,
+                    "integrated_rectified_gaussian_curvature_mm^-2": 0.024,
+                    "folding_index": 28,
+                    "intrinsic_curvature_index": 3.1,
+                },
+            ],
+        ),
+    ],
 )
-def test_read(path, headers, hemisphere, whole_brain_measurements, structural_measurements_length,
-              structural_measurements_subset):
+def test_read(
+    path,
+    headers,
+    hemisphere,
+    whole_brain_measurements,
+    structural_measurements_length,
+    structural_measurements_subset,
+):
     stats = CorticalParcellationStats.read(path)
     assert headers == stats.headers
     assert hemisphere == stats.hemisphere
@@ -218,16 +277,16 @@ def test_read(path, headers, hemisphere, whole_brain_measurements, structural_me
         check_names=True,
     )
     assert list(stats.structural_measurements.columns) == [
-        'structure_name',
-        'number_of_vertices',
-        'surface_area_mm^2',
-        'gray_matter_volume_mm^3',
-        'average_thickness_mm',
-        'thickness_stddev_mm',
-        'integrated_rectified_mean_curvature_mm^-1',
-        'integrated_rectified_gaussian_curvature_mm^-2',
-        'folding_index',
-        'intrinsic_curvature_index',
+        "structure_name",
+        "number_of_vertices",
+        "surface_area_mm^2",
+        "gray_matter_volume_mm^3",
+        "average_thickness_mm",
+        "thickness_stddev_mm",
+        "integrated_rectified_mean_curvature_mm^-1",
+        "integrated_rectified_gaussian_curvature_mm^-2",
+        "folding_index",
+        "intrinsic_curvature_index",
     ]
     assert len(stats.structural_measurements) == structural_measurements_length
     pandas.util.testing.assert_frame_equal(
@@ -240,19 +299,27 @@ def test_read(path, headers, hemisphere, whole_brain_measurements, structural_me
 
 
 @pytest.mark.parametrize(
-    ('path', 'structural_measurements_length'),
-    [(os.path.join(SUBJECTS_DIR, 'soichi', 'stats', 'lh.BA_exvivo.stats'), 14),
-     (os.path.join(SUBJECTS_DIR, 'soichi', 'stats', 'lh.BA_exvivo.thresh.stats'), 14),
-     (os.path.join(SUBJECTS_DIR, 'soichi', 'stats', 'lh.aparc.DKTatlas.stats'), 31),
-     (os.path.join(SUBJECTS_DIR, 'soichi', 'stats', 'lh.aparc.a2009s.stats'), 74),
-     (os.path.join(SUBJECTS_DIR, 'soichi', 'stats', 'lh.aparc.pial.stats'), 34),
-     (os.path.join(SUBJECTS_DIR, 'soichi', 'stats', 'lh.aparc.stats'), 34),
-     (os.path.join(SUBJECTS_DIR, 'soichi', 'stats', 'rh.BA_exvivo.stats'), 14),
-     (os.path.join(SUBJECTS_DIR, 'soichi', 'stats', 'rh.BA_exvivo.thresh.stats'), 14),
-     (os.path.join(SUBJECTS_DIR, 'soichi', 'stats', 'rh.aparc.DKTatlas.stats'), 31),
-     (os.path.join(SUBJECTS_DIR, 'soichi', 'stats', 'rh.aparc.a2009s.stats'), 74),
-     (os.path.join(SUBJECTS_DIR, 'soichi', 'stats', 'rh.aparc.pial.stats'), 34),
-     (os.path.join(SUBJECTS_DIR, 'soichi', 'stats', 'rh.aparc.stats'), 34)],
+    ("path", "structural_measurements_length"),
+    [
+        (os.path.join(SUBJECTS_DIR, "soichi", "stats", "lh.BA_exvivo.stats"), 14),
+        (
+            os.path.join(SUBJECTS_DIR, "soichi", "stats", "lh.BA_exvivo.thresh.stats"),
+            14,
+        ),
+        (os.path.join(SUBJECTS_DIR, "soichi", "stats", "lh.aparc.DKTatlas.stats"), 31),
+        (os.path.join(SUBJECTS_DIR, "soichi", "stats", "lh.aparc.a2009s.stats"), 74),
+        (os.path.join(SUBJECTS_DIR, "soichi", "stats", "lh.aparc.pial.stats"), 34),
+        (os.path.join(SUBJECTS_DIR, "soichi", "stats", "lh.aparc.stats"), 34),
+        (os.path.join(SUBJECTS_DIR, "soichi", "stats", "rh.BA_exvivo.stats"), 14),
+        (
+            os.path.join(SUBJECTS_DIR, "soichi", "stats", "rh.BA_exvivo.thresh.stats"),
+            14,
+        ),
+        (os.path.join(SUBJECTS_DIR, "soichi", "stats", "rh.aparc.DKTatlas.stats"), 31),
+        (os.path.join(SUBJECTS_DIR, "soichi", "stats", "rh.aparc.a2009s.stats"), 74),
+        (os.path.join(SUBJECTS_DIR, "soichi", "stats", "rh.aparc.pial.stats"), 34),
+        (os.path.join(SUBJECTS_DIR, "soichi", "stats", "rh.aparc.stats"), 34),
+    ],
 )
 def test_read_structural_measurements_length(path, structural_measurements_length):
     # simple test to verify no exception gets raised, see test_read for comprehensive test