Written by Derrek Hibar, Neda Jahanshad, Roberto Toro, Jerod Rasmussen, Theo van Erp.

Adjusted by Premika Boedhoe

Instructions FreeSurfer cortical segmentation

In the cortical surface stream, the FreeSurfer tools construct models of the boundary between white matter and cortical grey matter as well as the pial surface. Once these surfaces are known, an array of anatomical measures becomes possible, including: cortical thickness, surface area, curvature, and surface normal at each point on the cortex.

The preprocessing pipeline of FreeSurfer (described in the previous instructions document) runs both cortical and subcortical segmentations. We continue with the assumption you work in a Linux environment with an enigma output folder. Your output folder should contain subject folders in which 10 sub folders (such as ‘mri’, ‘stats’, ‘surf’ etc) are embedded.

Below we will guide you through the steps that are necessary for the quality control of the cortical segmentation. You will find the required scripts in the attachment in the email or you can click on the hyperlinks.

1.  Extract and Organize Cortical Measures (FreeSurfer)

This section assumes that you have downloaded the script for extracting Surface Area and Thickness Values: extract.sh

The extract.sh script is depicted on the next page. This script will extract and organize each of the values for each FreeSurfer ROI. The script assumes that your FreeSurfer output is organized in a standard way:

{enigma}
à {input}
à{output}
à {subject1} à {FreeSurfer Output Sub Folders}
à {subject 2} à {FreeSurfer Output Sub Folders}

Save the extract.sh script in the Parent folder with your FreeSurfer output (<path>/enigma/output). Open the extract.sh and edit the for loop (line 6) so that the ls command selects the subject folder naming scheme used in your study:

for subj_id in $(ls -d Subj*); do #may need to change this so that it selects your subjects with FS output

Save the extract.sh script after editing. On the command line, you can run the script directly by running

