Note
Go to the end to download the full example code or to run this example in your browser via Binder.
Single-subject data (two runs) in native space¶
The example shows the analysis of an SPM dataset, with two conditions: viewing a face image or a scrambled face image.
This example takes a lot of time because the input are lists of 3D images sampled in different positions (encoded by different affine functions).
See also
For more information see the dataset description.
Fetch and inspect the data¶
Fetch the SPM multimodal_faces data.
from nilearn.datasets import fetch_spm_multimodal_fmri
subject_data = fetch_spm_multimodal_fmri()
[fetch_spm_multimodal_fmri] Dataset created in
/home/runner/nilearn_data/spm_multimodal_fmri
[fetch_spm_multimodal_fmri] Missing 390 functional scans for session 1.
[fetch_spm_multimodal_fmri] Data absent, downloading...
[fetch_spm_multimodal_fmri] Downloading data from
https://www.fil.ion.ucl.ac.uk/spm/download/data/mmfaces/multimodal_fmri.zip ...
[fetch_spm_multimodal_fmri] Downloaded 1720320 of 134263085 bytes (1.3%%,
1.3min remaining)
[fetch_spm_multimodal_fmri] Downloaded 7135232 of 134263085 bytes (5.3%%,
36.1s remaining)
[fetch_spm_multimodal_fmri] Downloaded 11763712 of 134263085 bytes (8.8%%,
31.5s remaining)
[fetch_spm_multimodal_fmri] Downloaded 16637952 of 134263085 bytes (12.4%%,
28.6s remaining)
[fetch_spm_multimodal_fmri] Downloaded 21659648 of 134263085 bytes (16.1%%,
26.5s remaining)
[fetch_spm_multimodal_fmri] Downloaded 26959872 of 134263085 bytes (20.1%%,
24.3s remaining)
[fetch_spm_multimodal_fmri] Downloaded 32440320 of 134263085 bytes (24.2%%,
22.3s remaining)
[fetch_spm_multimodal_fmri] Downloaded 37707776 of 134263085 bytes (28.1%%,
20.8s remaining)
[fetch_spm_multimodal_fmri] Downloaded 42868736 of 134263085 bytes (31.9%%,
19.5s remaining)
[fetch_spm_multimodal_fmri] Downloaded 48037888 of 134263085 bytes (35.8%%,
18.2s remaining)
[fetch_spm_multimodal_fmri] Downloaded 53264384 of 134263085 bytes (39.7%%,
17.0s remaining)
[fetch_spm_multimodal_fmri] Downloaded 58761216 of 134263085 bytes (43.8%%,
15.6s remaining)
[fetch_spm_multimodal_fmri] Downloaded 64585728 of 134263085 bytes (48.1%%,
14.2s remaining)
[fetch_spm_multimodal_fmri] Downloaded 70410240 of 134263085 bytes (52.4%%,
12.9s remaining)
[fetch_spm_multimodal_fmri] Downloaded 76759040 of 134263085 bytes (57.2%%,
11.4s remaining)
[fetch_spm_multimodal_fmri] Downloaded 82190336 of 134263085 bytes (61.2%%,
10.3s remaining)
[fetch_spm_multimodal_fmri] Downloaded 87433216 of 134263085 bytes (65.1%%,
9.2s remaining)
[fetch_spm_multimodal_fmri] Downloaded 92340224 of 134263085 bytes (68.8%%,
8.3s remaining)
[fetch_spm_multimodal_fmri] Downloaded 96804864 of 134263085 bytes (72.1%%,
7.5s remaining)
[fetch_spm_multimodal_fmri] Downloaded 101580800 of 134263085 bytes (75.7%%,
6.5s remaining)
[fetch_spm_multimodal_fmri] Downloaded 106037248 of 134263085 bytes (79.0%%,
5.7s remaining)
[fetch_spm_multimodal_fmri] Downloaded 110206976 of 134263085 bytes (82.1%%,
4.9s remaining)
[fetch_spm_multimodal_fmri] Downloaded 113352704 of 134263085 bytes (84.4%%,
4.3s remaining)
[fetch_spm_multimodal_fmri] Downloaded 116367360 of 134263085 bytes (86.7%%,
3.8s remaining)
[fetch_spm_multimodal_fmri] Downloaded 119390208 of 134263085 bytes (88.9%%,
3.2s remaining)
[fetch_spm_multimodal_fmri] Downloaded 122486784 of 134263085 bytes (91.2%%,
2.6s remaining)
[fetch_spm_multimodal_fmri] Downloaded 125222912 of 134263085 bytes (93.3%%,
2.0s remaining)
[fetch_spm_multimodal_fmri] Downloaded 127705088 of 134263085 bytes (95.1%%,
1.5s remaining)
[fetch_spm_multimodal_fmri] Downloaded 130318336 of 134263085 bytes (97.1%%,
0.9s remaining)
[fetch_spm_multimodal_fmri] Downloaded 133103616 of 134263085 bytes (99.1%%,
0.3s remaining)
[fetch_spm_multimodal_fmri] ...done. (32 seconds, 0 min)
[fetch_spm_multimodal_fmri] Extracting data from
/home/runner/nilearn_data/spm_multimodal_fmri/sub001/multimodal_fmri.zip...
[fetch_spm_multimodal_fmri] .. done.
[fetch_spm_multimodal_fmri] Downloading data from
https://www.fil.ion.ucl.ac.uk/spm/download/data/mmfaces/multimodal_smri.zip ...
[fetch_spm_multimodal_fmri] Downloaded 1073152 of 6852766 bytes (15.7%%, 5.6s
remaining)
[fetch_spm_multimodal_fmri] ...done. (3 seconds, 0 min)
[fetch_spm_multimodal_fmri] Extracting data from
/home/runner/nilearn_data/spm_multimodal_fmri/sub001/multimodal_smri.zip...
[fetch_spm_multimodal_fmri] .. done.
Let’s inspect one of the event files before using them.
import pandas as pd
events = [subject_data.events1, subject_data.events2]
events_dataframe = pd.read_csv(events[0], sep="\t")
events_dataframe["trial_type"].value_counts()
trial_type
scrambled 86
faces 64
Name: count, dtype: int64
We can confirm there are only 2 conditions in the dataset.
from nilearn.plotting import plot_event, show
plot_event(events)
show()

