<jupyter_start><jupyter_text>Multiple Comparisons Correction<jupyter_code># First, import the necessary modules and functions
import os

import matplotlib.pyplot as plt
from myst_nb import glue
from nilearn import plotting
from repo2data.repo2data import Repo2Data

# Install the data if running locally, or points to cached data if running on neurolibre
DATA_REQ_FILE = os.path.abspath("../binder/data_requirement.json")
repo2data = Repo2Data(DATA_REQ_FILE)
data_path = repo2data.install()
data_path = os.path.join(data_path[0], "data")

# Set an output directory for any files generated during the book building process
out_dir = os.path.abspath("../outputs/")
os.makedirs(out_dir, exist_ok=True)<jupyter_output>---- repo2data starting ----
/home/data/nbc/misc-projects/Salo_NiMARE/conda_env/lib/python3.7/site-packages/repo2data
Config from file :
/home/data/nbc/misc-projects/Salo_NiMARE/binder/data_requirement.json
Destination:
./../data/nimare-paper

Info : ./../data/nimare-paper already downloaded<jupyter_text>In NiMARE, multiple comparisons correction is separated from each CBMA and IBMA `Estimator`, so that any number of relevant correction methods can be applied after the `Estimator` has been fit to the `Dataset`.Some correction options, such as the `montecarlo` option for FWE correction, are designed to work specifically with a given `Estimator` (and are indeed implemented within the `Estimator` class, and only called by the `Corrector`).`Corrector`s are divided into two subclasses: `FWECorrector`s, which correct based on family-wise error rate, and `FDRCorrector`s, which correct based on false discovery rate.All `Corrector`s are initialized with a number of parameters, including the correction method that will be used.After that, you can use the `transform` method on a `MetaResult` object produced by a CBMA or IBMA `Estimator` to apply the correction method.This will return an updated `MetaResult` object, with both the statistical maps from the original `MetaResult`, as well as new, corrected maps.Here we will apply both FWE and FDR correction to results from a MKDADensity meta-analysis, performed back in [](content:cbma:mkdad).```{warning}In the following example, we use 5000 iterations for Monte Carlo FWE correction.Normally, one would use at least 10000 iterations, but we reduced this for the sake of speed.```<jupyter_code>from nimare import meta, correct

mkdad_meta = meta.cbma.mkda.MKDADensity.load(os.path.join(data_path, "MKDADensity.pkl.gz"))

mc_corrector = correct.FWECorrector(method="montecarlo", n_iters=5000, n_cores=4)
mc_results = mc_corrector.transform(mkdad_meta.results)
mc_results.save_maps(output_dir=out_dir, prefix="MKDADensity_FWE")

fdr_corrector = correct.FDRCorrector(method="indep")
fdr_results = fdr_corrector.transform(mkdad_meta.results)<jupyter_output>INFO:nimare.correct:Using correction method implemented in Estimator: nimare.meta.cbma.mkda.MKDADensity.correct_fwe_montecarlo.<jupyter_text>Statistical maps saved by NiMARE `MetaResult`s automatically follow a naming convention based loosely on the Brain Imaging Data Standard (BIDS).Let's take a look at the files created by the `FWECorrector`.<jupyter_code>from glob import glob

fwe_maps = sorted(glob(os.path.join(out_dir, "MKDADensity_FWE*.nii.gz")))
fwe_maps = [os.path.basename(fwe_map) for fwe_map in fwe_maps]
print("\n".join(fwe_maps))<jupyter_output>MKDADensity_FWE_logp_desc-mass_level-cluster_corr-FWE_method-montecarlo.nii.gz
MKDADensity_FWE_logp_desc-size_level-cluster_corr-FWE_method-montecarlo.nii.gz
MKDADensity_FWE_logp_level-voxel_corr-FWE_method-montecarlo.nii.gz
MKDADensity_FWE_p.nii.gz
MKDADensity_FWE_stat.nii.gz
MKDADensity_FWE_z.nii.gz
MKDADensity_FWE_z_desc-mass_level-cluster_corr-FWE_method-montecarlo.nii.gz
MKDADensity_FWE_z_desc-size_level-cluster_corr-FWE_method-montecarlo.nii.gz
MKDADensity_FWE_z_level-voxel_corr-FWE_method-montecarlo.nii.gz<jupyter_text>If you ignore the prefix, which was specified in the call to `MetaResult.save_maps`, the maps all have a common naming convention.The maps from the original meta-analysis (before multiple comparisons correction) are simply named according to the values contained in the map (e.g., `z`, `stat`, `p`).Maps generated by the correction method, however, use a series of key-value pairs to indicate how they were generated.The `corr` key indicates whether FWE or FDR correction was applied.The `method` key reflects the correction method employed, which was defined by the `method` parameter used to create the `Corrector`.The `level` key simply indicates if the map was corrected at the voxel or cluster level.Finally, the `desc` key reflects any necessary description that goes beyond what is already covered by the other entities.<jupyter_code>meta_results = {
    "Cluster-level Monte Carlo": mc_results.get_map(
        "z_desc-size_level-cluster_corr-FWE_method-montecarlo",
        return_type="image",
    ),
    "Independent FDR": fdr_results.get_map(
        "z_corr-FDR_method-indep",
        return_type="image",
    ),
}

fig, axes = plt.subplots(figsize=(6, 4), nrows=2)

for i_meta, (name, file_) in enumerate(meta_results.items()):
    display = plotting.plot_stat_map(
        file_,
        annotate=False,
        axes=axes[i_meta],
        draw_cross=False,
        cmap="Reds",
        cut_coords=[0, 0, 0],
        figure=fig,
    )
    axes[i_meta].set_title(name)

    colorbar = display._cbar
    colorbar_ticks = colorbar.get_ticks()
    if colorbar_ticks[0] < 0:
        new_ticks = [colorbar_ticks[0], 0, colorbar_ticks[-1]]
    else:
        new_ticks = [colorbar_ticks[0], colorbar_ticks[-1]]
    colorbar.set_ticks(new_ticks, update_ticks=True)

glue("figure_corr_cbma", fig, display=False)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09054640069384215, 'fraction_numerical': 0.006591500433651344, 'mean_word_length': 5.420935412026726, 'pattern_counts': {'":': 2, '<': 15, '<?xml version=': 0, '>': 14, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '76499', 'license': 'MIT', 'n_tokens_mistral': 1975, 'n_tokens_neox': 1882, 'n_words': 528, 'path': 'content/_build/jupyter_execute/07_correction.ipynb', 'repo_name': 'ltetrel/nimare-paper', 'size': '5765'}