sh extract.sh
#!/bin/bash
echo 'SubjID,L_bankssts_thickavg,L_caudalanteriorcingulate_thickavg,L_caudalmiddlefrontal_thickavg,L_cuneus_thickavg,L_entorhinal_thickavg,L_fusiform_thickavg,L_inferiorparietal_thickavg,L_inferiortemporal_thickavg,L_isthmuscingulate_thickavg,L_lateraloccipital_thickavg,L_lateralorbitofrontal_thickavg,L_lingual_thickavg,L_medialorbitofrontal_thickavg,L_middletemporal_thickavg,L_parahippocampal_thickavg,L_paracentral_thickavg,L_parsopercularis_thickavg,L_parsorbitalis_thickavg,L_parstriangularis_thickavg,L_pericalcarine_thickavg,L_postcentral_thickavg,L_posteriorcingulate_thickavg,L_precentral_thickavg,L_precuneus_thickavg,L_rostralanteriorcingulate_thickavg,L_rostralmiddlefrontal_thickavg,L_superiorfrontal_thickavg,L_superiorparietal_thickavg,L_superiortemporal_thickavg,L_supramarginal_thickavg,L_frontalpole_thickavg,L_temporalpole_thickavg,L_transversetemporal_thickavg,L_insula_thickavg,R_bankssts_thickavg,R_caudalanteriorcingulate_thickavg,R_caudalmiddlefrontal_thickavg,R_cuneus_thickavg,R_entorhinal_thickavg,R_fusiform_thickavg,R_inferiorparietal_thickavg,R_inferiortemporal_thickavg,R_isthmuscingulate_thickavg,R_lateraloccipital_thickavg,R_lateralorbitofrontal_thickavg,R_lingual_thickavg,R_medialorbitofrontal_thickavg,R_middletemporal_thickavg,R_parahippocampal_thickavg,R_paracentral_thickavg,R_parsopercularis_thickavg,R_parsorbitalis_thickavg,R_parstriangularis_thickavg,R_pericalcarine_thickavg,R_postcentral_thickavg,R_posteriorcingulate_thickavg,R_precentral_thickavg,R_precuneus_thickavg,R_rostralanteriorcingulate_thickavg,R_rostralmiddlefrontal_thickavg,R_superiorfrontal_thickavg,R_superiorparietal_thickavg,R_superiortemporal_thickavg,R_supramarginal_thickavg,R_frontalpole_thickavg,R_temporalpole_thickavg,R_transversetemporal_thickavg,R_insula_thickavg,LThickness,RThickness,LSurfArea,RSurfArea,ICV' > CorticalMeasuresENIGMA_ThickAvg.csv
echo 'SubjID,L_bankssts_surfavg,L_caudalanteriorcingulate_surfavg,L_caudalmiddlefrontal_surfavg,L_cuneus_surfavg,L_entorhinal_surfavg,L_fusiform_surfavg,L_inferiorparietal_surfavg,L_inferiortemporal_surfavg,L_isthmuscingulate_surfavg,L_lateraloccipital_surfavg,L_lateralorbitofrontal_surfavg,L_lingual_surfavg,L_medialorbitofrontal_surfavg,L_middletemporal_surfavg,L_parahippocampal_surfavg,L_paracentral_surfavg,L_parsopercularis_surfavg,L_parsorbitalis_surfavg,L_parstriangularis_surfavg,L_pericalcarine_surfavg,L_postcentral_surfavg,L_posteriorcingulate_surfavg,L_precentral_surfavg,L_precuneus_surfavg,L_rostralanteriorcingulate_surfavg,L_rostralmiddlefrontal_surfavg,L_superiorfrontal_surfavg,L_superiorparietal_surfavg,L_superiortemporal_surfavg,L_supramarginal_surfavg,L_frontalpole_surfavg,L_temporalpole_surfavg,L_transversetemporal_surfavg,L_insula_surfavg,R_bankssts_surfavg,R_caudalanteriorcingulate_surfavg,R_caudalmiddlefrontal_surfavg,R_cuneus_surfavg,R_entorhinal_surfavg,R_fusiform_surfavg,R_inferiorparietal_surfavg,R_inferiortemporal_surfavg,R_isthmuscingulate_surfavg,R_lateraloccipital_surfavg,R_lateralorbitofrontal_surfavg,R_lingual_surfavg,R_medialorbitofrontal_surfavg,R_middletemporal_surfavg,R_parahippocampal_surfavg,R_paracentral_surfavg,R_parsopercularis_surfavg,R_parsorbitalis_surfavg,R_parstriangularis_surfavg,R_pericalcarine_surfavg,R_postcentral_surfavg,R_posteriorcingulate_surfavg,R_precentral_surfavg,R_precuneus_surfavg,R_rostralanteriorcingulate_surfavg,R_rostralmiddlefrontal_surfavg,R_superiorfrontal_surfavg,R_superiorparietal_surfavg,R_superiortemporal_surfavg,R_supramarginal_surfavg,R_frontalpole_surfavg,R_temporalpole_surfavg,R_transversetemporal_surfavg,R_insula_surfavg,LThickness,RThickness,LSurfArea,RSurfArea,ICV' > CorticalMeasuresENIGMA_SurfAvg.csv
for subj_id in $(ls -d Subj*); do #may need to change this so that it selects subjects with FS output
printf "%s," "${subj_id}" > CorticalMeasuresENIGMA_ThickAvg.csv
printf "%s," "${subj_id}" > CorticalMeasuresENIGMA_SurfAvg.csv
for side in lh.aparc.stats rh.aparc.stats; do
for x in bankssts caudalanteriorcingulate caudalmiddlefrontal cuneus entorhinal fusiform inferiorparietal inferiortemporal isthmuscingulate lateraloccipital lateralorbitofrontal lingual medialorbitofrontal middletemporal parahippocampal paracentral parsopercularis parsorbitalis parstriangularis pericalcarine postcentral posteriorcingulate precentral precuneus rostralanteriorcingulate rostralmiddlefrontal superiorfrontal superiorparietal superiortemporal supramarginal frontalpole temporalpole transversetemporal insula; do
printf "%g," `grep -w ${x} ${subj_id}/stats/${side} | awk '{print $5}'` > CorticalMeasuresENIGMA_ThickAvg.csv
printf "%g," `grep -w ${x} ${subj_id}/stats/${side} | awk '{print $3}'` > CorticalMeasuresENIGMA_SurfAvg.csv
done
done
printf "%g," `cat ${subj_id}/stats/lh.aparc.stats | grep MeanThickness | awk -F, '{print $4}'` > CorticalMeasuresENIGMA_ThickAvg.csv
printf "%g," `cat ${subj_id}/stats/rh.aparc.stats | grep MeanThickness | awk -F, '{print $4}'` > CorticalMeasuresENIGMA_ThickAvg.csv
printf "%g," `cat ${subj_id}/stats/lh.aparc.stats | grep MeanThickness | awk -F, '{print $4}'` > CorticalMeasuresENIGMA_SurfAvg.csv
printf "%g," `cat ${subj_id}/stats/rh.aparc.stats | grep MeanThickness | awk -F, '{print $4}'` > CorticalMeasuresENIGMA_SurfAvg.csv
printf "%g," `cat ${subj_id}/stats/lh.aparc.stats | grep WhiteSurfArea | awk -F, '{print $4}'` > CorticalMeasuresENIGMA_ThickAvg.csv
printf "%g," `cat ${subj_id}/stats/rh.aparc.stats | grep WhiteSurfArea | awk -F, '{print $4}'` > CorticalMeasuresENIGMA_ThickAvg.csv
printf "%g," `cat ${subj_id}/stats/lh.aparc.stats | grep WhiteSurfArea | awk -F, '{print $4}'` > CorticalMeasuresENIGMA_SurfAvg.csv
printf "%g," `cat ${subj_id}/stats/rh.aparc.stats | grep WhiteSurfArea | awk -F, '{print $4}'` > CorticalMeasuresENIGMA_SurfAvg.csv
printf "%g" `cat ${subj_id}/stats/aseg.stats | grep IntraCranialVol | awk -F, '{print $4}'` > CorticalMeasuresENIGMA_ThickAvg.csv
printf "%g" `cat ${subj_id}/stats/aseg.stats | grep IntraCranialVol | awk -F, '{print $4}'` > CorticalMeasuresENIGMA_SurfAvg.csv
echo "" > CorticalMeasuresENIGMA_ThickAvg.csv
echo "" > CorticalMeasuresENIGMA_SurfAvg.csv
done

