Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

FSL Preprocessing and GLM

Run this notebook

This notebook showcases the FSL software package and performs preprocessing and first-level analysis on one subject from the Flanker dataset. The example is closely inspired by the FSL tutorial in Andy’s Brain Book and follows the steps outlined in Chapter 4: Preprocessing and Chapter 5: Statistics and Modeling. For detailed information about the dataset and analysis pipeline, refer to Andy’s original tutorial.

Author: Monika Doerig

Date: 15 May 2025

License:

MIT License

Note: If this notebook uses neuroimaging tools from Neurocontainers, those tools retain their original licenses. Please see Neurodesk citation guidelines for details.

Citation and Resoures:

Tools inluded in this workflow

FSL:

Educational Resources

Andy’s Brain Book:

Dataset

Flanker Dataset from OpenNeuro

  • Kelly AMC and Uddin LQ and Biswal BB and Castellanos FX and Milham MP (2018). Flanker task (event-related). OpenNeuro Dataset ds000102. [Dataset] doi: null

  • Kelly AM, Uddin LQ, Biswal BB, Castellanos FX, Milham MP. Competition between functional brain networks mediates behavioral variability. Neuroimage. 2008 Jan 1;39(1):527-37. doi: Kelly et al. (2008). Epub 2007 Aug 23. PMID: 17919929.

  • Mennes, M., Kelly, C., Zuo, X.N., Di Martino, A., Biswal, B.B., Castellanos, F.X., Milham, M.P. (2010). Inter-individual differences in resting-state functional connectivity predict task-induced BOLD activity. Neuroimage, 50(4):1690-701. doi: Mennes et al. (2010). Epub 2010 Jan 15. Erratum in: Neuroimage. 2011 Mar 1;55(1):434

  • Mennes, M., Zuo, X.N., Kelly, C., Di Martino, A., Zang, Y.F., Biswal, B., Castellanos, F.X., Milham, M.P. (2011). Linking inter-individual differences in neural activation and behavior to intrinsic brain dynamics. Neuroimage, 54(4):2950-9. doi: Mennes et al. (2011)

Load FSL and Import Python Libraries

['fsl/6.0.7.16']

Data download and preparation

./ds000102/sub-08/
├── anat
│   └── sub-08_T1w.nii.gz -> ../../.git/annex/objects/mw/MM/MD5E-s10561256--b94dddd8dc1c146aa8cd97f8d9994146.nii.gz/MD5E-s10561256--b94dddd8dc1c146aa8cd97f8d9994146.nii.gz
└── func
    ├── congruent_run1.txt
    ├── congruent_run2.txt
    ├── incongruent_run1.txt
    ├── incongruent_run2.txt
    ├── sub-08_task-flanker_run-1_bold.nii.gz -> ../../.git/annex/objects/zX/v9/MD5E-s28641609--47314e6d1a14b8545686110b5b67f8b8.nii.gz/MD5E-s28641609--47314e6d1a14b8545686110b5b67f8b8.nii.gz
    ├── sub-08_task-flanker_run-1_events.tsv
    ├── sub-08_task-flanker_run-2_bold.nii.gz -> ../../.git/annex/objects/WZ/F0/MD5E-s28636310--4535bf26281e1c5556ad0d3468e7fe4e.nii.gz/MD5E-s28636310--4535bf26281e1c5556ad0d3468e7fe4e.nii.gz
    └── sub-08_task-flanker_run-2_events.tsv

3 directories, 9 files

Inspecting the anatomical and functional images

Before beginning any preprocessing or analysis, it’s essential to visually inspect both anatomical and functional MRI data. This helps catch common issues such as motion artifacts, abnormal intensities, or poor image quality that could affect downstream results. To look at the data with FSL’s image viewer, you would type:

fsleyes ds000102/sub-08/anat/sub-08_T1w.nii.gz

We will use NiiVue to look at the data:

Loading...
Loading...
Loading...

1. Preprocessing

Brain Extraction

The first step is to remove the skull and non-brain areas from the image with FSL’s bet, the Brain Extraction Tool.


Usage:    bet <input> <output> [options]

