Using brain templates from TemplateFlow

In this example, we see how to fetch and use brain templates from TemplateFlow.

We first see how to fetch and use the Desikan-Killiany (DK) atlas in order to make surface plots.

Then, we see how to get the proper template for the Harvard-Oxford volumetric atlas.

Datasets used in this example

Fetch DK Surface template

TemplateFlow allows for the retrieval of image files, annotations, and metadata for various brain templates. Specific files are accessed via the get function by providing the template name and filtering by file name ‘entities’ such as resolution (res), suffix, atlas, hemisphere (hemi), space, description (desc)…

Tips

TemplateFlow files follow a BIDS filename template and should more less be organized as BIDS template.

If a search matches multiple files, the function returns a list of all matching paths.

Available resources can be explored in the TemplateFlow browser.

import templateflow.api as tflow

from nilearn.surface import SurfaceImage, load_surf_data

template = "fsaverage"

fetched_files = tflow.get(
    template,
    extension="surf.gii",
    suffix="pial",
)
print(fetched_files)
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-L_den-3k_pial.surf.gii

  0%|          | 0.00/66.1k [00:00<?, ?B/s]
100%|██████████| 66.1k/66.1k [00:00<00:00, 993kB/s]
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-L_den-10k_pial.surf.gii

  0%|          | 0.00/271k [00:00<?, ?B/s]
 26%|██▌       | 69.6k/271k [00:00<00:00, 533kB/s]
100%|██████████| 271k/271k [00:00<00:00, 1.37MB/s]
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-L_den-41k_pial.surf.gii

  0%|          | 0.00/1.07M [00:00<?, ?B/s]
  7%|▋         | 69.6k/1.07M [00:00<00:01, 533kB/s]
 37%|███▋      | 400k/1.07M [00:00<00:00, 1.70MB/s]
100%|██████████| 1.07M/1.07M [00:00<00:00, 3.22MB/s]
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-L_den-164k_pial.surf.gii

  0%|          | 0.00/4.34M [00:00<?, ?B/s]
  2%|▏         | 69.6k/4.34M [00:00<00:07, 554kB/s]
  9%|▉         | 383k/4.34M [00:00<00:02, 1.68MB/s]
 28%|██▊       | 1.22M/4.34M [00:00<00:00, 3.93MB/s]
 86%|████████▌ | 3.72M/4.34M [00:00<00:00, 10.2MB/s]
100%|██████████| 4.34M/4.34M [00:00<00:00, 8.46MB/s]
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-R_den-3k_pial.surf.gii

  0%|          | 0.00/66.1k [00:00<?, ?B/s]
100%|██████████| 66.1k/66.1k [00:00<00:00, 1.00MB/s]
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-R_den-10k_pial.surf.gii

  0%|          | 0.00/271k [00:00<?, ?B/s]
 26%|██▋       | 71.7k/271k [00:00<00:00, 548kB/s]
100%|██████████| 271k/271k [00:00<00:00, 1.36MB/s]
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-R_den-41k_pial.surf.gii

  0%|          | 0.00/1.07M [00:00<?, ?B/s]
  7%|▋         | 71.7k/1.07M [00:00<00:01, 569kB/s]
 36%|███▌      | 385k/1.07M [00:00<00:00, 1.88MB/s]
100%|██████████| 1.07M/1.07M [00:00<00:00, 3.34MB/s]
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-R_den-164k_pial.surf.gii

  0%|          | 0.00/4.34M [00:00<?, ?B/s]
  2%|▏         | 69.6k/4.34M [00:00<00:08, 528kB/s]
  8%|▊         | 366k/4.34M [00:00<00:02, 1.53MB/s]
 32%|███▏      | 1.41M/4.34M [00:00<00:00, 4.42MB/s]