The result of this step will be two comma-separated (CSV) files that can be opened in your favourite spreadsheet application (i.e. Excel). The first row is a header describing the extracted regions and names for each column. Each row after the first gives the cortical thickness (or surface area) measures for each subject found in your FreeSurfer directory. In the next step, you will do a QC of the segmentation quality.

Note 1: After running the extract.sh script, open both of the CSV files (CorticalMeasuresENIGMA_ThickAvg.csv and CorticalMeasuresENIGMA_SurfAvg.csv) and make sure that only subjects are listed in the rows of the file. Sometimes, if there are other folders in your parent directory those folders can sometimes become included in your final files. If that happens just delete those from your CSV files and save.

Note 2: When you edit the files in Excel, be sure to keep them in CSV format when you save!

2.  Quality Checking Cortical Measures (FreeSurfer)

There are three major steps for quality checking the cortical segmentations of your FreeSurfer output:

a.  Outlier Detection

i.  This is a simple R script that will identify subjects with cortical thickness and surface area values that deviate from the rest of your subjects

b.  Internal Surface Method

i.  This method uses a Matlab function to plot cortical surface segmentations directly on a subject’s scan and collates snapshots from internal slices of the brain into a webpage for easy checking

c.  External Surface Method

i.  This step is loosely based on the QA tools for FreeSurfer. Webpages are created with external views of the segmentations from different angles

2.a. Outlier detection

This step requires that you have R installed and that you have downloaded the outlier detection script (outliers.R).

The outliers.R script will generate a log file that will tell you which subjects are outliers and for which structures they are outliers for. Make sure you look at these subjects closely as you proceed with the quality check protocol to make sure they are segmented properly.

Change directories to the location of your CorticalMeasuresENIGMA_ThickAvg.csv and CorticalMeasuresENIGMA_SurfAvg.csv generated in Step 1. Make sure the outliers.R script is also in that directory and run:

R --no-save --slave < outliers.R > outliers.log

NB: Just because a subject is an outlier does not necessarily mean that they should be excluded from the analyses. If a subject is segmented properly in FreeSurfer (which you will visually verify at later steps in this protocol) then please do keep them in the analyses.

2.b. The Internal Surface Method (Matlab)

2.b.1. Making .png image files

This step is performed in Matlab and assumes you have downloaded the QC_ENIGMA_Cortex.zip package and that you have downloaded the script to wrap the output into a webpage (make_ENIGMA_QC_wegpage.sh).