Main bet2 options:
  -o          generate brain surface outline overlaid onto original image
  -m          generate binary brain mask
  -s          generate approximate skull image
  -n          don't generate segmented brain image output
  -f <f>      fractional intensity threshold (0->1); default=0.5; smaller values give larger brain outline estimates
  -g <g>      vertical gradient in fractional intensity threshold (-1->1); default=0; positive values give larger brain outline at bottom, smaller at top
  -r <r>      head radius (mm not voxels); initial surface sphere is set to half of this
  -c <x y z>  centre-of-gravity (voxels not mm) of initial mesh surface.
  -t          apply thresholding to segmented brain image and mask
  -e          generates brain surface as mesh in .vtk format

Variations on default bet2 functionality (mutually exclusive options):
  (default)   just run bet2
  -R          robust brain centre estimation (iterates BET several times)
  -S          eye & optic nerve cleanup (can be useful in SIENA - disables -o option)
  -B          bias field & neck cleanup (can be useful in SIENA)
  -Z          improve BET if FOV is very small in Z (by temporarily padding end slices)
  -F          apply to 4D FMRI data (uses -f 0.3 and dilates brain mask slightly)
  -A          run bet2 and then betsurf to get additional skull and scalp surfaces (includes registrations)
  -A2 <T2>    as with -A, when also feeding in non-brain-extracted T2 (includes registrations)