100%|██████████| 4.34M/4.34M [00:00<00:00, 9.05MB/s]
[PosixPath('/home/runner/.cache/templateflow/tpl-fsaverage/tpl-fsaverage_hemi-L_den-3k_pial.surf.gii'), PosixPath('/home/runner/.cache/templateflow/tpl-fsaverage/tpl-fsaverage_hemi-L_den-10k_pial.surf.gii'), PosixPath('/home/runner/.cache/templateflow/tpl-fsaverage/tpl-fsaverage_hemi-L_den-41k_pial.surf.gii'), PosixPath('/home/runner/.cache/templateflow/tpl-fsaverage/tpl-fsaverage_hemi-L_den-164k_pial.surf.gii'), PosixPath('/home/runner/.cache/templateflow/tpl-fsaverage/tpl-fsaverage_hemi-R_den-3k_pial.surf.gii'), PosixPath('/home/runner/.cache/templateflow/tpl-fsaverage/tpl-fsaverage_hemi-R_den-10k_pial.surf.gii'), PosixPath('/home/runner/.cache/templateflow/tpl-fsaverage/tpl-fsaverage_hemi-R_den-41k_pial.surf.gii'), PosixPath('/home/runner/.cache/templateflow/tpl-fsaverage/tpl-fsaverage_hemi-R_den-164k_pial.surf.gii')]

In this example, the Desikan-Killiany (DK) atlas is fetched. DK is defined with reference to the FreeSurfer average (fsaverage) template, which is provided at multiple densities (number of vertices per hemisphere): 3k, 10k, 41k, 164k Here, we build a SurfaceImage containing the labels for both hemispheres for the 3k and 10k densities.

used_densities = ["3k", "10k"]
# uncomment the following line in case you want to see all densities
# used_densities = ["3k", "10k", "41k", "164k"]

desikan_dict = {}
for density in ["3k", "10k"]:
    mesh = {}
    data = {}
    for hemi in ["left", "right"]:
        mesh[hemi] = tflow.get(
            template,
            extension="surf.gii",
            suffix="pial",
            density=density,
            hemi=hemi[0].upper(),
        )

        desc = "curated" if density == "164k" else None
        roi_data = load_surf_data(
            tflow.get(
                template,
                atlas="Desikan2006",
                density=density,
                hemi=hemi[0].upper(),
                extension="label.gii",
                desc=desc,
            )
        )
        if density == "164k":
            roi_data[roi_data < 0] = 0

        data[hemi] = roi_data

    desikan_dict[density] = SurfaceImage(mesh=mesh, data=data)
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-L_den-3k_atlas-Desikan2006_seg-aparc_dseg.label.gii

  0%|          | 0.00/6.79k [00:00<?, ?B/s]
100%|██████████| 6.79k/6.79k [00:00<00:00, 11.7MB/s]
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-R_den-3k_atlas-Desikan2006_seg-aparc_dseg.label.gii

  0%|          | 0.00/6.79k [00:00<?, ?B/s]
100%|██████████| 6.79k/6.79k [00:00<00:00, 20.2MB/s]
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-L_den-10k_atlas-Desikan2006_seg-aparc_dseg.label.gii

  0%|          | 0.00/9.61k [00:00<?, ?B/s]
100%|██████████| 9.61k/9.61k [00:00<00:00, 25.3MB/s]
Downloading https://templateflow.s3.amazonaws.com/tpl-fsaverage/tpl-fsaverage_hemi-R_den-10k_atlas-Desikan2006_seg-aparc_dseg.label.gii

  0%|          | 0.00/9.52k [00:00<?, ?B/s]
100%|██████████| 9.52k/9.52k [00:00<00:00, 25.1MB/s]

Plotting the DK atlas

To plot the DK atlas, we also fetch the lookup table (LUT) from TemplateFlow, to map region indices to the original region names and colors. We also use the background sulcal depth map to add more detail to the surface plot. To do this we map the density to the corresponding fsaverage data that Nilearn can fetch directly.

import matplotlib.pyplot as plt

from nilearn.datasets import load_fsaverage_data
from nilearn.plotting import plot_surf_roi, show

_, axes = plt.subplots(1, 2, subplot_kw={"projection": "3d"})

fs_density = {
    "3k": "fsaverage4",
    "10k": "fsaverage5",
    "41k": "fsaverage6",
    "164k": "fsaverage",
}

lut = tflow.get(
    template,
    atlas="Desikan2006",
    suffix="dseg",
    extension="tsv",
)

for ax, density in zip(axes, ["3k", "10k"], strict=True):
    desikan = desikan_dict[density]
    sulcal_depth_map = load_fsaverage_data(
        mesh=fs_density[density], data_type="sulcal"
    )
    plot_surf_roi(
        roi_map=desikan,
        cmap=lut,
        bg_map=sulcal_depth_map,
        bg_on_data=True,
        title=f"DK atlas ({density})",
        axes=ax,
    )
    if density == "10k":
        ax._colorbars[0].remove()

show()
DK atlas (3k), DK atlas (10k)
[load_fsaverage_data] Dataset created in /home/runner/nilearn_data/fsaverage4
[load_fsaverage_data] Downloading data from https://osf.io/28uma/download ...
[load_fsaverage_data]  ...done. (3 seconds, 0 min)

[load_fsaverage_data] Extracting data from /home/runner/nilearn_data/fsaverage4/
8d2777113299ca7de61b16037c37aaea/download...
[load_fsaverage_data] .. done.

[load_fsaverage_data] Dataset found in /home/runner/nilearn_data/fsaverage4

Getting the right template for volumetric atlases

The template used by nilearn to plot volumetric images is ICBM152 2009, release a. However, some atlases are defined on different templates, this is the case for the Harvard-Oxford atlas. This can lead to some imprecisions when plotting volumetric atlases, with regions encompassing non-brain areas.

from nilearn.datasets import fetch_atlas_harvard_oxford
from nilearn.plotting import plot_roi

plotting_params = {
    "view_type": "contours",
    "display_mode": "x",
    "cut_coords": [-4, -2, 0],
    "black_bg": False,
}

harvard_oxford_sub = fetch_atlas_harvard_oxford("sub-maxprob-thr25-1mm")


plot_roi(
    harvard_oxford_sub.filename,
    title="Harvard-Oxford atlas | sub-cortical | ICBM152 2009",
    **plotting_params,
)
plot templateflow
[fetch_atlas_harvard_oxford] Dataset found in /home/runner/nilearn_data/fsl

<nilearn.plotting.displays._slicers.XSlicer object at 0x7fc317bca110>

This is because the template of the Harvard-Oxford atlas is:

print(f"Harvard-Oxford atlas template: {harvard_oxford_sub.template}")
Harvard-Oxford atlas template: MNI152NLin6Asym

Getting a template

If you want to visualize the Harvard-Oxford atlas on the template it was originally defined, you can get it from TemplateFlow. This template is the default template used by FSL, and its unique identifier within TemplateFlow is`MNI152NLin6Asym`.

template = "MNI152NLin6Asym"
resolution = "01"

MNI152NLin6Asym_template_img = tflow.get(
    template,
    resolution=resolution,
    suffix="T1w",
    desc="brain",  # Set desc-brain to get the skull-stripped variant
    extension="nii.gz",
)

print(f"{MNI152NLin6Asym_template_img=}")

plot_roi(
    harvard_oxford_sub.filename,
    title="Harvard-Oxford atlas | sub-cortical | MNI152NLin6Asym",
    bg_img=MNI152NLin6Asym_template_img,
    **plotting_params,
)

show()
plot templateflow
Downloading https://templateflow.s3.amazonaws.com/tpl-MNI152NLin6Asym/tpl-MNI152NLin6Asym_res-01_desc-brain_T1w.nii.gz

  0%|          | 0.00/3.29M [00:00<?, ?B/s]
  2%|▏         | 69.6k/3.29M [00:00<00:05, 538kB/s]
 12%|█▏        | 400k/3.29M [00:00<00:01, 1.70MB/s]
 52%|█████▏    | 1.70M/3.29M [00:00<00:00, 5.46MB/s]
100%|██████████| 3.29M/3.29M [00:00<00:00, 8.03MB/s]
MNI152NLin6Asym_template_img=PosixPath('/home/runner/.cache/templateflow/tpl-MNI152NLin6Asym/tpl-MNI152NLin6Asym_res-01_desc-brain_T1w.nii.gz')

Total running time of the script: (0 minutes 25.266 seconds)

Estimated memory usage: 187 MB

Gallery generated by Sphinx-Gallery