Move the QC_ENIGMA_Cortex.zip scripts into your enigma folder and unzip them. Move the make_ENIGMA_QC_webpage.sh script to the same folder containing all other matlab scripts.

Start Matlab:

path_to_matlab>/matlab

Add the ENIGMA_QC_cortical folder containing all the required scripts to Matlab’s path:

File à Set Path à Add Folder à {ok} à {save} à {close}

When you work in Matlab without a GUI, you can instead type

addpath <path>/enigma/ENIGMA_QC

In the Matlab console window, change directories to the folder with all of your FreeSurfer subject folders

cd <path> /enigma/output/

Make a directory to store all of the internal QC output

mkdir <path> /enigma/output/QC_cortical_internal/

The script we want to run is called func_make_corticalpngs_ENIGMA_QC.m with the following parameters:

func_make_corticalpngs_ENIGMA_QC(output_QC_directory, subject_name, select_MRI_image, select_Segmented_image)

We want to set ‘subject_name’ such that ‘subject_name’ + ‘select_Segmented_image’ will form the full name of the segmentation label files (e.g. subj1/mri/aparc+aseg.mgz) and similarly for ‘select_MRI_image’ we want it to give the full name of the registered MRI scan outputted by FreeSurfer (e.g. subj1/mri/orig.mgz).

In the Matlab command window we can do:

QC_output_directory='<path>/enigma/output/QC_cortical_internal/';
FS_directory='<path>/enigma/output/';
a=dir(char(strcat(FS_directory,'/subj*')));%Choose this so that it selects only your
%subject folders that contain FS output
for x = 1:size(a,1)
[c,b,d]=fileparts(a(x,1).name); %b becomes the subject_name
try
func_make_corticalpngs_ENIGMA_QC(QC_output_directory, b, [FS_directory, '/', b, '/mri/orig.mgz'], [FS_directory,'/', b, '/mri/aparc+aseg.mgz']);
end
display(['Done with subject: ', b, ': ', num2str(x), ' of ', num2str(size(a,1))]);
end

The func_make_corticalpngs_ENIGMA_QC.m script should take approximately 7 seconds/subject and will output a series of *.png image files separated by individual subject folders.

NB: if you run into problems with this Matlab loop try removing the last “/” in the QC_output_directory variable. So,

QC_output_directory=’<path>/enigma/output/QC_cortical_internal/’;

would become

QC_output_directory=’<path>/enigma/output/QC_cortical_internal’;

2.b.2. Making the internal cortical QC webpage

To create a webpage for easy viewing of the QC output you just generated in Matlab, go to the directory where you stored the script make_ENIGMA_QC _webpage.sh and make sure it is executable:

chmod 777 make_ENIGMA_QC_webpage.sh

Now to run the script, just give the script the full path to the directory where you stored the Matlab QC output files:

./make_ENIGMA_QC_webpage.sh <path>/enigma/output/QC_cortical_internal/

NB: If you have trouble running this script, it’s possible that you need to fix the line endings in the script before running. You can do this by running this command:

sed -i -e 's/\r$//' make_ENIGMA_QC_webpage.sh

This script will create a webpage called ENIGMA_Cortical_QC.html in the same folder as your QC output. To open the webpage in a browser of your choice in a Linux environment type, for example:

firefox <path>/enigma/output/QC/ENIGMA_Cortical_QC.html

Note 1: if you want to check the segmentation on another computer, you can just copy over the whole QC folder to your computer and open the webpage from there.

Note 2: scroll through each set of images. Note that you can click on a subject’s files to see a larger version.

NOTE 3 : use the legend.jpg file as a coloured coded reference of each FreeSurfer ROI (split by left/right) while quality checking the cortical segmentations.

2.b.3. Examples

On the next page you will see examples of good and bad segmentations.

If cortical labels are bad:

·  Open the data files CorticalMeasuresENIGMA_ThickAvg.csv and CorticalMeasuresENIGMA_SurfAvg.csv in Excel

·  Mark poorly segmented cortical regions with "NA" (without the quotes) in BOTH csv files

·  If the whole subject is poorly segmented (like in the example) you can delete the subject's row from the data files or mark all of the entries in a subject's row with "NA".

Make sure to save the files back in CSV format!

Example of a good segmentation

Example of a bad segmentation

A close-up shot of a good vs. bad segmentation:

Good Bad

2.c.1. The External Surface Method (FreeSurfer)

