freesurfertools module

class clabtoolkit.freesurfertools.AnnotParcellation(parc_file=None, annot_id=None, ref_surf=None, cont_tech='local', cont_image=None)[source]

Bases: object

This class contains methods to work with FreeSurfer annot files # Implemented methods: # - Correct the parcellation by refilling the vertices from the cortex label file that do not have a label in the annotation file # - Convert FreeSurfer annot files to gcs files # Methods to be implemented: # Grouping regions to create a coarser parcellation # Removing regions from the parcellation # Correct parcellations by removing small clusters of vertices labeled inside another region

__init__(parc_file=None, annot_id=None, ref_surf=None, cont_tech='local', cont_image=None)[source]

Initialize the AnnotParcellation object

Parameters:
  • parc_file (str, optional) – Path to the parcellation file (annot, gii, or gcs format). If None, the object is initialized without loading any file.

  • annot_id (str, optional) – Annotation ID to use for the parcellation. If None, uses the file name without extension.

  • ref_surf (str, optional) – Reference surface for conversion. If None, uses the default FreeSurfer white surface.

  • cont_tech (str, optional) – Container technology to use (e.g., ‘local’, ‘docker’). Default is ‘local’.

  • cont_image (str, optional) – Container image to use. If None, uses the default for the specified container technology.

load_from_file(parc_file, annot_id=None, ref_surf=None, cont_tech='local', cont_image=None)[source]

Load parcellation data from file

Parameters:
  • parc_file (str) – Path to the parcellation file (annot, gii, or gcs format)

  • annot_id (str, optional) – Annotation ID to use for the parcellation. If None, uses the file name.

  • ref_surf (str, optional) – Reference surface for conversion. If None, uses the default FreeSurfer white surface.

  • cont_tech (str, optional) – Container technology to use (e.g., ‘local’, ‘docker’). Default is ‘local’.

  • cont_image (str, optional) – Container image to use. If None, uses the default for the specified container technology.

is_loaded()[source]

Check if parcellation data has been loaded

create_from_data(codes, regtable, regnames, annot_id, hemi='lh', filename=None)[source]

Create parcellation from existing data arrays

Parameters:
  • codes (array-like) – Vertex-wise region codes

  • regtable (array-like) – Region table with colors and codes

  • regnames (list) – List of region names

  • annot_id (str) – Annotation ID for the parcellation

  • hemi (str, optional) – Hemisphere (‘lh’ or ‘rh’)

  • filename (str, optional) – Associated filename

save_annotation(out_file=None, force=True)[source]

Save the annotation file. If the file already exists, it will be overwritten.

Parameters:
  • Optional (force -)

  • Optional

fill_parcellation(label_file, surf_file, corr_annot=None)[source]

Correct the parcellation by refilling vertices from the cortex label file that do not have a label in the annotation file.

This method iteratively fills unlabeled vertices (those with value -1 or 0) by assigning the most frequent label from their neighboring vertices. The algorithm focuses on boundary vertices - those at the edges of the parcellation - and continues until all vertices within the cortex have been assigned labels or no further progress can be made.

Parameters:
  • label_file (str) – Path to the cortex label file containing vertex indices that define the cortical surface. This file typically has a .label extension and is used to mask vertices to only those within the cortex.

  • surf_file (str) – Path to the surface geometry file containing vertex coordinates and face connectivity information. This is typically a FreeSurfer surface file (e.g., lh.pial, rh.white) that defines the mesh topology.

  • corr_annot (str, optional) – Path where the corrected annotation file should be saved. If None, the original annotation filename will be used. The directory will be created if it doesn’t exist. Default is None.

Returns:

  • corr_annot (str) – Path to the corrected annotation file that was saved.

  • vert_lab (numpy.ndarray) – Array of vertex labels after correction, where each element corresponds to the label assigned to that vertex index.

  • reg_ctable (numpy.ndarray) – Region color table containing RGB color values for each region in the parcellation.

  • reg_names (list) – List of region names corresponding to each label in the parcellation. May include “unknown” as the first element if unlabeled vertices were initially present.

Raises:
  • ValueError – If the surface file does not exist. Both annotation and surface files are mandatory for the parcellation correction process.

  • ValueError – If the cortex label file does not exist. The cortex label file is required to define which vertices should be considered for labeling.

Notes

The algorithm works by:

  1. Loading surface geometry and cortex label information

  2. Identifying vertices with missing labels (value -1, converted to 0)

  3. Finding boundary faces that contain both labeled and unlabeled vertices

  4. Iteratively assigning labels to unlabeled boundary vertices based on the most frequent label among their neighbors

  5. Repeating until no more vertices can be labeled or all vertices are filled

The method modifies the internal state of the annotation object and optionally saves the result to a file.

Examples

Basic usage with an annotation object:

>>> # Assuming 'annot' is an annotation object
>>> label_file = '/path/to/lh.cortex.label'
>>> surf_file = '/path/to/lh.pial'
>>> output_file = '/path/to/lh.corrected.annot'
>>>
>>> corrected_path, labels, ctable, names = annot.fill_parcellation(
...     label_file=label_file,
...     surf_file=surf_file,
...     corr_annot=output_file
... )
>>>
>>> print(f"Corrected annotation saved to: {corrected_path}")
>>> print(f"Number of regions: {len(names)}")

Usage without specifying output file (uses original filename):

>>> corrected_path, labels, ctable, names = annot.fill_parcellation(
...     label_file=label_file,
...     surf_file=surf_file
... )

See also

nibabel.freesurfer.read_geometry

For reading surface files

nibabel.freesurfer.read_label

For reading label files

save_annotation

For saving annotation files

export_to_tsv(prefix2add=None, reg_offset=1000, tsv_file=None)[source]

Export the parcellation table to a TSV file containing region information.

Creates a comprehensive table with region indices, annotation IDs, parcellation IDs, names, and hexadecimal color codes. This is useful for creating lookup tables, documentation, or interfacing with other neuroimaging tools that require parcellation metadata in tabular format.

Parameters:
  • prefix2add (str, optional) – Prefix string to prepend to all region names. This is useful for distinguishing regions from different hemispheres (e.g., ‘lh_’ or ‘rh_’) or different atlases. If None, original region names are preserved. Default is None.

  • reg_offset (int, optional) – Integer offset to add to the parcellation IDs. This helps avoid ID conflicts when combining multiple parcellations or when specific ID ranges are required. The offset is added to sequential indices starting from 0. Default is 1000.

  • tsv_file (str, optional) – Path where the TSV file should be saved. If provided, the DataFrame will be written to this file with tab separation. The parent directory will be created if it doesn’t exist. If None, no file is saved and only the DataFrame is returned. Default is None.