Resample the images:
this is achieved by the concat_imgs function of Nilearn.
import warnings
from nilearn.image import concat_imgs, mean_img, resample_img
# Avoid getting too many warnings due to resampling
with warnings.catch_warnings():
warnings.simplefilter("ignore")
fmri_img = [
concat_imgs(subject_data.func1, auto_resample=True),
concat_imgs(subject_data.func2, auto_resample=True),
]
affine, shape = fmri_img[0].affine, fmri_img[0].shape
print("Resampling the second image (this takes time)...")
fmri_img[1] = resample_img(fmri_img[1], affine, shape[:3])
Resampling the second image (this takes time)...
Let’s create mean image for display purposes.
Fit the model¶
Fit the GLM for the 2 runs by specifying a FirstLevelModel and then fitting it.
# Sample at the beginning of each acquisition.
slice_time_ref = 0.0
# We use a discrete cosine transform to model signal drifts.
drift_model = "cosine"
# The cutoff for the drift model is 0.01 Hz.
high_pass = 0.01
# The hemodynamic response function
hrf_model = "spm + derivative"
from nilearn.glm.first_level import FirstLevelModel
print("Fitting a GLM")
fmri_glm = FirstLevelModel(
smoothing_fwhm=None,
t_r=subject_data.t_r,
hrf_model=hrf_model,
drift_model=drift_model,
high_pass=high_pass,
verbose=1,
)
fmri_glm = fmri_glm.fit(fmri_img, events=events)
Fitting a GLM
[FirstLevelModel.fit] Loading data from <nibabel.nifti1.Nifti1Image object at
0x7f0f2f67e7d0>
[FirstLevelModel.fit] Computing mask
[FirstLevelModel.fit] Resampling mask
[FirstLevelModel.fit] Finished fit
[FirstLevelModel.fit] Computing run 1 out of 2 runs (go take a coffee, a big
one).
[FirstLevelModel.fit] Performing mask computation.
[FirstLevelModel.fit] Loading data from <nibabel.nifti1.Nifti1Image object at
0x7f0f2f67e7d0>
[FirstLevelModel.fit] Extracting region signals
[FirstLevelModel.fit] Cleaning extracted signals
[FirstLevelModel.fit] Masking took 1 seconds.
[FirstLevelModel.fit] Performing GLM computation.
[FirstLevelModel.fit] GLM took 1 seconds.
[FirstLevelModel.fit] Computing run 2 out of 2 runs (2 seconds remaining).
[FirstLevelModel.fit] Performing mask computation.
[FirstLevelModel.fit] Loading data from <nibabel.nifti1.Nifti1Image object at
0x7f0f2f67e410>
[FirstLevelModel.fit] Extracting region signals
[FirstLevelModel.fit] Cleaning extracted signals
[FirstLevelModel.fit] Masking took 1 seconds.
[FirstLevelModel.fit] Performing GLM computation.
[FirstLevelModel.fit] GLM took 1 seconds.
[FirstLevelModel.fit] Computation of 2 runs done in 5 seconds.
View the results¶
Now we can compute contrast-related statistical maps (in z-scale), and plot them.
from nilearn.plotting import plot_stat_map
print("Computing contrasts")
Computing contrasts
We actually want more interesting contrasts. The simplest contrast just makes the difference between the two main conditions. We define the two opposite versions to run one-tailed t-tests.
contrasts = ["faces - scrambled", "scrambled - faces"]
Let’s store common parameters for all plots.
We plot the contrasts values overlaid on the mean fMRI image and we will use the z-score values as transparency, with any voxel with | Z-score | > 3 being fully opaque and any voxel with 0 < | Z-score | < 1.96 being partly transparent.
plot_param = {
"vmin": 0,
"display_mode": "z",
"cut_coords": 3,
"black_bg": True,
"bg_img": mean_image,
"cmap": "inferno",
"transparency_range": [0, 3],
}
# Iterate on contrasts to compute and plot them.
for contrast_id in contrasts:
print(f"\tcontrast id: {contrast_id}")
results = fmri_glm.compute_contrast(contrast_id, output_type="all")
plot_stat_map(
results["stat"],
title=contrast_id,
transparency=results["z_score"],
**plot_param,
)
contrast id: faces - scrambled
/home/runner/work/nilearn/nilearn/examples/04_glm_first_level/plot_spm_multimodal_faces.py:134: RuntimeWarning: The same contrast will be used for all 2 runs. If the design matrices are not the same for all runs, (for example with different column names or column order across runs) you should pass contrast as an expression using the name of the conditions as they appear in the design matrices.
results = fmri_glm.compute_contrast(contrast_id, output_type="all")
[FirstLevelModel.compute_contrast] Computing image from signals
[FirstLevelModel.compute_contrast] Computing image from signals
[FirstLevelModel.compute_contrast] Computing image from signals
[FirstLevelModel.compute_contrast] Computing image from signals
[FirstLevelModel.compute_contrast] Computing image from signals
contrast id: scrambled - faces
/home/runner/work/nilearn/nilearn/examples/04_glm_first_level/plot_spm_multimodal_faces.py:134: RuntimeWarning: The same contrast will be used for all 2 runs. If the design matrices are not the same for all runs, (for example with different column names or column order across runs) you should pass contrast as an expression using the name of the conditions as they appear in the design matrices.
results = fmri_glm.compute_contrast(contrast_id, output_type="all")
[FirstLevelModel.compute_contrast] Computing image from signals
[FirstLevelModel.compute_contrast] Computing image from signals
[FirstLevelModel.compute_contrast] Computing image from signals
[FirstLevelModel.compute_contrast] Computing image from signals
[FirstLevelModel.compute_contrast] Computing image from signals
We also define the effects of interest contrast, a 2-dimensional contrasts spanning the two conditions.
import numpy as np
contrasts = np.eye(2)
results = fmri_glm.compute_contrast(contrasts, output_type="all")
plot_stat_map(
results["stat"],
title="effects of interest",
transparency=results["z_score"],
**plot_param,
)
show()

