8.2. First level models

8.2.1. HRF models

Nilearn offers a few different HRF models including the commonly used double-gamma SPM model (‘spm’) and the model shape proposed by G. Glover (‘glover’), both allowing the option of adding time and dispersion derivatives. The addition of these derivatives allows to better model any uncertainty in timing information. In addition, an FIR (finite impulse response, ‘fir’) model of the HRF is also available.

In order to visualize the predicted regressor prior to plugging it into the linear model, use the function nilearn.glm.first_level.compute_regressor, or explore the HRF plotting example Example of MRI response functions.

8.2.2. Design matrix: event-based and time series-based

8.2.2.1. Event-based

To create an event-based design matrix, information about the trial type, onset time and duration of the events in the experiment are necessary. This can be provided by the user, or be part of the dataset if using a BIDS-compatible dataset or one of the nilearn dataset fetcher functions like nilearn.datasets.fetch_spm_multimodal_fmri, nilearn.datasets.fetch_language_localizer_demo_dataset, etc.

Refer to the examples below for usage under the different scenarios:

To ascertain that the sequence of events provided to the first level model is accurate, Nilearn provides an event visualization function called nilearn.plotting.plot_event. Sample usage for this is available in Generate an events.tsv file for the NeuroSpin localizer task.

Once the events are defined, the design matrix is created using the nilearn.glm.first_level.make_first_level_design_matrix function:

from nilearn.glm.first_level import make_first_level_design_matrix
design_matrices = make_first_level_design_matrix(frame_times, events,
                          drift_model='polynomial', drift_order=3)

Note

Additional predictors, like subject motion, can be specified using the add_reg parameter. Look at the function definition for available arguments.

A handy function called nilearn.plotting.plot_design_matrix can be used to visualize the design matrix. This is generally a good practice to follow before proceeding with the analysis:

from nilearn.plotting import plot_design_matrix
plot_design_matrix(design_matrices)
../_images/sphx_glr_plot_design_matrix_001.png

8.2.2.2. Time series-based

The time series of a seed region can also be used as the predictor for a first level model. This approach would help identify brain areas co-activating with the seed region. The time series is extracted using nilearn.maskers.NiftiSpheresMasker. For instance, if the seed region is the posterior cingulate cortex with coordinate [pcc_coords]:

from nilearn.maskers import NiftiSpheresMasker
seed_masker = NiftiSpheresMasker([pcc_coords], radius=10)
seed_time_series = seed_masker.fit_transform(adhd_dataset.func[0])

The seed_time_series is then passed into the design matrix using the add_reg argument mentioned in the note above. Code for this approach is in Default Mode Network extraction of ADHD dataset.

8.2.3. Fitting a first level model

The nilearn.glm.first_level.FirstLevelModel class provides the tools to fit the linear model to the fMRI data. The nilearn.glm.first_level.FirstLevelModel.fit function takes the fMRI data and design matrix as input and fits the GLM. Like other Nilearn functions, nilearn.glm.first_level.FirstLevelModel.fit accepts file names as input, but can also work with NiftiImage objects. More information about input formats is available here

from nilearn.glm.first_level import FirstLevelModel
fmri_glm = FirstLevelModel()
fmri_glm = fmri_glm.fit(subject_data, design_matrices=design_matrices)

8.2.3.1. Computing contrasts

To get more interesting results out of the GLM model, contrasts can be computed between regressors of interest. The nilearn.glm.first_level.FirstLevelModel.compute_contrast function can be used for that. First, the contrasts of interest must be defined. In the spm_multimodal_fmri dataset referenced above, subjects are presented with ‘normal’ and ‘scrambled’ faces. The basic contrasts that can be constructed are the main effects of ‘normal faces’ and ‘scrambled faces’. Once the basic_contrasts have been set up, we can construct more interesting contrasts like ‘normal faces - scrambled faces’.

Note

The compute_contrast function can work with both numeric and symbolic arguments. See nilearn.glm.first_level.FirstLevelModel.compute_contrast for more information.

And finally we can compute the contrasts using the compute_contrast function. Refer to Single-subject data (two runs) in native space for the full example.

The activation maps from these 3 contrasts is presented below:

../_images/sphx_glr_plot_spm_multimodal_faces_001.png ../_images/sphx_glr_plot_spm_multimodal_faces_002.png ../_images/sphx_glr_plot_spm_multimodal_faces_003.png

Additional example: Simple example of two-runs fMRI model fitting

8.2.4. Extracting predicted time series and residuals

One way to assess the quality of the fit is to compare the observed and predicted time series of voxels. Nilearn makes the predicted time series easily accessible via a parameter called predicted that is part of the nilearn.glm.first_level.FirstLevelModel. This parameter is populated when FistLevelModel is initialized with the minimize_memory flag set to False.

observed_timeseries = masker.fit_transform(fmri_img)
predicted_timeseries = masker.fit_transform(fmri_glm.predicted[0])

Here, masker is an object of nilearn.maskers.NiftiSpheresMasker. In the figure below, predicted (red) and observed (not red) timecourses of 6 voxels are shown.

../_images/sphx_glr_plot_predictions_residuals_002.png

In addition to the predicted timecourses, this flag also yields the residuals of the GLM. The residuals are useful to calculate the F and R-squared statistic. For more information refer to Predicted time series and residuals

8.2.5. Surface-based analysis

fMRI analyses can also be performed on the cortical surface instead of a volumetric brain. Nilearn provides functions to map subject brains on to a cortical mesh, which can be either a standard surface as provided by, for e.g. Freesurfer, or a user-defined one. Freesurfer meshes can be accessed using nilearn.datasets.fetch_surf_fsaverage, while the function nilearn.surface.vol_to_surf does the projection from volumetric to surface space. Surface plotting functions like nilearn.plotting.plot_surf and nilearn.plotting.plot_surf_stat_map allow for easy visualization of surface-based data.

For a complete example refer to Example of surface-based first-level analysis