This section assumes you have downloaded the fsqc.sh script. FreeSurfer and its utilities need to be in your path or this script will not run properly. You can type tksurfer on the command line to make sure it is available.

The script fsqc.sh will create a webpage with lateral and medial snapshots of pial surface reconstructions coloured with cortical labels. Clicking on the images will display a larger version.

To run the script, first source FreeSurfer’s environment variable $SUBJECTS_DIR to point you subjects directory. For example:

bash
export SUBJECTS_DIR=<path>/enigma/output

Next create a directory to contain the snapshots (.tif image file). Here, we will call it QC_cortial_external. Change the working directory to QC_cortical_external and run the fsqc.sh script from there:

cd QC_cortical_external
source <path to enigma scripts>/fsqc.sh

This script will call ‘tksurfer’ in a loop for each subject and output a series of 4 images (.tif files) for each subject. It will also create a website called index.html so that you can easily view the images. You can open the index.html file in any browser, just make sure all of the .tif files are in the same folder if you deicide to move the index.html file to a different location (like a local computer). If you are in a Linux environment you should be able to just type on the command line:

#while in the output QC_cortical_external folder

firefox index.html


2.c.2. Examples

On the next page you will see examples of good and bad reconstructions.

Make sure to:

·  Check that all the lobes are present, especially the ventral part of the temporal lobe

·  Check that labels positions are not different from the general case (see legend.jpg)

If cortical labels are bad:

·  Open the data file CoticalMeasuresENIGMA_ThickAvg.csv and CorticalMeasuresENIGMA_SurfAvg.csv in Excel

·  Mark poorly segmented cortical regions with “NA” (without the quotes) in BOTH csv files

·  If the whole subject is poorly segmented (like in the example below) you can delete the subject’s row from the data files or mark all of the entries in the concerning subject’s row with “NA”.

Make sure to save the files back in CSV format!

Example of a successful reconstruction

Example of poor labelling

3.  Generate Summary Statistics and Histogram Plots

This step assumes that you have downloaded the automated script for generating the plots ENIGMA_CortexROI_plots.R. and that you have downloaded and installed R (download here).

After having quality checked each of your segmented structures, you should have two files called CorticalMeasuresENIGMA_ThickAvg.csv and CorticalMeasuresENIGMA_SurfAvg.csv, which are comma separated files with the values of each segmented structure for each subject. The CorticalMeasuresENIGMA_ThickAvg.csv file should look like this (e.g.) (note the ... there should be 74 columns) with poorly labelled structures marked with NA:

SubjID,L_bankssts_thickavg,L_caudalanteriorcingulate_thickavg, ...
subject1,2.324,2.383, ...
subject2,2.593,NA, ...
subject3,2.77,2.955, ...
subject4,NA,NA, ...
subject5,2.695,3.348, ...

Generating plots and summary statistics

Make a new directory to store all of your summary stats and histogram plots:

mkdir <path>/enigma/figures

Copy your CorticalMeasuresENIGMMA_ThickAvg.csv and CorticalMeasuresENIGMA_SurfAvg.csv files to your new folder:

cp <path>/enigma/output/CorticalMeasuresENIGMA_ThickAvg <path>/enigma/figures/
cp <path>/enigma/output/CorticalMeasuresENIGMA_SurfAvg <path>/enigma/figures/

Save the ENIGMA_CortexROI_plots.R script in the same folder, make sure you are in your new figures folder and run the script to generate the plots:

R --no save --slave < ENIGMA_CortexROI_plots.R

It should only take a minute to generate all of the plots. If you get errors, the script might tell you what things need to be changed in your data file in order to work properly. Just make sure that your input file is in *.csv format like the example file above.

The output will be a series of PNG image files that you can open in any standard picture viewer. You need to go through each of the PNG files to make sure that your histograms look approximately normal.

NB: If a subject is an outlier in your histogram plots, but after inspection you decide the subject is properly segmented, you should KEEP it in your CorticalMeasuresENIGMA_ThickAvg.csv and CorticalMeasuresENIGMA_SurfAvg.csv files to be used in the analysis.

When done, please send the resulting folder with the histogram plots and the SummaryStats.txt files to: Premika Boedhoe ()

These protocols are offered with an unlimited license and without warranty. However, if you find these protocols useful in your research, please provide a link to the ENIGMA website in your work: www.enigma.ini.usc.edu