/home/runner/work/nilearn/nilearn/examples/04_glm_first_level/plot_spm_multimodal_faces.py:151: RuntimeWarning: The same contrast will be used for all 2 runs. If the design matrices are not the same for all runs, (for example with different column names or column order across runs) you should pass contrast as an expression using the name of the conditions as they appear in the design matrices.
results = fmri_glm.compute_contrast(contrasts, output_type="all")
/home/runner/work/nilearn/nilearn/examples/04_glm_first_level/plot_spm_multimodal_faces.py:151: UserWarning: F contrasts should have 20 columns, but it has only 2. The rest of the contrast was padded with zeros.
results = fmri_glm.compute_contrast(contrasts, output_type="all")
/home/runner/work/nilearn/nilearn/examples/04_glm_first_level/plot_spm_multimodal_faces.py:151: UserWarning: Running approximate fixed effects on F statistics.
results = fmri_glm.compute_contrast(contrasts, output_type="all")
[FirstLevelModel.compute_contrast] Computing image from signals
[FirstLevelModel.compute_contrast] Computing image from signals
[FirstLevelModel.compute_contrast] Computing image from signals
[FirstLevelModel.compute_contrast] Computing image from signals
[FirstLevelModel.compute_contrast] Computing image from signals
Based on the resulting maps we observe that the analysis results in wide activity for the ‘effects of interest’ contrast, showing the implications of large portions of the visual cortex in the conditions. By contrast, the differential effect between “faces” and “scrambled” involves sparser, more anterior and lateral regions. It also displays some responses in the frontal lobe.
Total running time of the script: (1 minutes 39.900 seconds)
Estimated memory usage: 1028 MB