Returns:

  • tsv_df (pandas.DataFrame) – DataFrame containing the parcellation table with the following columns:

    • ’index’: Sequential indices starting from 0 for each region

    • ’annotid’: Original annotation IDs from the FreeSurfer annotation file

    • ’parcid’: Parcellation IDs (index + reg_offset)

    • ’name’: Region names, optionally prefixed

    • ’color’: Hexadecimal color codes (e.g., ‘#FF0000’ for red)

  • tsv_file (str) – Path to the saved TSV file if tsv_file parameter was provided, otherwise returns the input tsv_file parameter (which may be None).

Raises:

PermissionError – If the specified directory for the TSV file cannot be created due to insufficient write permissions. The method will print an error message and exit the program.

Notes

The method processes the internal parcellation data as follows:

1. Converts RGB color values to hexadecimal format using the first 3 columns of the region table 2. Applies optional prefix to region names using a name correction function 3. Creates sequential indices and applies the specified offset to parcellation IDs 4. Combines all information into a structured DataFrame 5. Optionally saves to TSV format with tab separation and no row indices

The annotation IDs correspond to the original FreeSurfer annotation values, while parcellation IDs provide a more standardized numbering scheme.

Examples

Basic usage - return DataFrame only:

>>> # Assuming 'annot' is an annotation object
>>> df, filename = annot.export_to_tsv()
>>> print(df.head())
    index  annotid  parcid           name     color
0        0     1234    1000    unknown   #000000
1        1     5678    1001    precentral #FF0000
2        2     9012    1002    postcentral #00FF00

Add prefix to region names:

>>> df, filename = annot.export_to_tsv(prefix2add='lh_')
>>> print(df['name'].head())
0        lh_unknown
1        lh_precentral
2        lh_postcentral

Save to file with custom offset:

>>> output_file = '/path/to/parcellation_table.tsv'
>>> df, saved_path = annot.export_to_tsv(
...     prefix2add='rh_',
...     reg_offset=2000,
...     tsv_file=output_file
... )
>>> print(f"Table saved to: {saved_path}")
>>> print(f"Parcellation IDs range: {df['parcid'].min()}-{df['parcid'].max()}")

Create hemisphere-specific tables:

>>> # Left hemisphere
>>> lh_df, lh_file = lh_annot.export_to_tsv(
...     prefix2add='lh_',
...     reg_offset=1000,
...     tsv_file='lh_parcellation.tsv'
... )
>>>
>>> # Right hemisphere
>>> rh_df, rh_file = rh_annot.export_to_tsv(
...     prefix2add='rh_',
...     reg_offset=2000,
...     tsv_file='rh_parcellation.tsv'
... )
>>>
>>> # Combine both hemispheres
>>> combined_df = pd.concat([lh_df, rh_df], ignore_index=True)

See also

pandas.DataFrame.to_csv

For saving DataFrames in various formats

cltcol.multi_rgb2hex

For converting RGB values to hexadecimal

cltcol.correct_names

For applying prefixes to region names

map_values(regional_values, is_dataframe=False)[source]

Map regional values to vertex-wise values using the parcellation codes and region table.

This method transforms region-level data (e.g., statistical measures, anatomical properties, or functional metrics computed per brain region) into vertex-level data for surface visualization. Each vertex is assigned the value corresponding to its parcellation region, enabling surface-based visualization of regional data.

Parameters:
  • regional_values (str or pandas.DataFrame or numpy.ndarray) –

    Regional values to map to vertices. Can be provided in three formats:

    • str: Path to a text/CSV file containing regional values. The file

    should have one row per region matching the parcellation. Single column files are read as arrays, while multi-column CSV files can optionally be read with headers when is_dataframe=True.

    • pandas.DataFrame: DataFrame with one row per region and columns

    representing different measures. Must have numeric values and column names. The number of rows must match the number of regions in the parcellation.

    • numpy.ndarray: Array with shape (n_regions, n_measures) where

    n_regions matches the number of regions in the parcellation. Can be 1D for single measures or 2D for multiple measures.

  • is_dataframe (bool, optional) – Whether to read text files as DataFrames with column headers. Only applies when regional_values is a file path (str). If True, the first row is treated as column names and preserved in the output. If False, the file is read without headers. Default is False.

Returns:

vertex_wise_values – Vertex-wise values mapped from the regional values. The output format depends on the input:

  • numpy.ndarray: Returned when input is a numpy array or a file

read without headers (is_dataframe=False). Shape is (n_vertices,) for single measures or (n_vertices, n_measures) for multiple measures.

  • pandas.DataFrame: Returned when input is a DataFrame or a file

read with headers (is_dataframe=True). Has one row per vertex and preserves original column names.

Return type:

numpy.ndarray or pandas.DataFrame

Raises:
  • ValueError – If the regional values file does not exist (when input is a file path).

  • ValueError – If the number of rows in regional_values does not match the number of regions in the parcellation. This ensures proper mapping between regions and values.

  • ValueError – If the DataFrame contains non-numeric values. All regional values must be numeric for proper mapping to vertices.

  • ValueError – If regional_values is not one of the supported types (str, DataFrame, or ndarray).

Notes

The mapping process works as follows:

1. Input validation: Checks that the input format is supported and that dimensions match the parcellation structure.

2. Format standardization: Converts all input types to numpy arrays while preserving column information when applicable.

3. Vertex assignment: Uses the internal region_to_vertexwise function to assign each vertex the value from its corresponding region based on the parcellation codes.

4. Output formatting: Returns data in the same structural format as the input (array vs DataFrame) to maintain consistency.

The parcellation codes (self.codes) define which region each vertex belongs to, and the region table (self.regtable) provides the mapping structure. Vertices with undefined regions (typically background or unknown areas) may receive special handling depending on the implementation of region_to_vertexwise.

Examples

Map single measure from numpy array:

>>> import numpy as np
>>> # Regional thickness values for each region
>>> thickness_values = np.array([2.5, 3.1, 2.8, 3.2, 2.9])  # 5 regions
>>> vertex_values = annot.map_values(thickness_values)
>>> print(f"Mapped {len(vertex_values)} vertices")
>>> print(f"Value range: {vertex_values.min():.2f} - {vertex_values.max():.2f}")

Map multiple measures from DataFrame:

>>> import pandas as pd
>>> # Multiple regional measures
>>> regional_data = pd.DataFrame({
...     'thickness': [2.5, 3.1, 2.8, 3.2, 2.9],
...     'volume': [1200, 1500, 1100, 1400, 1300],
...     'surface_area': [850, 920, 780, 900, 840]
... })
>>> vertex_df = annot.map_values(regional_data)
>>> print(f"Output columns: {list(vertex_df.columns)}")
>>> print(f"Vertex data shape: {vertex_df.shape}")

Read from CSV file without headers:

>>> # File contains single column of regional values
>>> vertex_values = annot.map_values('regional_thickness.txt')
>>> print(f"Mapped values type: {type(vertex_values)}")

Read from CSV file with headers:

>>> # File contains multiple columns with headers
>>> vertex_df = annot.map_values(
...     'regional_measures.csv',
...     is_dataframe=True
... )
>>> print(f"Preserved columns: {list(vertex_df.columns)}")

Typical neuroimaging workflow:

>>> # Load regional statistics from analysis
>>> regional_stats = pd.read_csv('region_statistics.csv')
>>>
>>> # Map to surface for visualization
>>> surface_data = annot.map_values(regional_stats)
>>>
>>> # Save for visualization software
>>> if isinstance(surface_data, pd.DataFrame):
...     surface_data.to_csv('surface_values.csv', index=False)
... else:
...     np.savetxt('surface_values.txt', surface_data)

Error handling example:

>>> try:
...     # This will fail if dimensions don't match
...     wrong_size = np.array([1, 2, 3])  # Only 3 values for 5 regions
...     vertex_values = annot.map_values(wrong_size)
... except ValueError as e:
...     print(f"Dimension mismatch: {e}")

See also

region_to_vertexwise

Underlying function that performs the mapping

pandas.read_csv

For reading CSV files with various options

numpy.loadtxt

Alternative for reading simple numeric files

static gii2annot(gii_file, ref_surf=None, annot_file=None, cont_tech='local', cont_image=None)[source]

Convert FreeSurfer GIFTI parcellation files to annotation files using mris_convert.

This method converts GIFTI label files (commonly used in neuroimaging pipelines like HCP, fMRIPrep) to FreeSurfer’s native annotation format. The conversion enables use of external parcellations within FreeSurfer’s ecosystem and visualization tools.

Parameters:
  • gii_file (str) – Path to the input GIFTI label file (.gii). The file should contain parcellation labels corresponding to surface vertices. The hemisphere is automatically detected from the filename.

  • ref_surf (str, optional) – Path to the reference surface file used for the conversion. This surface should match the geometric space of the GIFTI file. If None, defaults to the white surface of the fsaverage subject from FREESURFER_HOME. Default is None.

  • annot_file (str, optional) – Path for the output annotation file. If None, the output file is created in the same directory as the input file with the extension changed from .gii to .annot. Default is None.

  • cont_tech (str, optional) – Container technology for running FreeSurfer commands. Options include ‘local’ (run directly), ‘singularity’, ‘docker’, or other supported containerization methods. Default is ‘local’.

  • cont_image (str, optional) – Container image specification when using containerized execution. Required when cont_tech is not ‘local’. Should specify the FreeSurfer container image (e.g., ‘freesurfer/freesurfer:7.2.0’). Default is None.

Returns:

annot_file – Path to the created annotation file.

Return type:

str

Raises:
  • ValueError – If the input GIFTI file does not exist.

  • ValueError – If FREESURFER_HOME environment variable is not set and no reference surface is provided.

  • ValueError – If the provided reference surface file does not exist.

Notes

This method uses FreeSurfer’s mris_convert command with the –annot flag to perform the conversion. The command structure is:

mris_convert --annot input.gii reference_surface.surf output.annot

The reference surface is crucial for proper conversion as it defines the vertex correspondence between the GIFTI labels and the annotation format. The method automatically detects the hemisphere from the GIFTI filename and selects the appropriate reference surface.

Container execution allows running FreeSurfer tools without a local installation, which is useful in cloud environments or when FreeSurfer is not available locally.

Examples

Basic conversion with automatic reference surface:

>>> # Convert HCP-style parcellation to FreeSurfer format
>>> gii_file = '/path/to/lh.Schaefer2018_400Parcels.label.gii'
>>> annot_file = AnnotParcellation.gii2annot(gii_file)
>>> print(f"Created annotation: {annot_file}")

Specify custom reference surface:

>>> # Use subject-specific surface for conversion
>>> gii_file = '/path/to/rh.custom_parcellation.gii'
>>> ref_surf = '/path/to/subject/surf/rh.pial'
>>> output_file = '/path/to/output/rh.custom.annot'
>>>
>>> result = AnnotParcellation.gii2annot(
...     gii_file=gii_file,
...     ref_surf=ref_surf,
...     annot_file=output_file
... )

Using Docker container:

>>> # Run conversion in FreeSurfer Docker container
>>> annot_file = AnnotParcellation.gii2annot(
...     gii_file='parcellation.gii',
...     cont_tech='docker',
...     cont_image='freesurfer/freesurfer:7.2.0'
... )

See also

annot2gii

Convert annotation files to GIFTI format

mris_convert

FreeSurfer command-line tool for surface file conversion

static annot2gii(annot_file, ref_surf=None, gii_file=None, cont_tech='local', cont_image=None)[source]

Convert FreeSurfer annotation files to GIFTI format using mris_convert.

This method converts FreeSurfer’s native annotation format to GIFTI label files, enabling use of FreeSurfer parcellations in other neuroimaging software and analysis pipelines that support GIFTI format (e.g., Connectome Workbench, CIFTI-based analyses).

Parameters:
  • annot_file (str) – Path to the input FreeSurfer annotation file (.annot). This file contains the parcellation labels and associated color/name information in FreeSurfer’s binary format.

  • ref_surf (str, optional) – Path to the reference surface file that corresponds to the annotation. This surface defines the vertex coordinates and topology. If None, defaults to the white surface of the fsaverage subject from FREESURFER_HOME. Default is None.

  • gii_file (str, optional) – Path for the output GIFTI file. If None, the output file is created in the same directory as the input file with the extension changed from .annot to .gii. Default is None.

  • cont_tech (str, optional) – Container technology for running FreeSurfer commands. Options include ‘local’ (run directly), ‘singularity’, ‘docker’, or other supported containerization methods. Default is ‘local’.

  • cont_image (str, optional) – Container image specification when using containerized execution. Required when cont_tech is not ‘local’. Should specify the FreeSurfer container image (e.g., ‘freesurfer/freesurfer:7.2.0’). Default is None.

Returns:

gii_file – Path to the created GIFTI file.

Return type:

str

Raises:
  • ValueError – If the input annotation file does not exist.

  • ValueError – If FREESURFER_HOME environment variable is not set and no reference surface is provided.

  • ValueError – If the provided reference surface file does not exist.

Notes

This method uses FreeSurfer’s mris_convert command with the –annot flag to perform the conversion. The command structure is:

mris_convert --annot input.annot reference_surface.surf output.gii

The GIFTI format is more widely supported across neuroimaging software packages and is part of the CIFTI specification used in large-scale neuroimaging projects. The conversion preserves the parcellation labels but may not retain all FreeSurfer-specific metadata.

The hemisphere is automatically detected from the annotation filename to select the appropriate reference surface when using the default fsaverage surfaces.

Examples

Basic conversion with automatic reference surface:

>>> # Convert FreeSurfer parcellation to GIFTI format
>>> annot_file = '/path/to/lh.aparc.annot'
>>> gii_file = AnnotParcellation.annot2gii(annot_file)
>>> print(f"Created GIFTI: {gii_file}")

Specify custom output location:

>>> # Convert with custom output path
>>> annot_file = '/path/to/rh.Destrieux.annot'
>>> output_file = '/output/rh.Destrieux.label.gii'
>>>
>>> result = AnnotParcellation.annot2gii(
...     annot_file=annot_file,
...     gii_file=output_file
... )

Using subject-specific surface:

>>> # Use individual subject's surface
>>> annot_file = '/subjects/sub001/label/lh.aparc.a2009s.annot'
>>> ref_surf = '/subjects/sub001/surf/lh.white'
>>>
>>> gii_file = AnnotParcellation.annot2gii(
...     annot_file=annot_file,
...     ref_surf=ref_surf
... )

Using Singularity container:

>>> # Run conversion in Singularity container
>>> gii_file = AnnotParcellation.annot2gii(
...     annot_file='parcellation.annot',
...     cont_tech='singularity',
...     cont_image='/path/to/freesurfer.sif'
... )

See also

gii2annot

Convert GIFTI files to annotation format

mris_convert

FreeSurfer command-line tool for surface file conversion

static gcs2annot(gcs_file, annot_file=None, freesurfer_dir=None, ref_id='fsaverage', cont_tech='local', cont_image=None)[source]

Convert FreeSurfer GCS (Gaussian Classifier Surface) files to annotation files.

This method applies a trained GCS classifier to generate subject-specific parcellations. GCS files contain statistical models trained on manual parcellations that can be applied to new subjects to automatically generate anatomically consistent region labels.

Parameters:
  • gcs_file (str) – Path to the input GCS classifier file. These files contain trained Gaussian classifiers for automatic parcellation (e.g., aparc.gcs, aparc.a2009s.gcs). The hemisphere is automatically detected from the filename.

  • annot_file (str, optional) – Path for the output annotation file. If None, the output file is created in the same directory as the GCS file with the extension changed from .gcs to .annot. Default is None.

  • freesurfer_dir (str, optional) – Path to the FreeSurfer subjects directory containing the reference subject data. If None, uses the SUBJECTS_DIR environment variable. The directory will be created if it doesn’t exist. Default is None.

  • ref_id (str, optional) – Subject ID of the reference subject containing the surface files needed for classification (sphere.reg, cortex.label, aseg.mgz). Typically ‘fsaverage’ for standard space analysis. Default is ‘fsaverage’.

  • cont_tech (str, optional) – Container technology for running FreeSurfer commands. Options include ‘local’ (run directly), ‘singularity’, ‘docker’, or other supported containerization methods. Default is ‘local’.

  • cont_image (str, optional) – Container image specification when using containerized execution. Required when cont_tech is not ‘local’. Should specify the FreeSurfer container image (e.g., ‘freesurfer/freesurfer:7.2.0’). Default is None.

Returns:

annot_file – Path to the created annotation file containing the classified parcellation labels.

Return type:

str

Raises:
  • ValueError – If the input GCS file does not exist.

  • ValueError – If neither freesurfer_dir is provided nor SUBJECTS_DIR environment variable is set, and FREESURFER_HOME is also not available.

Notes

This method uses FreeSurfer’s mris_ca_label command to apply the GCS classifier. The command structure is:

mris_ca_label -l cortex.label -aseg aseg.mgz subject_id hemisphere \
            sphere.reg classifier.gcs output.annot

The classification process requires several FreeSurfer files from the reference subject:

  • cortex.label: Defines the cortical vertices to be labeled

  • aseg.mgz: Volumetric segmentation for spatial context

  • sphere.reg: Spherical surface registration for spatial normalization

The method automatically manages the FreeSurfer environment by setting the SUBJECTS_DIR variable and ensuring the necessary directory structure exists. The hemisphere is detected from the GCS filename.

GCS-based parcellation is particularly useful for:

  • Applying consistent parcellation schemes across subjects

  • Automated processing pipelines

  • Reproducing published parcellation protocols

  • Cross-study standardization

Examples

Basic GCS application with default settings:

>>> # Apply Desikan-Killiany parcellation
>>> gcs_file = '/path/to/lh.aparc.gcs'
>>> annot_file = AnnotParcellation.gcs2annot(gcs_file)
>>> print(f"Created parcellation: {annot_file}")

Specify custom FreeSurfer directory:

>>> # Use custom subjects directory
>>> gcs_file = '/atlases/rh.aparc.a2009s.gcs'
>>> fs_dir = '/data/freesurfer_subjects'
>>>
>>> result = AnnotParcellation.gcs2annot(
...     gcs_file=gcs_file,
...     freesurfer_dir=fs_dir,
...     ref_id='fsaverage'
... )

Apply to individual subject space:

>>> # Use subject-specific reference
>>> gcs_file = '/atlases/lh.aparc.gcs'
>>> output_file = '/subjects/sub001/label/lh.aparc.annot'
>>>
>>> annot_file = AnnotParcellation.gcs2annot(
...     gcs_file=gcs_file,
...     annot_file=output_file,
...     ref_id='sub001'  # Use subject's own surfaces
... )

Using Docker for processing:

>>> # Run classification in container
>>> result = AnnotParcellation.gcs2annot(
...     gcs_file='parcellation.gcs',
...     freesurfer_dir='/data/subjects',
...     cont_tech='docker',
...     cont_image='freesurfer/freesurfer:7.2.0'
... )

Batch processing multiple GCS files:

>>> import glob
>>> gcs_files = glob.glob('/atlases/*.gcs')
>>>
>>> for gcs_file in gcs_files:
...     output_dir = '/parcellations'
...     basename = os.path.basename(gcs_file).replace('.gcs', '.annot')
...     output_file = os.path.join(output_dir, basename)
...
...     AnnotParcellation.gcs2annot(
...         gcs_file=gcs_file,
...         annot_file=output_file,
...         freesurfer_dir='/data/freesurfer'
...     )

See also

mris_ca_label

FreeSurfer command for applying GCS classifiers

gii2annot

Convert GIFTI parcellations to annotation format

annot2gii

Convert annotations to GIFTI format

annot2tsv(tsv_file=None)[source]

Save the annotation colort able a tab-separated values (TSV) file.

This method exports the region-wise parcellation labels to a simple text format that can be easily read by other software packages or analysis scripts. Each line contains the label ID for the corresponding region.

Parameters:

tsv_file (str, optional) – Path for the output TSV file. If None, the file is saved in the same directory as the annotation file with the extension changed from .annot to .tsv. The directory will be created if it doesn’t exist. Default is None.

Returns:

tsv_file – Path to the created TSV file.

Return type:

str

Notes

The output TSV file contains one integer per line, where each line corresponds to a region index and the value represents the parcellation label assigned to that vertices of that region.

This simple format is useful for:

  • Importing labels into custom analysis scripts

  • Interfacing with non-FreeSurfer neuroimaging software

  • Creating lightweight label files for data sharing

  • Debugging and manual inspection of parcellation assignments

The method uses tab separation and integer formatting to ensure compatibility across different systems and software packages.

Examples

Save to default location:

>>> # Annotation file: /data/lh.aparc.annot
>>> # Output will be: /data/lh.aparc.tsv
>>> tsv_path = AnnotParcellation.annot2tsv()
>>> print(f"Labels saved to: {tsv_path}")

Specify custom output path:

>>> # Save to specific location
>>> output_file = '/analysis/vertex_labels.tsv'
>>> tsv_path = AnnotParcellation.annot2tsv(tsv_file=output_file)
>>>
>>> # Verify the output
>>> import numpy as np
>>> labels = np.loadtxt(tsv_path, dtype=int)
>>> print(f"Loaded {len(labels)} vertex labels")
>>> print(f"Unique labels: {np.unique(labels)}")

Use in analysis pipeline:

>>> # Convert annotation to TSV for external analysis
>>> tsv_file = AnnotParcellation.annot2tsv()
>>>
>>> # Read in external software (e.g., R, MATLAB)
>>> # R: labels <- read.table(tsv_file, header=FALSE)
>>> # MATLAB: labels = readtable(tsv_file);

Batch processing multiple annotations:

>>> import glob
>>> annot_files = glob.glob('/subjects/*/label/*.annot')
>>>
>>> for annot_file in annot_files:
...     annot = AnnotParcellation(annot_file)
...     tsv_path = AnnotParcellation.annot2tsv()
...     print(f"Converted: {annot_file} -> {tsv_path}")

See also

numpy.savetxt

Function used internally for saving arrays

export_to_tsv

Export comprehensive parcellation table with metadata

annot2gcs(gcs_file=None, freesurfer_dir=None, fssubj_id=None, hemi=None, cont_tech='local', cont_image=None)[source]

Convert FreeSurfer annotation files to GCS (Gaussian Classifier Surface) files.

This method creates a trained Gaussian classifier from an existing manual or semi-manual parcellation. The resulting GCS file can be applied to new subjects to automatically generate parcellations with the same regional definitions and boundaries as the training annotation.

Parameters:
  • gcs_file (str, optional) – Path for the output GCS classifier file. If None, the file is saved in the same directory as the annotation file with the extension changed from .annot to .gcs. Default is None.

  • freesurfer_dir (str, optional) – Path to the FreeSurfer subjects directory containing the training subject data. If None, uses the SUBJECTS_DIR environment variable. The directory will be created if it doesn’t exist. Default is None.

  • fssubj_id (str, required) – Subject ID of the FreeSurfer subject to use for training the classifier. This subject must have the required surface files (sphere.reg) and should be the same subject from which the annotation was derived. No default value - must be provided.

  • hemi (str, optional) – Hemisphere specification (‘lh’ or ‘rh’). If None, the hemisphere is automatically detected from the annotation filename. Default is None.

  • cont_tech (str, optional) – Container technology for running FreeSurfer commands. Options include ‘local’ (run directly), ‘singularity’, ‘docker’, or other supported containerization methods. Default is ‘local’.

  • cont_image (str, optional) – Container image specification when using containerized execution. Required when cont_tech is not ‘local’. Should specify the FreeSurfer container image (e.g., ‘freesurfer/freesurfer:7.2.0’). Default is None.

Returns:

gcs_name – Filename (not full path) of the created GCS classifier file.

Return type:

str

Raises:
  • ValueError – If SUBJECTS_DIR environment variable is not set and freesurfer_dir is not provided.

  • ValueError – If fssubj_id is not provided (required parameter).

  • ValueError – If the FreeSurfer subject directory does not exist.

  • ValueError – If the required sphere.reg file is not found in the subject directory.

  • ValueError – If the hemisphere cannot be determined from the filename and is not provided as a parameter.

Notes

This method uses FreeSurfer’s mris_ca_train command to create the GCS classifier. The process involves:

1. Color table creation: Generates a temporary .ctab file with region names and RGB color values from the annotation.

2. Classifier training: Uses spherical surface registration and the annotation labels to train Gaussian classifiers for each region.

3. Model output: Creates a .gcs file containing the trained statistical models that can be applied to new subjects.

The command structure is:

mris_ca_train -n 2 -t color_table.ctab hemisphere sphere.reg \
            annotation.annot subject_id output.gcs

Required FreeSurfer files for the training subject:

  • sphere.reg: Spherical surface registration for spatial normalization

  • Proper directory structure: Standard FreeSurfer subject organization

The resulting GCS file can be used with the gcs2annot method to apply the same parcellation scheme to new subjects automatically.

Examples

Basic GCS creation with required subject ID:

>>> # Train classifier from manual parcellation
>>> annot = Annotation('/data/sub001/label/lh.manual.annot')
>>> gcs_name = AnnotParcellation.annot2gcs(fssubj_id='sub001')
>>> print(f"Created classifier: {gcs_name}")

Specify custom output location:

>>> # Save GCS file to specific location
>>> output_file = '/atlases/custom_parcellation.gcs'
>>> gcs_name = AnnotParcellation.annot2gcs(
...     gcs_file=output_file,
...     fssubj_id='fsaverage',
...     freesurfer_dir='/data/freesurfer'
... )

Create classifier from template subject:

>>> # Use fsaverage as training template
>>> annot = Annotation('/templates/fsaverage/label/rh.custom.annot')
>>> gcs_name = AnnotParcellation.annot2gcs(
...     fssubj_id='fsaverage',
...     hemi='rh',
...     freesurfer_dir='/usr/local/freesurfer/subjects'
... )

Using Docker for training:

>>> # Train classifier in container environment
>>> gcs_name = AnnotParcellation.annot2gcs(
...     fssubj_id='training_subject',
...     cont_tech='docker',
...     cont_image='freesurfer/freesurfer:7.2.0'
... )

Complete workflow - train and apply:

>>> # Step 1: Create GCS from manual annotation
>>> manual_annot = AnnotParcellation('/manual/lh.expert_labels.annot')
>>> gcs_file = '/classifiers/expert_parcellation.gcs'
>>>
>>> gcs_name = manual_annot.annot2gcs(
...     gcs_file=gcs_file,
...     fssubj_id='template_subject'
... )
>>>
>>> # Step 2: Apply to new subjects
>>> for subject in ['sub002', 'sub003', 'sub004']:
...     output_annot = f'/results/{subject}/lh.expert_auto.annot'
...     AnnotParcellation.gcs2annot(
...         gcs_file=gcs_file,
...         annot_file=output_annot,
...         ref_id=subject
...     )

Quality control after training:

>>> # Verify the trained classifier works
>>> test_output = '/tmp/test_application.annot'
>>> AnnotParcellation.gcs2annot(
...     gcs_file='/atlases/new_classifier.gcs',
...     annot_file=test_output,
...     ref_id='fsaverage'
... )
>>>
>>> # Compare with original
>>> original = AnnotParcellation('/original/annotation.annot')
>>> test_result = AnnotParcellation(test_output)
>>> # Implement comparison logic...

See also

gcs2annot

Apply GCS classifiers to generate annotations

mris_ca_train

FreeSurfer command for training surface classifiers

export_to_tsv

Export parcellation metadata for analysis

group_into_lobes(grouping='desikan', lobes_json=None, out_annot=None, ctxprefix=None, force=False)[source]

Group parcellation regions into anatomical lobes for coarser-grained analysis.

This method combines fine-grained brain regions into larger anatomical units (lobes) based on predefined or custom grouping schemes. This is useful for reducing dimensionality in analyses, creating simplified visualizations, or studying brain function at the lobar level.

Parameters:
  • grouping (str, optional) – Grouping method or scheme name to use for lobar organization. Built-in options include ‘desikan’ for Desikan-Killiany atlas grouping. Custom groupings can be specified when providing a lobes_json file. Default is ‘desikan’.

  • lobes_json (str, optional) –

    Path to a JSON file containing custom lobe definitions and region mappings. If None, uses the default grouping scheme called lobes.json. This file is located in the clabtoolkit package directory (e.g., clabtoolkit/config/lobes.json).

    Default is None.

  • out_annot (str, optional) – Path where the new lobar annotation file should be saved. If None, the parcellation is only returned as an object without saving to disk. The output directory will be created if it doesn’t exist. Default is None.

  • ctxprefix (str, optional) – Prefix string to prepend to the lobe names. This is useful for distinguishing between hemispheres (e.g., ‘lh_’ or ‘rh_’) or different analysis contexts. If None, no prefix is added. Default is None.

  • force (bool, optional) – Whether to overwrite existing output files. If False and the output file already exists, an error will be raised. If True, existing files will be overwritten without warning. Default is False.

Returns:

lobar_parcellation – New AnnotParcellation object containing the lobar parcellation where original regions have been grouped into larger anatomical units. The object contains updated region names, codes, and color tables corresponding to the lobes.

Return type:

AnnotParcellation

Raises:
  • FileExistsError – If the output annotation file already exists and force=False.

  • FileNotFoundError – If the specified lobes_json file does not exist.

  • ValueError – If the JSON file format is invalid or missing required keys.

  • KeyError – If regions specified in the JSON file are not found in the current parcellation.

Notes

The grouping process works as follows:

1. Region mapping: Original parcellation regions are mapped to their corresponding lobes based on the grouping scheme.

2. Label reassignment: Vertex labels are updated to reflect the new lobar assignments rather than fine-grained regional assignments.

3. Color assignment: New color table is created for the lobes, either from the JSON file specification or using default colors.

4. Metadata update: Region names and identifiers are updated to reflect the lobar structure.

The method is particularly useful for:

  • Simplifying complex parcellations for visualization

  • Reducing multiple comparisons in statistical analyses

  • Creating anatomically meaningful ROI groups

  • Cross-study comparisons at the lobar level

  • Educational and clinical applications

Examples

Basic lobar grouping with default scheme:

>>> # Group Desikan-Killiany regions into standard lobes
>>> lobar_parc = parc.group_into_lobes(grouping='desikan')
>>> print(f"Original regions: {len(parc.regnames)}")
>>> print(f"Lobar regions: {len(lobar_parc.regnames)}")
>>> print(f"Lobe names: {lobar_parc.regnames}")

Save lobar parcellation to file:

>>> # Create and save lobar parcellation
>>> output_file = '/results/lh.desikan_lobes.annot'
>>> lobar_parc = parc.group_into_lobes(
...     grouping='desikan',
...     out_annot=output_file
... )
>>> print(f"Lobar parcellation saved to: {output_file}")

Use custom JSON grouping file:

>>> # Create custom lobe definitions
>>> custom_json = '/configs/custom_lobes.json'
>>> lobar_parc = parc.group_into_lobes(
...     grouping='mylobes',
...     lobes_json=custom_json
... )

Force overwrite existing files:

>>> # Overwrite existing lobar parcellation
>>> lobar_parc = parc.group_into_lobes(
...     grouping='desikan',
...     out_annot='/existing/file.annot',
...     force=True
... )

See also

export_to_tsv

Export parcellation tables for external analysis

map_values

Map regional values to surface vertices

AnnotParcellation

Main class for parcellation handling

class clabtoolkit.freesurfertools.FreeSurferSubject(subj_id, subjs_dir=None)[source]

Bases: object

A comprehensive class for managing and analyzing FreeSurfer subject data.

This class provides methods to work with FreeSurfer subjects, including initialization of file structures, processing status checking, launching FreeSurfer commands, and extracting morphometric statistics.

__init__(subj_id, subjs_dir=None)[source]

Initialize the FreeSurferSubject object with subject ID and subjects directory.

Creates organized dictionaries containing paths to all standard FreeSurfer outputs including MRI volumes, surface files, parcellations, and statistics.

Parameters:
  • subj_id (str) – FreeSurfer subject identifier matching the directory name in the FreeSurfer subjects directory.

  • subjs_dir (str, optional) – Path to the FreeSurfer subjects directory. If None, uses the SUBJECTS_DIR environment variable. Directory will be created if it doesn’t exist. Default is None.

subj_id

The subject identifier.

Type:

str

subjs_dir

Path to the FreeSurfer subjects directory.

Type:

str

fs_files

Nested dictionary containing organized paths to all FreeSurfer files organized by data type (mri, surf, stats) and hemisphere.

Type:

dict

Examples

>>> subject = FreeSurferSubject('sub-001')
>>> print(subject.fs_files['mri']['T1'])
>>> lh_thickness = subject.fs_files['surf']['lh']['map']['thickness']
get_hemi_dicts(subj_dir, hemi)[source]

Create organized dictionaries containing hemisphere-specific FreeSurfer file paths.

Helper method that constructs structured dictionaries for surface meshes, morphometric maps, parcellations, and statistics files for a specified hemisphere.

Parameters:
  • subj_dir (str) – Path to the FreeSurfer subject directory.

  • hemi (str) – Hemisphere identifier (‘lh’ or ‘rh’).

Returns:

  • s_dict (dict) – Surface mesh file paths (pial, white, inflated, sphere). Empty string if not found.

  • m_dict (dict) – Morphometric map file paths (curv, sulc, thickness, area, volume, lgi). Empty string if not found.

  • p_dict (dict) – Parcellation annotation file paths (desikan, destrieux, dkt). Empty string if not found.

  • t_dict (dict) – Statistics file paths for each parcellation and curvature. Empty string if not found.

Examples

>>> surf, maps, parc, stats = subject.get_hemi_dicts(subj_dir, 'lh')
>>> print(surf['pial'])
get_proc_status()[source]

Check the FreeSurfer processing status for this subject.

Evaluates which FreeSurfer processing stages have been completed by checking for the existence of key output files. Handles missing pial surface files by copying from pial.T1 files when needed.

Attributes Set

pstatusstr

Processing status: ‘unprocessed’, ‘autorecon1’, ‘autorecon2’, or ‘processed’.

Notes

  • ‘unprocessed’: No processing done

  • ‘autorecon1’: Basic preprocessing completed

  • ‘autorecon2’: Surface reconstruction completed

  • ‘processed’: Full processing including parcellation completed

Examples

>>> subject.get_proc_status()
>>> print(f"Status: {subject.pstatus}")
>>> if subject.pstatus == 'processed':
...     print("Ready for analysis")
get_cras()[source]

Extract the CRAS (Center of Rotation in AC-PC Space) coordinates from the Talairach transform file. Reads the Talairach transform file (talairach.lta) to extract the CRAS coordinates, which represent the center of rotation in the AC-PC aligned space. These coordinates are essential for accurate spatial normalization and alignment of brain images.

Parameters:

None

Returns:

cras – A tuple containing the CRAS coordinates (x, y, z) in millimeters.

Return type:

tuple

Raises:

ValueError – If the Talairach transform file does not exist.

Examples

>>> subject.get_cras()
>>> print(f"CRAS coordinates: {subject.cras}")
launch_freesurfer(t1w_img=None, proc_stage='all', extra_proc=None, cont_tech='local', cont_image=None, fs_license=None, force=False)[source]

Launch FreeSurfer recon-all processing with flexible options and containerization support.

Provides interface for running FreeSurfer’s recon-all pipeline with support for containerized execution, incremental processing, and additional modules.

Parameters:
  • t1w_img (str, optional) – Path to input T1-weighted MRI image. Required for unprocessed subjects.

  • proc_stage (str or list, optional) – Processing stage(s): ‘all’, ‘autorecon1’, ‘autorecon2’, ‘autorecon3’, or list of stages. Default is ‘all’.

  • extra_proc (str or list, optional) – Additional modules: ‘lgi’, ‘thalamus’, ‘brainstem’, ‘hippocampus’, ‘amygdala’, ‘hypothalamus’. Default is None.

  • cont_tech (str, optional) – Container technology: ‘local’, ‘docker’, ‘singularity’. Default is ‘local’.

  • cont_image (str, optional) – Container image specification when using containerization.

  • fs_license (str, optional) – Path to FreeSurfer license file for containers.

  • force (bool, optional) – Force reprocessing even if outputs exist. Default is False.

Returns:

proc_status – Updated processing status after completion.

Return type:

str

Raises:

ValueError – If invalid processing stages or missing required files.

Examples

>>> # Basic processing
>>> status = subject.launch_freesurfer(t1w_img='/data/T1w.nii.gz')
>>>
>>> # With extra modules
>>> status = subject.launch_freesurfer(
...     t1w_img='/data/T1w.nii.gz',
...     extra_proc=['lgi', 'hippocampus']
... )
>>>
>>> # Using Docker
>>> status = subject.launch_freesurfer(
...     t1w_img='/data/T1w.nii.gz',
...     cont_tech='docker',
...     cont_image='freesurfer/freesurfer:7.2.0'
... )
create_stats_table(lobes_grouping='desikan', add_bids_entities=False, output_file=None)[source]

Generate comprehensive FreeSurfer statistics table combining morphometric measurements.

Extracts and organizes cortical and volumetric measurements from FreeSurfer outputs into a structured DataFrame suitable for analysis.

Parameters:
  • lobes_grouping (str, optional) – Parcellation grouping method for lobar regions: ‘desikan’ or ‘desikan+cingulate’. Default is ‘desikan’.

  • add_bids_entities (bool, optional) – Whether to extract BIDS entities from subject ID. Default is False.

  • output_file (str, optional) – Path to save the DataFrame as CSV. If None, not saved. Default is None.

Returns:

  • pd.DataFrame – Comprehensive statistics table with surface-based and volumetric measurements across multiple parcellation schemes.

  • Attributes Set

  • ————–

  • stats_table (pd.DataFrame) – The generated statistics table stored as object attribute.

Return type:

DataFrame

Examples

>>> # Generate basic stats table
>>> stats_df = subject.create_stats_table()
>>> print(f"Generated {len(stats_df)} measurements")
>>>
>>> # Save to file with BIDS entities
>>> stats_df = subject.create_stats_table(
...     add_bids_entities=True,
...     output_file='/results/subject_stats.csv'
... )
volume_morpho(parcellations=['desikan+aseg', 'destrieux+aseg', 'dkt+aseg'], lobes_grouping='desikan')[source]

Compute volume measurements from FreeSurfer volumetric parcellations.

Extracts volumetric measurements from specified FreeSurfer parcellations and returns organized DataFrame with volume values per region.

Parameters:
  • parcellations (list, optional) – List of parcellation names to compute volumes from. Default includes Desikan-Killiany, Destrieux, and DKT atlases combined with subcortical segmentation.

  • lobes_grouping (str, optional) – Grouping method for lobar segmentation: ‘desikan’ or ‘desikan+cingulate’. Default is ‘desikan’.

Returns:

DataFrame with volume measurements organized by parcellation atlas and brain region.

Return type:

pd.DataFrame

Examples

>>> # Compute volumes for default parcellations
>>> vol_df = subject.volume_morpho()
>>> print(f"Computed volumes for {len(vol_df)} regions")
>>>
>>> # Custom parcellations
>>> vol_df = subject.volume_morpho(
...     parcellations=['desikan+aseg', 'dkt+aseg']
... )
surface_hemi_morpho(hemi='lh', lobes_grouping='desikan', verbose=False)[source]

Compute morphometric metrics for a hemisphere using cortical surface data.

Extracts morphometric properties like thickness, surface area, and curvature from cortical surfaces, maps, and parcellations for the specified hemisphere.

Parameters:
  • hemi (str, optional) – Hemisphere to process: ‘lh’ or ‘rh’. Default is ‘lh’.

  • lobes_grouping (str, optional) – Grouping method for lobar segmentation: ‘desikan’ or ‘desikan+cingulate’. Default is ‘desikan’.

  • verbose (bool, optional) – Whether to print processing progress. Default is False.

Returns:

DataFrame with morphometric measurements including thickness, area, curvature, and Euler characteristics organized by parcellation and region.

Return type:

pd.DataFrame

Examples

>>> # Process left hemisphere
>>> lh_df = subject.surface_hemi_morpho(hemi='lh')
>>> print(f"Extracted {len(lh_df)} morphometric measurements")
>>>
>>> # Process with verbose output
>>> rh_df = subject.surface_hemi_morpho(
...     hemi='rh',
...     verbose=True
... )
static set_freesurfer_directory(fs_dir=None)[source]

Set up the FreeSurfer subjects directory and configure environment variables.

Creates the FreeSurfer directory if it doesn’t exist and sets the SUBJECTS_DIR environment variable. Used to ensure proper FreeSurfer environment setup.

Parameters:

fs_dir (str, optional) – Path to FreeSurfer subjects directory. If None, extracts from SUBJECTS_DIR environment variable. Directory will be created if it doesn’t exist. Default is None.

Returns:

The directory path is set in the SUBJECTS_DIR environment variable.

Return type:

None

Raises:

ValueError – If fs_dir is None and SUBJECTS_DIR environment variable is not set.

Examples

>>> # Use environment variable
>>> FreeSurferSubject.set_freesurfer_directory()
>>>
>>> # Set custom directory
>>> FreeSurferSubject.set_freesurfer_directory('/data/freesurfer')
>>> print(os.environ['SUBJECTS_DIR'])
annot2ind(ref_id, hemi, fs_annot, ind_annot, cont_tech='local', cont_image=None, force=False, verbose=False)[source]

Map annotation parcellation from reference space to individual subject space.

Uses FreeSurfer’s mri_surf2surf to transfer parcellation labels from a reference subject to the individual subject’s surface, followed by gap-filling to ensure complete cortical coverage.

Parameters:
  • ref_id (str) – FreeSurfer subject ID of the reference subject containing the source annotation file.

  • hemi (str) – Hemisphere identifier: ‘lh’ or ‘rh’.

  • fs_annot (str) – Path to source annotation file or basename. Can be full path or just the annotation name (e.g., ‘aparc’). Also accepts GIFTI files (.gii).

  • ind_annot (str) – Path for output annotation file in individual subject space.

  • cont_tech (str, optional) – Container technology: ‘local’, ‘docker’, ‘singularity’. Default is ‘local’.

  • cont_image (str, optional) – Container image specification when using containerization. Default is None.

  • force (bool, optional) – Force processing even if output file exists. Default is False.

  • verbose (bool, optional) – Print verbose messages about processing status. Default is False.

Returns:

ind_annot – Path to the created individual space annotation file.

Return type:

str

Raises:

FileNotFoundError – If the source annotation file cannot be found in expected locations.

Notes

The method performs the following steps: 1. Converts GIFTI to annotation format if needed 2. Uses mri_surf2surf for surface-to-surface mapping 3. Applies gap-filling to ensure complete cortical labeling 4. Handles containerized execution with proper volume mounting

Examples

>>> # Map Desikan-Killiany parcellation
>>> output_file = subject.annot2ind(
...     ref_id='fsaverage',
...     hemi='lh',
...     fs_annot='aparc',
...     ind_annot='/output/lh.aparc.individual.annot'
... )
>>>
>>> # Using Docker container
>>> output_file = subject.annot2ind(
...     ref_id='fsaverage',
...     hemi='rh',
...     fs_annot='/path/to/custom.annot',
...     ind_annot='/output/rh.custom.individual.annot',
...     cont_tech='docker',
...     cont_image='freesurfer/freesurfer:7.2.0'
... )
gcs2ind(fs_gcs, ind_annot, hemi, cont_tech='local', cont_image=None, force=False, verbose=False)[source]

Apply GCS classifier to generate individual subject parcellation.

Uses FreeSurfer’s mris_ca_label to apply a trained Gaussian Classifier Surface (GCS) file to the individual subject, creating subject-specific parcellation followed by gap-filling for complete coverage.

Parameters:
  • fs_gcs (str) – Path to the FreeSurfer GCS (Gaussian Classifier Surface) file containing the trained classifier model.

  • ind_annot (str) – Path for output annotation file in individual subject space.

  • hemi (str) – Hemisphere identifier: ‘lh’ or ‘rh’.

  • cont_tech (str, optional) – Container technology: ‘local’, ‘docker’, ‘singularity’. Default is ‘local’.

  • cont_image (str, optional) – Container image specification when using containerization. Default is None.

  • force (bool, optional) – Force processing even if output file exists. Default is False.

  • verbose (bool, optional) – Print verbose messages about processing status. Default is False.

Returns:

ind_annot – Path to the created individual space annotation file.

Return type:

str

Notes

The method performs the following steps: 1. Uses mris_ca_label with cortex label and sphere registration 2. Applies the GCS classifier to generate parcellation labels 3. Performs gap-filling to ensure complete cortical coverage 4. Handles containerized execution with proper volume mounting

Requires the following FreeSurfer files for the individual subject: - cortex.label: Defines cortical vertices - sphere.reg: Spherical surface registration - Standard FreeSurfer directory structure

Examples

>>> # Apply Desikan-Killiany GCS classifier
>>> output_file = subject.gcs2ind(
...     fs_gcs='/atlases/lh.aparc.gcs',
...     ind_annot='/output/lh.aparc.individual.annot',
...     hemi='lh'
... )
>>>
>>> # Force reprocessing with custom classifier
>>> output_file = subject.gcs2ind(
...     fs_gcs='/custom/rh.custom_atlas.gcs',
...     ind_annot='/output/rh.custom.individual.annot',
...     hemi='rh',
...     force=True,
...     verbose=True
... )
surf2vol(atlas, out_vol, gm_grow='0', color_table=None, bool_native=False, bool_mixwm=False, cont_tech='local', cont_image=None, force=False, verbose=False)[source]

Create volumetric parcellation from surface annotation files.

Converts surface-based parcellation annotations to volumetric format, with options for label growing, white matter mixing, and coordinate space selection.

Parameters:
  • atlas (str) – Atlas identifier or name for the surface parcellation to convert. Should correspond to available annotation files for both hemispheres.

  • out_vol (str) – Path for output volumetric parcellation file.

  • gm_grow (int or str, optional) – Amount in millimeters to grow gray matter labels into surrounding tissue. Can help fill gaps between surface and volume. Default is “0”.

  • color_table (list or str, optional) – Format(s) for saving color lookup table: ‘tsv’, ‘lut’, or list of both [‘tsv’, ‘lut’]. Default is None (no color table saved).

  • bool_native (bool, optional) – If True, output parcellation in native subject space. If False, uses FreeSurfer’s standard space. Default is False.

  • bool_mixwm (bool, optional) – Mix cortical white matter growing with gray matter labels. Extends cortical labels into white matter regions. Default is False.

  • cont_tech (str, optional) – Container technology: ‘local’, ‘docker’, ‘singularity’. Default is ‘local’.

  • cont_image (str, optional) – Container image specification when using containerization. Default is None.

  • force (bool, optional) – Force processing even if output file exists. Default is False.

  • verbose (bool, optional) – Print verbose messages about processing progress. Default is False.

Returns:

out_vol – Path to the created volumetric parcellation file.

Return type:

str

Notes

This method is particularly useful for: - Creating volumetric ROIs from surface parcellations - Bridging surface-based and volume-based analyses - Generating masks for volume-based connectivity analysis - Converting surface atlases to volume format for other software

The process typically involves projecting surface labels onto the volumetric space, with optional growing and white matter integration to ensure comprehensive tissue coverage.

Examples

>>> # Basic surface-to-volume conversion
>>> vol_file = subject.surf2vol(
...     atlas='aparc',
...     out_vol='/output/aparc_volume.mgz'
... )
>>>
>>> # With gray matter growing and color table
>>> vol_file = subject.surf2vol(
...     atlas='aparc.a2009s',
...     out_vol='/output/destrieux_volume.mgz',
...     gm_grow="2",
...     color_table=['tsv', 'lut'],
...     bool_mixwm=True
... )
>>>
>>> # Native space output
>>> vol_file = subject.surf2vol(
...     atlas='custom_atlas',
...     out_vol='/output/custom_native.nii.gz',
...     bool_native=True,
...     force=True
... )
conform2native(mgz_conform, nii_native, interp_method='nearest', cont_tech='local', cont_image=None, force=False)[source]

Transform image from FreeSurfer conform space to native acquisition space.

Uses FreeSurfer’s mri_vol2vol to transform images from the standardized conform space (256³ isotropic) back to the original native acquisition space and dimensions.

Parameters:
  • mgz_conform (str) – Path to input image in FreeSurfer conform space (typically .mgz format).

  • nii_native (str) – Path for output image in native acquisition space.

  • interp_method (str, optional) – Interpolation method for resampling: ‘nearest’, ‘trilinear’, or ‘cubic’. Use ‘nearest’ for label/segmentation images. Default is ‘nearest’.

  • cont_tech (str, optional) – Container technology: ‘local’, ‘docker’, ‘singularity’. Default is ‘local’.

  • cont_image (str, optional) – Container image specification when using containerization. Default is None.

  • force (bool, optional) – Force processing even if output exists. If False, checks dimensions before deciding whether to reprocess. Default is False.

Returns:

Output file is created at the specified nii_native path.

Return type:

None

Raises:

FileNotFoundError – If the required rawavg.mgz file (native space reference) doesn’t exist.

Notes

This method is essential for bringing FreeSurfer processing results back to native space for integration with other analyses or visualization in original acquisition coordinates. The transformation uses the header information from rawavg.mgz as the target native space reference.

Examples

>>> # Convert parcellation to native space
>>> subject.conform2native(
...     mgz_conform='/fs/mri/aparc+aseg.mgz',
...     nii_native='/output/aparc_native.nii.gz'
... )
>>>
>>> # Convert with trilinear interpolation
>>> subject.conform2native(
...     mgz_conform='/fs/mri/T1.mgz',
...     nii_native='/output/T1_native.nii.gz',
...     interp_method='trilinear'
... )
get_surface(hemi, surf_type)[source]

Get the file path for a specific surface mesh.

Returns the path to surface files organized in the fs_files structure based on hemisphere and surface type specifications.

Parameters:
  • hemi (str) – Hemisphere identifier: ‘lh’ or ‘rh’.

  • surf_type (str) – Surface type: ‘pial’, ‘white’, ‘inflated’, or ‘sphere’.

Returns:

surf_file – Full path to the requested surface file.

Return type:

str

Raises:
  • ValueError – If hemisphere is not ‘lh’ or ‘rh’.

  • ValueError – If surf_type is not one of the valid surface types.

Examples

>>> # Get left hemisphere pial surface
>>> pial_surf = subject.get_surface('lh', 'pial')
>>> print(pial_surf)
>>>
>>> # Get right hemisphere white matter surface
>>> white_surf = subject.get_surface('rh', 'white')
get_vertexwise_map(hemi, map_type)[source]

Get the file path for a specific vertex-wise morphometric map.

Returns the path to morphometric map files organized in the fs_files structure based on hemisphere and map type specifications.

Parameters:
  • hemi (str) – Hemisphere identifier: ‘lh’ or ‘rh’.

  • map_type (str) – Map type: ‘curv’, ‘sulc’, ‘thickness’, ‘area’, or ‘volume’.

Returns:

map_file – Full path to the requested morphometric map file.

Return type:

str

Raises:
  • ValueError – If hemisphere is not ‘lh’ or ‘rh’.

  • ValueError – If map_type is not one of the valid morphometric map types.

Examples

>>> # Get left hemisphere cortical thickness
>>> thickness_map = subject.get_vertexwise_map('lh', 'thickness')
>>> print(thickness_map)
>>>
>>> # Get right hemisphere curvature
>>> curv_map = subject.get_vertexwise_map('rh', 'curv')
get_annotation(hemi, annot_type)[source]

Get the file path for a specific parcellation annotation.

Returns the path to annotation files organized in the fs_files structure based on hemisphere and annotation type specifications.

Parameters:
  • hemi (str) – Hemisphere identifier: ‘lh’ or ‘rh’.

  • annot_type (str) – Annotation type: ‘desikan’, ‘destrieux’, or ‘dkt’.

Returns:

annot_file – Full path to the requested annotation file.

Return type:

str

Raises:
  • ValueError – If hemisphere is not ‘lh’ or ‘rh’.

  • ValueError – If annot_type is not one of the valid annotation types.

Examples

>>> # Get left hemisphere Desikan-Killiany parcellation
>>> aparc_file = subject.get_annotation('lh', 'desikan')
>>> print(aparc_file)
>>>
>>> # Get right hemisphere Destrieux parcellation
>>> destrieux_file = subject.get_annotation('rh', 'destrieux')
clabtoolkit.freesurfertools.create_individual_freesurfer_table(subj_id, subjs_dir=None, out_tab_file=None, add_bids_entities=False)[source]

Create a dataset table from the subjects in the given directory. :param subjs_dir: The directory containing the FreeSurfer subjects. If None, uses the

FREESURFER_HOME environment variable to locate the subjects directory.

Parameters:
  • subj_id (str) – The subject ID for which to create the dataset table.

  • out_tab_file (str, optional) – If provided, the path to save the dataset table as a TSV file.

Returns:

A DataFrame containing the morphometry table for the subject.

Return type:

pd.DataFrame

clabtoolkit.freesurfertools.process_subject(fs_fullid, fs_subject_dir, out_folder)[source]

Process a single subject and return the result.

Parameters:
  • fs_fullid (str) – The full subject ID

  • fs_subject_dir (str) – The FreeSurfer subjects directory

  • out_folder (str) – The output folder for stats tables

Returns:

(subject_id, success_status, error_message_if_any)

Return type:

tuple

clabtoolkit.freesurfertools.create_freesurfer_table(out_folder, ids_file=None, fs_subject_dir=None, max_workers=1)[source]

Create FreeSurfer stats tables for multiple subjects in parallel.

Parameters:
  • out_folder (str) – The output folder for stats tables.

  • ids_file (str or List[str], optional) – A text file containing subject IDs (one per line) or a list of subject IDs. If None, an error is raised.

  • fs_subject_dir (str, optional) – The FreeSurfer subjects directory. If None, uses the SUBJECTS_DIR environment variable.

  • max_workers (int, optional) – The maximum number of worker threads to use for parallel processing. Default is 1 (non-parallel).

Return type:

None

Notes

This function processes each subject in parallel using ThreadPoolExecutor and displays a progress bar. It handles errors gracefully and provides a summary of completed and failed subjects.

Example

>>> create_freesurfer_table("/path/to/output", "/path/to/ids.txt", "/path/to/freesurfer/subjects", max_workers=4)

Create symbolic links to the fsaverage reference subject folder.

Creates symbolic links from a custom FreeSurfer subjects directory to the standard fsaverage template, enabling FreeSurfer tools to locate reference data.

Parameters:
  • fssubj_dir (str) – Target FreeSurfer subjects directory where the link will be created.

  • fsavg_dir (str, optional) – Source fsaverage directory path. If None, uses FREESURFER_HOME/subjects/fsaverage. Default is None.

  • refsubj_name (str, optional) – Reference subject name. If None, uses ‘fsaverage’. Default is None.

Returns:

link_folder – Path to the created symbolic link.

Return type:

str

Raises:

ValueError – If the FreeSurfer subjects directory or fsaverage directory doesn’t exist.

Examples

>>> # Create standard fsaverage link
>>> link_path = create_fsaverage_links('/data/freesurfer_subjects')
>>>
>>> # Create link with custom reference
>>> link_path = create_fsaverage_links(
...     '/data/freesurfer_subjects',
...     refsubj_name='fsaverage6'
... )

Remove symbolic links to the fsaverage folder.

Safely removes symbolic links to fsaverage directories that don’t point to the original FreeSurfer installation location.

Parameters:

linkavg_folder (str) – Path to the fsaverage link folder to potentially remove.

Notes

Only removes links that don’t point to the original FREESURFER_HOME location to prevent accidental deletion of the actual fsaverage data.

Examples

>>> # Remove custom fsaverage link
>>> remove_fsaverage_links('/data/freesurfer_subjects/fsaverage')
clabtoolkit.freesurfertools.region_to_vertexwise(reg_values, labels, reg_ctable)[source]

Map regional values to vertex-wise values using parcellation labels.

Assigns regional measurements to individual vertices based on their parcellation labels, creating vertex-wise data from region-wise data.

Parameters:
  • reg_values (np.ndarray) – Array of values for each region. Can be 1D or 2D array.

  • labels (np.ndarray) – Array of parcellation labels for each vertex.

  • reg_ctable (np.ndarray) – Color table with shape (N, 5) where column 4 contains region labels.

Returns:

vertex_values – Array with values mapped to each vertex. Shape: (num_vertices, num_measures).

Return type:

np.ndarray

Raises:

ValueError – If number of regions in reg_values doesn’t match reg_ctable dimensions or if reg_values has more than 2 dimensions.

Examples

>>> # Map thickness values to vertices
>>> regional_thickness = np.array([2.5, 3.1, 2.8])
>>> vertex_thickness = region_to_vertexwise(
...     regional_thickness, vertex_labels, color_table
... )
clabtoolkit.freesurfertools.create_vertex_colors(labels, reg_ctable)[source]

Create per-vertex RGBA colors based on parcellation labels.

Assigns colors to vertices based on their parcellation region using the color table information.

Parameters:
  • labels (np.ndarray) – Array of parcellation labels for each vertex.

  • reg_ctable (np.ndarray) – Color table with shape (N, 5) where first 3 columns are RGB values and column 4 contains region labels.

Returns:

vertex_colors – Array of RGB colors for each vertex with shape (num_vertices, 3). Default color is gray (240, 240, 240) for unlabeled vertices.

Return type:

np.ndarray

Examples

>>> # Create vertex colors for visualization
>>> colors = create_vertex_colors(vertex_labels, color_table)
>>> print(f"Colors shape: {colors.shape}")  # (num_vertices, 3)
clabtoolkit.freesurfertools.colors2colortable(colors)[source]

Convert color list to FreeSurfer color table format.

Transforms hexadecimal colors or RGB arrays into FreeSurfer’s standard color table format with packed RGB values.

Parameters:

colors (list or np.ndarray) – List of hexadecimal color strings (e.g., [‘#FF0000’, ‘#00FF00’]) or numpy array of RGB values.

Returns:

colortable – FreeSurfer color table with shape (N, 5) containing RGB values, alpha channel, and packed RGB values.

Return type:

np.ndarray

Raises:

ValueError – If colors is not a list or numpy array.

Examples

>>> # Convert hex colors to color table
>>> hex_colors = ["#FF0000", "#00FF00", "#0000FF"]
>>> ctab = colors2colortable(hex_colors)
>>> print(f"Color table shape: {ctab.shape}")
clabtoolkit.freesurfertools.resolve_colortable_duplicates(color_table)[source]

Make all RGB colors in FreeSurfer color table unique.

Identifies duplicate RGB colors and modifies them by incrementing color channels until uniqueness is achieved. Updates packed RGB values accordingly.

Parameters:

color_table (np.ndarray) – FreeSurfer color table with shape (n, 5) where columns 0-2 are RGB, column 3 is alpha, and column 4 is packed RGB value.

Returns:

  • modified_table (np.ndarray) – Updated color table with unique colors.

  • modification_log (dict) – Dictionary containing details of changes made including original duplicates count and list of modifications.

  • packed_values_mapping (dict) – Dictionary with ‘old_values’ and ‘new_values’ arrays for updating label maps accordingly.

Examples

>>> # Resolve duplicate colors
>>> unique_table, log, mapping = resolve_colortable_duplicates(color_table)
>>> print(f"Modified {len(log['modifications_made'])} colors")
clabtoolkit.freesurfertools.find_unique_color(rgb, rgb_to_indices)[source]

Find unique RGB color by systematically modifying channels.

Helper function that searches for an unused RGB color by incrementing or decrementing color channels in order: Blue, Green, Red.

Parameters:
  • rgb (np.ndarray) – Original RGB values [R, G, B].

  • rgb_to_indices (dict) – Dictionary mapping RGB tuples to indices for collision detection.

Returns:

New unique RGB values.

Return type:

np.ndarray

Raises:

RuntimeError – If no unique color can be found (extremely rare).

clabtoolkit.freesurfertools.verify_packed_rgb_values(color_table)[source]

Verify that packed RGB values are correctly calculated.

Checks if the packed RGB values (column 4) match the calculated values from RGB channels using the formula: R + (G << 8) + (B << 16).

Parameters:

color_table (np.ndarray) – FreeSurfer color table to verify.

Returns:

  • all_correct (bool) – True if all packed values are correct.

  • incorrect_indices (list) – List of dictionaries with details of incorrect entries.

Examples

>>> # Verify color table integrity
>>> is_correct, errors = verify_packed_rgb_values(color_table)
>>> if not is_correct:
...     print(f"Found {len(errors)} incorrect packed values")
clabtoolkit.freesurfertools.detect_hemi(file_name)[source]

Detect hemisphere from filename using common naming conventions.

Identifies left (‘lh’) or right (‘rh’) hemisphere from FreeSurfer and BIDS-style filenames using various naming patterns.

Parameters:

file_name (str) – Filename to analyze for hemisphere information.

Returns:

hemi – Hemisphere identifier (‘lh’ or ‘rh’) or None if not detected.

Return type:

str or None

Notes

Recognizes patterns like ‘lh.’, ‘rh.’, ‘hemi-L’, ‘hemi-left’, etc. Issues warning if hemisphere cannot be determined.

Examples

>>> # Detect from FreeSurfer filename
>>> hemi = detect_hemi('lh.aparc.annot')
>>> print(hemi)  # 'lh'
>>>
>>> # Detect from BIDS filename
>>> hemi = detect_hemi('sub-01_hemi-L_pial.surf.gii')
>>> print(hemi)  # 'lh'
clabtoolkit.freesurfertools.parse_freesurfer_lta(filepath)[source]

Parse a FreeSurfer .lta (Linear Transform Array) file.

Parameters:

filepathstr

Path to the .lta file

Returns:

dict

Dictionary containing parsed information including cras coordinates

clabtoolkit.freesurfertools.get_cras_coordinates(filepath, source=True)[source]

Simple function to extract just the cras coordinates.

Parameters:

filepathstr

Path to the .lta file

sourcebool

If True, return source cras; if False, return destination cras

Returns:

tuple

(x, y, z) coordinates

clabtoolkit.freesurfertools.load_lobes_json(lobes_json=None)[source]

Load JSON file containing anatomical lobe definitions.

Loads configuration file that defines how brain regions are grouped into anatomical lobes for coarser-grained analyses.

Parameters:

lobes_json (str, optional) – Path to custom JSON file. If None, uses default configuration file included with the package. Default is None.

Returns:

pipe_dict – Dictionary containing lobe definitions and grouping schemes.

Return type:

dict

Raises:

ValueError – If the specified JSON file doesn’t exist.

Examples

>>> # Load default lobe definitions
>>> lobes_config = load_lobes_json()
>>> print(lobes_config.keys())
>>>
>>> # Load custom definitions
>>> custom_config = load_lobes_json('/path/to/custom_lobes.json')
clabtoolkit.freesurfertools.get_version(cont_tech='local', cont_image=None)[source]

Get FreeSurfer version number from installation or container.

Queries FreeSurfer installation to determine version number, supporting both local installations and containerized environments.

Parameters:
  • cont_tech (str, optional) – Container technology: ‘local’, ‘docker’, ‘singularity’. Default is ‘local’.

  • cont_image (str, optional) – Container image specification when using containerization. Default is None.

Returns:

vers_cad – FreeSurfer version number (e.g., ‘7.2.0’).

Return type:

str

Examples

>>> # Get local FreeSurfer version
>>> version = get_version()
>>> print(f"FreeSurfer version: {version}")
>>>
>>> # Get version from Docker container
>>> version = get_version(
...     cont_tech='docker',
...     cont_image='freesurfer/freesurfer:7.2.0'
... )

The freesurfertools module provides comprehensive integration with the FreeSurfer neuroimaging suite, enabling processing of cortical surfaces, annotation files, and morphometric data.

Key Features

  • Process FreeSurfer annotation files (.annot, .gcs formats)

  • Correct and validate parcellations

  • Parse FreeSurfer statistics files

  • Surface-based morphometry computation

  • Container technology integration

  • Multi-format conversion capabilities

  • Extract CRAS coordinates from transform files

  • Parse FreeSurfer LTA transform files

Main Classes

AnnotParcellation

The primary class for working with FreeSurfer annotation files.

Key Methods: - load_from_file(): Load annotation files with optional reference surfaces - correct_parcellation(): Fix unlabeled vertices in parcellations - save_as_gcs(): Convert annotation to GCS format - get_region_info(): Extract parcellation region information - get_cras(): Extract CRAS coordinates from Talairach transform file

Common Usage Examples

Working with annotation files:

from clabtoolkit.freesurfertools import AnnotParcellation

# Load annotation file
annot = AnnotParcellation("lh.aparc.a2009s.annot")

# Correct parcellation by filling unlabeled vertices
annot.correct_parcellation()

# Convert to GCS format
annot.save_as_gcs("lh.aparc.a2009s.gcs")

# Get region information
region_info = annot.get_region_info()

Surface morphometry processing:

# Compute morphometry table for FreeSurfer subjects directory
from clabtoolkit import freesurfertools as fs

# Process all subjects in FreeSurfer subjects directory
morphometry_table = fs.compute_morphometry_table(
    subjects_dir="/path/to/freesurfer/subjects",
    parcellation="aparc.a2009s"
)

Transform and coordinate processing:

from clabtoolkit.freesurfertools import AnnotParcellation, parse_freesurfer_lta, get_cras_coordinates

# Extract CRAS coordinates from an annotation object
annot = AnnotParcellation("lh.aparc.a2009s.annot")
cras_coords = annot.get_cras()
print(f"CRAS coordinates: {cras_coords}")

# Parse LTA transform file
lta_data = parse_freesurfer_lta("/path/to/transforms/talairach.lta")
transform_matrix = lta_data['transform_matrix']
source_cras = lta_data['source_cras']
dest_cras = lta_data['dest_cras']

# Extract CRAS coordinates directly from LTA file
cras_coordinates = get_cras_coordinates(
    "/path/to/transforms/talairach.lta",
    source=True
)