Repository: nilearn/nilearn

Issue:
Optimize masker and GLM reports in the doc build
1. Generating all the maskers / GLM reports takes at least 4 minutes (more if we include the data download time)
 
- there should be a way to speed this up.

2. Sometimes the documentation build will fail because the maskers and GLM reports cannot be built.

https://github.com/nilearn/nilearn/actions/runs/8194633995/job/22411144135#step:34:122

This seems to because the script that builds them needs to download datasets, atlases... And this may fail (same reason as to why we mock things for the fetchers in the test suite).

To minimize how often that happens we could:
- only build those reports when a full build of the doc is done (on `main` or for a commit with `[full doc]` in the message
- rely on the caching of the data between builds (should be doable given that the data is already cached in the build_doc workflow)



Discussion:

Resolving patch:
diff --git a/doc/conf.py b/doc/conf.py
--- a/doc/conf.py
+++ b/doc/conf.py
@@ -162,7 +162,7 @@
 # modindex_common_prefix = []
 
 # A list of warning types to suppress arbitrary warning messages
-suppress_warnings = ["image.not_readable"]
+suppress_warnings = ["image.not_readable", "config.cache"]
 
 # -- Options for HTML output -------------------------------------------------
 
diff --git a/doc/get_data_examples.py b/doc/get_data_examples.py
new file mode 100644
--- /dev/null
+++ b/doc/get_data_examples.py
@@ -0,0 +1,123 @@
+"""Downloads the data for building the reports and the examples."""
+
+import sys
+
+from nilearn import datasets
+
+
+def main(args=sys.argv) -> None:
+
+    build_type = args[1] if len(args) > 1 else "partial"
+
+    print(f"Getting data for a build: {build_type}")
+
+    # %%
+    # Even on partial build of the doc,
+    # the reports for GLM and maskers need to be built.
+    # See doc/visual_testing/reporter_visual_inspection_suite.py
+    # The following section downloads the necessary data for this.
+
+    datasets.fetch_icbm152_2009()
+
+    datasets.fetch_atlas_difumo(
+        dimension=64, resolution_mm=2, legacy_format=False
+    )
+    datasets.fetch_atlas_msdl()
+    datasets.fetch_atlas_schaefer_2018()
+    datasets.fetch_atlas_yeo_2011()
+
+    _, urls = datasets.fetch_ds000030_urls()
+    exclusion_patterns = [
+        "*group*",
+        "*phenotype*",
+        "*mriqc*",
+        "*parameter_plots*",
+        "*physio_plots*",
+        "*space-fsaverage*",
+        "*space-T1w*",
+        "*dwi*",
+        "*beh*",
+        "*task-bart*",
+        "*task-rest*",
+        "*task-scap*",
+        "*task-task*",
+    ]
+    urls = datasets.select_from_index(
+        urls, exclusion_filters=exclusion_patterns, n_subjects=1
+    )
+    datasets.fetch_openneuro_dataset(urls=urls)
+
+    datasets.fetch_adhd(n_subjects=1)
+    datasets.fetch_development_fmri(n_subjects=5)
+    datasets.fetch_fiac_first_level()
+    datasets.fetch_miyawaki2008()
+    datasets.fetch_oasis_vbm(n_subjects=5)
+
+    if build_type in ["full", "html", "html-strict"]:
+        # On full build of the doc we get all the data
+        # needed for building all the examples.
+
+        datasets.fetch_atlas_allen_2011()
+        datasets.fetch_atlas_surf_destrieux()
+        for resolution in [64, 197, 444]:
+            datasets.fetch_atlas_basc_multiscale_2015(
+                version="sym", resolution=resolution
+            )
+        datasets.fetch_atlas_destrieux_2009()
+        datasets.fetch_atlas_harvard_oxford("cort-maxprob-thr25-2mm")
+        datasets.fetch_atlas_juelich("maxprob-thr0-1mm")
+        for dimension in [10, 20]:
+            datasets.fetch_atlas_smith_2009(resting=False, dimension=dimension)
+        datasets.fetch_atlas_yeo_2011()
+
+        datasets.fetch_surf_fsaverage()
+        datasets.fetch_surf_fsaverage("fsaverage")
+
+        datasets.load_mni152_brain_mask(resolution=2)
+        datasets.fetch_icbm152_brain_gm_mask()
+
+        datasets.load_sample_motor_activation_image()
+
+        datasets.fetch_coords_power_2011()
+        datasets.fetch_coords_dosenbach_2010()
+
+        datasets.fetch_development_fmri(n_subjects=60)
+
+        datasets.fetch_haxby()
+        datasets.fetch_language_localizer_demo_dataset()
+        datasets.fetch_localizer_button_task()
+        datasets.fetch_localizer_calculation_task(n_subjects=20)
+        for contrast, n_subjects in zip(
+            [
+                "vertical checkerboard",
+                "horizontal checkerboard",
+                "left vs right button press",
+                "left button press (auditory cue)",
+            ],
+            [16, 16, 16, 94],
+        ):
+            datasets.fetch_localizer_contrasts(
+                contrasts=[contrast],
+                n_subjects=n_subjects,
+            )
+        datasets.fetch_localizer_first_level()
+        datasets.fetch_neurovault_motor_task()
+        datasets.fetch_neurovault_ids(
+            image_ids=(151, 3041, 3042, 2676, 2675, 2818, 2834)
+        )
+        datasets.fetch_neurovault(max_images=30, fetch_neurosynth_words=True)
+        datasets.fetch_neurovault_auditory_computation_task()
+        datasets.fetch_megatrawls_netmats(
+            dimensionality=300,
+            timeseries="eigen_regression",
+            matrices="partial_correlation",
+        )
+        datasets.fetch_mixed_gambles(n_subjects=16)
+        datasets.fetch_oasis_vbm(n_subjects=100)
+        datasets.fetch_spm_multimodal_fmri()
+        datasets.fetch_spm_auditory()
+        datasets.fetch_surf_nki_enhanced(n_subjects=1)
+
+
+if __name__ == "__main__":
+    main()


Test patch: