Run an image-based meta-analysis (IBMA) workflow

NiMARE provides a plethora of tools for performing meta-analyses on neuroimaging data. Sometimes it’s difficult to know where to start, especially if you’re new to meta-analysis. This tutorial will walk you through using a IBMA workflow function which puts together the fundamental steps of a IBMA meta-analysis.

import os
from pathlib import Path

import matplotlib.pyplot as plt
from nilearn.plotting import plot_stat_map

from nimare.extract import download_nidm_pain

Download data

Load Studyset

from nimare.nimads import Studyset
from nimare.utils import get_resource_path

studyset_file = os.path.join(get_resource_path(), "nidm_pain_studyset.json")
studyset = Studyset(studyset_file, target="mni152_2mm")
studyset.update_path(dset_dir)
'<Studyset: nimads_from_dataset>'

Run IBMA Workflow

The fit method of a IBMA workflow class runs the following steps:

  1. Runs a meta-analysis using the specified method (default: Stouffers)

  2. Applies a corrector to the meta-analysis results (default: FDRCorrector, indep)

  3. Generates cluster tables and runs diagnostics on the corrected results (default: Jackknife)

All in one call!

from nimare.workflows.ibma import IBMAWorkflow

workflow = IBMAWorkflow()
result = workflow.fit(studyset)
/home/docs/checkouts/readthedocs.org/user_builds/nimare/checkouts/latest/nimare/transforms.py:310: UserWarning: imgs are being resampled to the mask_img resolution. This process is memory intensive. You might want to provide a target_affine that is equal to the affine of the imgs or resample the mask beforehand to save memory and computation time.
  t = masker.transform(available_data["t"])
/home/docs/checkouts/readthedocs.org/user_builds/nimare/envs/latest/lib/python3.13/site-packages/nilearn/image/image.py:540: RuntimeWarning: overflow encountered in scalar negative
  infinity_norm = max(-data.min(), data.max())
/home/docs/checkouts/readthedocs.org/user_builds/nimare/checkouts/latest/nimare/transforms.py:310: UserWarning: imgs are being resampled to the mask_img resolution. This process is memory intensive. You might want to provide a target_affine that is equal to the affine of the imgs or resample the mask beforehand to save memory and computation time.
  t = masker.transform(available_data["t"])
/home/docs/checkouts/readthedocs.org/user_builds/nimare/envs/latest/lib/python3.13/site-packages/nilearn/image/image.py:540: RuntimeWarning: overflow encountered in scalar negative
  infinity_norm = max(-data.min(), data.max())
/home/docs/checkouts/readthedocs.org/user_builds/nimare/checkouts/latest/nimare/transforms.py:310: UserWarning: imgs are being resampled to the mask_img resolution. This process is memory intensive. You might want to provide a target_affine that is equal to the affine of the imgs or resample the mask beforehand to save memory and computation time.
  t = masker.transform(available_data["t"])
/home/docs/checkouts/readthedocs.org/user_builds/nimare/envs/latest/lib/python3.13/site-packages/nilearn/image/image.py:540: RuntimeWarning: overflow encountered in scalar negative
  infinity_norm = max(-data.min(), data.max())
/home/docs/checkouts/readthedocs.org/user_builds/nimare/checkouts/latest/nimare/transforms.py:310: UserWarning: imgs are being resampled to the mask_img resolution. This process is memory intensive. You might want to provide a target_affine that is equal to the affine of the imgs or resample the mask beforehand to save memory and computation time.
  t = masker.transform(available_data["t"])
/home/docs/checkouts/readthedocs.org/user_builds/nimare/envs/latest/lib/python3.13/site-packages/nilearn/image/image.py:540: RuntimeWarning: overflow encountered in scalar negative
  infinity_norm = max(-data.min(), data.max())
/home/docs/checkouts/readthedocs.org/user_builds/nimare/checkouts/latest/nimare/transforms.py:310: UserWarning: imgs are being resampled to the mask_img resolution. This process is memory intensive. You might want to provide a target_affine that is equal to the affine of the imgs or resample the mask beforehand to save memory and computation time.
  t = masker.transform(available_data["t"])
/home/docs/checkouts/readthedocs.org/user_builds/nimare/envs/latest/lib/python3.13/site-packages/nilearn/image/image.py:540: RuntimeWarning: overflow encountered in scalar negative
  infinity_norm = max(-data.min(), data.max())
/home/docs/checkouts/readthedocs.org/user_builds/nimare/checkouts/latest/nimare/transforms.py:310: UserWarning: imgs are being resampled to the mask_img resolution. This process is memory intensive. You might want to provide a target_affine that is equal to the affine of the imgs or resample the mask beforehand to save memory and computation time.
  t = masker.transform(available_data["t"])
/home/docs/checkouts/readthedocs.org/user_builds/nimare/envs/latest/lib/python3.13/site-packages/nilearn/image/image.py:540: RuntimeWarning: overflow encountered in scalar negative
  infinity_norm = max(-data.min(), data.max())
/home/docs/checkouts/readthedocs.org/user_builds/nimare/checkouts/latest/nimare/transforms.py:310: UserWarning: imgs are being resampled to the mask_img resolution. This process is memory intensive. You might want to provide a target_affine that is equal to the affine of the imgs or resample the mask beforehand to save memory and computation time.
  t = masker.transform(available_data["t"])
/home/docs/checkouts/readthedocs.org/user_builds/nimare/envs/latest/lib/python3.13/site-packages/nilearn/image/image.py:540: RuntimeWarning: overflow encountered in scalar negative
  infinity_norm = max(-data.min(), data.max())
/home/docs/checkouts/readthedocs.org/user_builds/nimare/checkouts/latest/nimare/transforms.py:310: UserWarning: imgs are being resampled to the mask_img resolution. This process is memory intensive. You might want to provide a target_affine that is equal to the affine of the imgs or resample the mask beforehand to save memory and computation time.
  t = masker.transform(available_data["t"])
/home/docs/checkouts/readthedocs.org/user_builds/nimare/envs/latest/lib/python3.13/site-packages/nilearn/image/image.py:540: RuntimeWarning: overflow encountered in scalar negative
  infinity_norm = max(-data.min(), data.max())
/home/docs/checkouts/readthedocs.org/user_builds/nimare/checkouts/latest/nimare/transforms.py:310: UserWarning: imgs are being resampled to the mask_img resolution. This process is memory intensive. You might want to provide a target_affine that is equal to the affine of the imgs or resample the mask beforehand to save memory and computation time.
  t = masker.transform(available_data["t"])
/home/docs/checkouts/readthedocs.org/user_builds/nimare/envs/latest/lib/python3.13/site-packages/nilearn/image/image.py:540: RuntimeWarning: overflow encountered in scalar negative
  infinity_norm = max(-data.min(), data.max())
/home/docs/checkouts/readthedocs.org/user_builds/nimare/checkouts/latest/nimare/transforms.py:310: UserWarning: imgs are being resampled to the mask_img resolution. This process is memory intensive. You might want to provide a target_affine that is equal to the affine of the imgs or resample the mask beforehand to save memory and computation time.
  t = masker.transform(available_data["t"])
/home/docs/checkouts/readthedocs.org/user_builds/nimare/envs/latest/lib/python3.13/site-packages/nilearn/image/image.py:540: RuntimeWarning: overflow encountered in scalar negative
  infinity_norm = max(-data.min(), data.max())
/home/docs/checkouts/readthedocs.org/user_builds/nimare/checkouts/latest/nimare/diagnostics.py:174: UserWarning: Attention: At least one of the (sub)peaks falls outside of the cluster body. Identifying the nearest in-cluster voxel.
  result = get_clusters_table(

  0%|          | 0/21 [00:00<?, ?it/s]
  5%|▍         | 1/21 [00:01<00:31,  1.57s/it]
 10%|▉         | 2/21 [00:03<00:30,  1.58s/it]
 14%|█▍        | 3/21 [00:04<00:28,  1.59s/it]
 19%|█▉        | 4/21 [00:06<00:26,  1.58s/it]
 24%|██▍       | 5/21 [00:07<00:25,  1.58s/it]
 29%|██▊       | 6/21 [00:09<00:23,  1.58s/it]
 33%|███▎      | 7/21 [00:11<00:22,  1.58s/it]
 38%|███▊      | 8/21 [00:12<00:20,  1.58s/it]
 43%|████▎     | 9/21 [00:14<00:18,  1.58s/it]
 48%|████▊     | 10/21 [00:15<00:17,  1.58s/it]
 52%|█████▏    | 11/21 [00:17<00:15,  1.52s/it]
 57%|█████▋    | 12/21 [00:18<00:13,  1.46s/it]
 62%|██████▏   | 13/21 [00:19<00:11,  1.41s/it]
 67%|██████▋   | 14/21 [00:21<00:09,  1.38s/it]
 71%|███████▏  | 15/21 [00:22<00:08,  1.36s/it]
 76%|███████▌  | 16/21 [00:23<00:06,  1.35s/it]
 81%|████████  | 17/21 [00:25<00:05,  1.35s/it]
 86%|████████▌ | 18/21 [00:26<00:04,  1.33s/it]
 90%|█████████ | 19/21 [00:27<00:02,  1.32s/it]
 95%|█████████▌| 20/21 [00:29<00:01,  1.32s/it]
100%|██████████| 21/21 [00:30<00:00,  1.31s/it]
100%|██████████| 21/21 [00:30<00:00,  1.44s/it]

Plot Results

The fit method of the IBMA workflow class returns a MetaResult object, where you can access the corrected results of the meta-analysis and diagnostics tables.

Corrected map:

img = result.get_map("z_corr-FDR_method-indep")
plot_stat_map(
    img,
    cut_coords=4,
    display_mode="z",
    threshold=1.65,  # voxel_thresh p < .05, one-tailed
    cmap="RdBu_r",
    symmetric_cbar=True,
    vmax=4,
)
plt.show()
12 plot ibma workflow

Clusters table

result.tables["z_corr-FDR_method-indep_tab-clust"]
Cluster ID X Y Z Peak Stat Cluster Size (mm3)
0 PositiveTail 1 -60.0 -24.0 20.0 13.838863 1061856
1 PositiveTail 1a -52.0 -2.0 2.0 13.838863
2 PositiveTail 1b -38.0 -20.0 12.0 13.838863
3 PositiveTail 1c -38.0 6.0 -2.0 13.838863
4 PositiveTail 2 18.0 -4.0 -44.0 2.974257 336
5 PositiveTail 3 16.0 20.0 -24.0 2.902997 272
6 PositiveTail 4 40.0 -22.0 -34.0 2.550179 128
7 PositiveTail 5 -26.0 -8.0 -44.0 2.318065 120
8 NegativeTail 9 -4.0 36.0 -20.0 -9.574484 99400
9 NegativeTail 9a 2.0 30.0 -22.0 -9.047873
10 NegativeTail 9b -4.0 52.0 -14.0 -9.004929
11 NegativeTail 9c 2.0 50.0 -20.0 -8.973850
12 NegativeTail 10 -8.0 -56.0 8.0 -8.171700 22960
13 NegativeTail 10a 8.0 -54.0 8.0 -5.422620
14 NegativeTail 10b 22.0 -82.0 36.0 -4.259807
15 NegativeTail 10c 48.0 -66.0 22.0 -4.258718
16 NegativeTail 11 -24.0 -12.0 -28.0 -8.151698 11776
17 NegativeTail 11a -32.0 -36.0 -20.0 -7.748513
18 NegativeTail 12 20.0 -10.0 -28.0 -7.593386 13816
19 NegativeTail 12a 26.0 -42.0 -18.0 -6.360453
20 NegativeTail 12b 32.0 -46.0 -4.0 -4.242728
21 NegativeTail 12c 26.0 -40.0 6.0 -3.246375
22 NegativeTail 13 60.0 -4.0 22.0 -7.280138 16512
23 NegativeTail 13a 48.0 -24.0 52.0 -6.637193
24 NegativeTail 13b 58.0 -10.0 34.0 -6.139315
25 NegativeTail 13c 46.0 -18.0 44.0 -5.735124
26 NegativeTail 14 60.0 -6.0 -28.0 -7.008846 13912
27 NegativeTail 14a 58.0 -10.0 -12.0 -5.147785
28 NegativeTail 14b 66.0 -24.0 -2.0 -4.921708
29 NegativeTail 14c 56.0 2.0 -34.0 -4.714153
30 NegativeTail 15 -56.0 -14.0 -22.0 -6.957302 30408
31 NegativeTail 15a -52.0 12.0 -36.0 -6.559181
32 NegativeTail 15b -46.0 32.0 -18.0 -6.060843
33 NegativeTail 15c -54.0 -2.0 -30.0 -5.893809
34 NegativeTail 16 -50.0 -10.0 28.0 -6.665865 17496
35 NegativeTail 16a -44.0 -24.0 56.0 -5.773709
36 NegativeTail 16b -40.0 -22.0 64.0 -4.916386
37 NegativeTail 16c -66.0 -6.0 20.0 -4.629650
38 NegativeTail 17 -48.0 -66.0 26.0 -6.495798 8896
39 NegativeTail 17a -26.0 -80.0 38.0 -2.462854
40 NegativeTail 18 4.0 -28.0 60.0 -3.683875 1864
41 NegativeTail 18a 8.0 -32.0 68.0 -3.133207
42 NegativeTail 18b -6.0 -26.0 56.0 -2.093511
43 NegativeTail 19 0.0 8.0 -30.0 -3.209842 80
44 NegativeTail 20 26.0 12.0 -34.0 -2.739914 336
45 NegativeTail 20a 24.0 18.0 -28.0 -2.168240
46 NegativeTail 20b 24.0 18.0 -40.0 -2.126635
47 NegativeTail 21 28.0 26.0 -24.0 -2.736057 304
48 NegativeTail 21a 34.0 32.0 -22.0 -2.685497
49 NegativeTail 22 26.0 -64.0 60.0 -2.577298 224
50 NegativeTail 23 -20.0 -84.0 24.0 -2.560723 352
51 NegativeTail 23a -12.0 -86.0 26.0 -1.982633


Contribution table

result.tables["z_corr-FDR_method-indep_diag-Jackknife_tab-counts"]
id PositiveTail 1 PositiveTail 2 PositiveTail 3 PositiveTail 4 PositiveTail 5 NegativeTail 1 NegativeTail 2 NegativeTail 3 NegativeTail 4 NegativeTail 5 NegativeTail 6 NegativeTail 7 NegativeTail 8 NegativeTail 9 NegativeTail 10 NegativeTail 11 NegativeTail 12 NegativeTail 13 NegativeTail 14 NegativeTail 15
0 pain_01.nidm-1 0.227038 0.053888 0.713247 0.161265 -0.530519 -0.011508 0.190128 -0.007694 -0.002851 0.078681 0.112056 -0.013947 -0.109232 -0.123624 -0.957183 0.484816 0.800158 -0.172805 -0.678508 0.830867
1 pain_02.nidm-1 0.227038 0.053888 0.713247 0.161265 -0.530519 -0.011508 0.190128 -0.007694 -0.002851 0.078681 0.112056 -0.013947 -0.109232 -0.123624 -0.957183 0.484816 0.800158 -0.172805 -0.678508 0.830867
2 pain_03.nidm-1 0.227038 0.053888 0.713247 0.161265 -0.530519 -0.011508 0.190128 -0.007694 -0.002851 0.078681 0.112056 -0.013947 -0.109232 -0.123624 -0.957183 0.484816 0.800158 -0.172805 -0.678508 0.830867
3 pain_04.nidm-1 0.227038 0.053888 0.713247 0.161265 -0.530519 -0.011508 0.190128 -0.007694 -0.002851 0.078681 0.112056 -0.013947 -0.109232 -0.123624 -0.957183 0.484816 0.800158 -0.172805 -0.678508 0.830867
4 pain_05.nidm-1 0.227038 0.053888 0.713247 0.161265 -0.530519 -0.011508 0.190128 -0.007694 -0.002851 0.078681 0.112056 -0.013947 -0.109232 -0.123624 -0.957183 0.484816 0.800158 -0.172805 -0.678508 0.830867
5 pain_06.nidm-1 0.227038 0.053888 0.713247 0.161265 -0.530519 -0.011508 0.190128 -0.007694 -0.002851 0.078681 0.112056 -0.013947 -0.109232 -0.123624 -0.957183 0.484816 0.800158 -0.172805 -0.678508 0.830867
6 pain_07.nidm-1 0.227038 0.053888 0.713247 0.161265 -0.530519 -0.011508 0.190128 -0.007694 -0.002851 0.078681 0.112056 -0.013947 -0.109232 -0.123624 -0.957183 0.484816 0.800158 -0.172805 -0.678508 0.830867
7 pain_08.nidm-1 0.227038 0.053888 0.713247 0.161265 -0.530519 -0.011508 0.190128 -0.007694 -0.002851 0.078681 0.112056 -0.013947 -0.109232 -0.123624 -0.957183 0.484816 0.800158 -0.172805 -0.678508 0.830867
8 pain_09.nidm-1 0.227038 0.053888 0.713247 0.161265 -0.530519 -0.011508 0.190128 -0.007694 -0.002851 0.078681 0.112056 -0.013947 -0.109232 -0.123624 -0.957183 0.484816 0.800158 -0.172805 -0.678508 0.830867
9 pain_10.nidm-1 0.227038 0.053888 0.713247 0.161265 -0.530519 -0.011508 0.190128 -0.007694 -0.002851 0.078681 0.112056 -0.013947 -0.109232 -0.123624 -0.957183 0.484816 0.800158 -0.172805 -0.678508 0.830867
10 pain_11.nidm-1 0.288896 -0.111884 0.566922 0.154485 -0.662841 -0.053061 0.096778 -0.033009 -0.042245 0.076363 0.067493 -0.021443 -0.170809 -0.263961 -1.229116 0.595712 0.813344 -0.176819 -0.908259 0.741644
11 pain_12.nidm-1 0.289857 0.454738 0.886899 0.348907 -0.127901 0.020723 0.336792 0.048133 0.088428 0.151312 0.237752 0.069474 -0.055674 0.011404 -0.693874 0.686323 0.811645 -0.337087 -0.597269 1.084658
12 pain_13.nidm-1 0.22794 -0.06892 0.621699 -0.034439 -0.574284 0.235983 0.527454 0.262999 0.155342 0.321766 0.406361 0.317211 0.256632 0.276523 -0.52302 0.523216 1.000444 0.167231 -0.080303 1.077859
13 pain_14.nidm-1 0.353301 0.096014 0.670173 -0.023832 -0.620198 0.02248 0.156979 0.005584 -0.001536 0.224448 0.084511 -0.058568 -0.010107 -0.094652 -0.697007 0.456755 0.621153 -0.079577 -0.851382 0.742985
14 pain_15.nidm-1 0.263222 0.181421 0.75986 0.374965 -0.125934 0.062179 0.30247 0.141471 0.157542 0.172686 0.207759 0.105128 -0.064718 -0.019181 -0.888015 0.484816 0.984628 0.01334 -0.231692 0.750787
15 pain_16.nidm-1 0.24564 0.107775 0.739502 0.38533 -0.369429 0.118381 0.291071 0.188121 0.191876 0.153612 0.266289 0.142162 -0.042339 0.033289 -0.727878 0.503749 0.872251 0.130459 -0.242239 0.754209
16 pain_17.nidm-1 0.28886 0.09067 0.762354 0.123562 -0.20913 -0.077934 0.1019 -0.082929 -0.095626 -0.034442 0.057787 -0.059778 -0.274007 -0.240736 -1.218859 0.481838 0.738614 -0.412554 -0.880082 1.092501
17 pain_18.nidm-1 0.189606 0.159384 0.720414 0.201679 -0.498928 0.012384 0.240595 0.017468 0.028959 0.103294 0.106935 0.004956 -0.085112 -0.172656 -1.037171 0.484816 0.865236 -0.099154 -0.746177 0.873206
18 pain_19.nidm-1 0.241514 0.168867 0.807414 0.337392 -0.510576 0.077526 0.3489 0.04515 0.090573 0.063959 0.16403 0.042775 0.070602 0.062976 -0.642044 0.612505 0.840786 -0.141559 -0.254083 0.939576
19 pain_20.nidm-1 0.306831 0.122968 0.832963 0.399574 -0.491264 -0.07121 -0.01998 -0.114657 -0.10599 -0.002821 -0.044147 -0.131255 -0.18823 -0.248792 -1.062522 0.484816 0.79631 -0.211039 -0.984708 0.619934
20 pain_21.nidm-1 0.234422 0.016523 0.679777 0.138927 -0.686936 0.099786 0.129902 -0.00445 -0.031885 0.159774 0.194179 0.046619 0.019514 -0.071071 -0.70803 0.464838 0.841468 -0.040227 -0.673606 0.765129


Report

Finally, a NiMARE report is generated from the MetaResult.

from nimare.reports.base import run_reports

# root_dir = Path(os.getcwd()).parents[1] / "docs" / "_build"
# Use the previous root to run the documentation locally.
root_dir = Path(os.getcwd()).parents[1] / "_readthedocs"
html_dir = root_dir / "html" / "auto_examples" / "02_meta-analyses" / "12_plot_ibma_workflow"
html_dir.mkdir(parents=True, exist_ok=True)

run_reports(result, html_dir)
/home/docs/checkouts/readthedocs.org/user_builds/nimare/checkouts/latest/nimare/reports/figures.py:688: UserWarning: kwargs['alpha']=0.7 detected in parameters.
Overriding with transparency=None.
To suppress this warning pass your 'alpha' value via the 'transparency' parameter.
  fig = plot_img(

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

Gallery generated by Sphinx-Gallery