Miscellaneous options:
  -v          verbose (switch on diagnostic messages)
  -h          display this help, then exits
  -d          debug (don't delete temporary intermediate images)

Visualization of the brain extracted image

Check the following overlay image for areas where too much brain tissue has been removed or where parts of the skull haven’t been fully stripped away. The goal is to produce an image where the skull and face are completely removed, leaving only the brain—cortex, subcortical structures, brainstem, and cerebellum—intact.

Loading...

Fixing a bad skullstrip

If the skullstripping results aren’t satisfactory, you can adjust the parameters in the bet command. The -f option sets the fractional intensity threshold, which controls how much brain tissue is included—lower values result in a more generous brain mask, while higher values are more conservative. If too much brain was removed, try lowering the threshold. For example:

Loading...

Motion Correction

Motion correction realigns all volumes in a time series to a single reference volume to correct for head movement during the scan. The reference volume is typically the first, middle, or last volume in the series. FSL’s mcflirt can perform this correction by aligning each volume to the selected reference using rigid-body transformations that undo any detected motion.

The following commands use the first volume as the reference (- refvol 0) to perform motion correction:

Slice-Timing Correction

FSL does not perform slice-timing correction by default. Instead, it accounts for timing differences by including a temporal derivative in the statistical model.

Smoothing

Smoothing replaces each voxel’s signal with a weighted average of its neighbors, reducing noise at the cost of spatial resolution. While this blurs the image, it can enhance the signal-to-noise ratio by minimizing random fluctuations. Smoothing also helps improve statistical power and facilitates normalization to a standard template, as it makes anatomical differences between subjects less pronounced. To apply smoothing using fslmaths, the smoothing kernel is defined by its sigma (standard deviation). However, smoothing parameters are often specified using Full Width at Half Maximum (FWHM). To convert FWHM to sigma, use the formula:

σ=FWHM8ln⁡2≈FWHM2.3548\sigma = \frac{FWHM}{\sqrt{8 \ln 2}} \approx \frac{FWHM}{2.3548}

For a FWHM of 5 mm, this gives:

σ=52.3548≈2.1 mm\sigma = \frac{5}{2.3548} \approx 2.1 \text{ mm}

Registration and Normalization

Registration aligns functional images to the subject’s anatomical scan, while normalization aligns the anatomical scan to a standard template (e.g., MNI). Both steps involve estimating transformations and applying them to the data. The typical steps include:

  1. Initial Alignment: The functional and anatomical images are assumed to be roughly in the same location. If not, the outlines of the images are aligned.

  2. Mutual Information: Given that the anatomical and functional images have different contrast weightings (e.g., cerebrospinal fluid appears dark in the anatomical image but bright in the functional image), the algorithm uses this contrast difference. It matches bright voxels on one image to dark voxels on the other by testing different overlays until the best alignment is found.

  3. Transformation: Once the optimal match is achieved, the transformations used to align the anatomical image to the template are also applied to the functional images.

1. Extract a representative volume from each functional run (for flirt)

73

2. Register functional to anatomical (EPI to T1w)

Use full 3D search and 12 DOF for better alignment

  • Search options (-searchrx/y/z): Correspond to Full search in the FSL GUI, covering the full 3D rotation space (-180 to 180 degrees) to improve alignment.

  • Degrees of Freedom (-dof 12): Allows affine transformations including translation, rotation, scaling, and shearing.

3. Register anatomical to MNI template (T1w to MNI)

Same settings: full search, 12 DOF

/opt/fsl-6.0.7.16/data/standard/MNI152_T1_2mm_brain.nii.gz

4. Concatenate transforms

Combines functional → T1w and T1w → MNI into a single matrix

⚠️ There’s an important ordering rule when using convert_xfm -concat that you must follow:

result = mat2 * mat1

So, convert_xfm -omat output.mat -concat A.mat B.mat applys B first, then A.

5. Apply the transform to the full 4D functional data

Applies the final

Functional → Anatomical → MNI

transform in a single step using the .mat file created earlier, and resampling the functional images into MNI space.

Checking Preprocessing

Alignment

To visualize the alignment of functional run 1 in MNI space, the middle volume of the 4D dataset will be extracted and used as an overlay. Extracting a single volume instead of displaying the full 4D image reduces file size and computational load, making it more efficient for visualization and suitable for interactive display tools such as NiiVue.

Loading...

Motion parameters

The motion plots show translation and rotation over time, with each timepoint (volume) on the x-axis. For translation, values are in millimeters. Look for sudden spikes greater than half the voxel size, or gradual drifts exceeding a full voxel. For example, with 3 mm isotropic voxels, relative motion over 1.5 mm between volumes or absolute shifts over 3 mm across the run may warrant closer inspection.

<Figure size 1500x800 with 4 Axes>

2. Statistics and Modeling

Create timing files

To prepare condition-specific regressors for FSL analysis, timing files are required that specify the onset and duration of each event type. These are extracted from each subject’s events.tsv files. One timing file is generated per condition per run, formatted for use in FSL.

A Bash script called make_FSL_Timings.sh can be used to automate this step. It is available from Andy’s FSL_Scripts repository and should be placed in the directory containing the subject folders (e.g., ds000102/). Running the script will produce timing files in the appropriate format.

NOTE: This script only extracts the trials in which the subject made a correct response. Accuracy is nearly 100% for all subjects, but as an exercise you can modify this to extract the incorrect trials as well.

#!/bin/bash

#Check whether the file subjList.txt exists; if not, create it
if [ ! -f subjList.txt ]; then
        ls -d sub-?? > subjList.txt
fi

#Loop over all subjects and format timing files into FSL format
for subj in `cat subjList.txt` ; do
        cd $subj/func #Navigate to the subject's func directory, which contains the timing files
        
        #Extract the onset times for the incongruent and congruent trials for each run. NOTE: This script only extracts the trials in which the subject made a correct response. Accuracy is nearly 100% for all subjects, but as an exercise the student can modify this to extract the incorrect trials as well.
        cat ${subj}_task-flanker_run-1_events.tsv | awk '{if ($3=="incongruent_correct") {print $1, $2, "1"}}' > incongruent_run1.txt
        cat ${subj}_task-flanker_run-1_events.tsv | awk '{if ($3=="congruent_correct") {print $1, $2, "1"}}' > congruent_run1.txt

        cat ${subj}_task-flanker_run-2_events.tsv | awk '{if ($3=="incongruent_correct") {print $1, $2, "1"}}' > incongruent_run2.txt
        cat ${subj}_task-flanker_run-2_events.tsv | awk '{if ($3=="congruent_correct") {print $1, $2, "1"}}' > congruent_run2.txt
        
        cd ../..
done

Inspect the output:

0.0 2.0 1
10.0 2.0 1
20.0 2.0 1
52.0 2.0 1
88.0 2.0 1
130.0 2.0 1
144.0 2.0 1
174.0 2.0 1
248.0 2.0 1
260.0 2.0 1
274.0 2.0 1

Running the First-Level Analysis

As introduced in the beginning, this example uses the Flanker dataset, which is also described in Andy’s Brain Book. The contrasts are set up to compare congruent and incongruent trial types, reflecting typical cognitive control analyses.

FEAT Design Files for both runs

This file configures a first-level GLM analysis in FSL, skipping preprocessing steps and assuming the input data has already been preprocessed. Each .fsf file is tailored to a specific run, with unique input files and event timing. Below are the key sections to review and understand.

✅ General Analysis Settings

  • set fmri(level) 1: This is a first-level analysis (within-subject, per-run).

  • set fmri(analysis) 2: Only the Statistics stage is run (preprocessing is skipped).

  • set feat_files(1): Points to the preprocessed functional NIfTI file to analyze.

  • set fmri(outputdir): Path to where the FEAT results will be saved.

🧠 Model Specification Two Explanatory Variables (EVs):

  • evtitle1: “incongruent”

  • evtitle2: “congruent”

Each EV uses:

  • Custom timing files (custom1, custom2) in 3-column format (onset, duration, amplitude).

  • Double-Gamma HRF (set fmri(convolve1) 2).

  • No temporal derivative added (keeps design simpler to inspect).

📊 Contrasts Three contrasts are defined:

  • “incongruent”: [1 0]

  • “congruent”: [0 1]

  • “incongruent-congruent”: [1 -1]

These correspond to cope1, cope2, and cope3, respectively.

This setup allows testing condition effects vs baseline, and the difference between conditions.

⚙️ Other Notable Settings

  • TR: 2s (extracted from images)

  • Volumes: 146 (extracted from images)

  • Highpass filter: 100s cutoff

  • No motion regressors: (assumed already regressed out or not needed)

  • No registration: Standard space registration is enabled, but main structural registration is off (reghighres_yn is 0).

  • No pre-stats or post-stats steps (filtering_yn = 0, poststats_yn = 0).

Run feat for each of the two design files.

Visualization of First-level Design and Results (Run 1)

Below, the design matrix and selected results from the first run are shown. Since both runs use the same design and contrasts, the results of the second run can be explored using the same approach.

First, check the desgin Matrix, covariance matrix and design efficiency. The design efficiency report shows how well the model can detect each contrast. The correlation between regressors (0.573) is moderate and acceptable, although lower is better. The required effect sizes for detecting the contrasts (C1, C2, C3) are all under 1.5%, indicating good design sensitivity. In general, values below 2% suggest the design is capable of detecting realistic BOLD responses.

<IPython.core.display.Image object>
<IPython.core.display.Image object>

Let’s now display the thresholded activation maps. A voxelwise threshold of Z > 3.1 was applied, followed by cluster-level correction at p < 0.05 (corrected for multiple comparisons).

  • zstat1 - C1 (incongruent)

  • zstat2 - C2 (congruent)

  • zstat3 - C3 (incongruent-congruent)

Loading...
<IPython.core.display.Image object>
Loading...
<IPython.core.display.Image object>
Loading...
<IPython.core.display.Image object>

Dependencies in Jupyter/Python

  • Using the package watermark to document system environment and software versions used in this notebook, alongside the Neurodesktop version extracted from the JUPYTER_IMAGE or NEURODESKTOP_VERSION environment variables.

Last updated: 2026-07-08T08:53:54.090108+00:00

Python implementation: CPython
Python version       : 3.13.13
IPython version      : 9.12.0

Compiler    : GCC 14.3.0
OS          : Linux
Release     : 6.8.0-111-generic
Machine     : x86_64
Processor   : x86_64
CPU cores   : 16
Architecture: 64bit

IPython   : 9.12.0
ipyniivue : 2.4.4
matplotlib: 3.10.9
nibabel   : 5.3.3
nilearn   : 0.13.1
numpy     : 2.3.5

Neurodesktop version: 2026-06-04
References
  1. Kelly, A. M. C., Uddin, L. Q., Biswal, B. B., Castellanos, F. X., & Milham, M. P. (2008). Competition between functional brain networks mediates behavioral variability. NeuroImage, 39(1), 527–537. 10.1016/j.neuroimage.2007.08.008
  2. Mennes, M., Kelly, C., Zuo, X.-N., Di Martino, A., Biswal, B. B., Castellanos, F. X., & Milham, M. P. (2010). Inter-individual differences in resting-state functional connectivity predict task-induced BOLD activity. NeuroImage, 50(4), 1690–1701. 10.1016/j.neuroimage.2010.01.002
  3. Mennes, M., Zuo, X.-N., Kelly, C., Di Martino, A., Zang, Y.-F., Biswal, B., Castellanos, F. X., & Milham, M. P. (2011). Linking inter-individual differences in neural activation and behavior to intrinsic brain dynamics. NeuroImage, 54(4), 2950–2959. 10.1016/j.neuroimage.2010.10.046