Repository: nilearn/nilearn

Issue:
Add Schaefer/Yeo atlas
There is rapidly increasing adoption of the SchaeferYeo atlas now in the imaging neuroscience community. It would be great to add it soon in nilearn.datasets has been precomputed with 100, 200, 300, ... 1000 parcellations including their assignment to the original 7 and 17 Yeo networks.

https://github.com/ThomasYeoLab/CBIG


Discussion:
Sounds great. PR welcome. 

⁣Sent from my phone. Please forgive typos and briefness.​

On Jun 28, 2018, 22:04, at 22:04, Danilo Bzdok <notifications@github.com> wrote:
>There is rapidly increasing adoption of the SchaeferYeo atlas now in
>the imaging neuroscience community. It would be great to add it soon in
>nilearn.datasets has been precomputed with 100, 200, 300, ... 1000
>parcellations including their assignment to the original 7 and 17 Yeo
>networks.
>
>https://github.com/ThomasYeoLab/CBIG
>
>-- 
>You are receiving this because you are subscribed to this thread.
>Reply to this email directly or view it on GitHub:
>https://github.com/nilearn/nilearn/issues/1667

Is anybody working on that? I'd be happy to create a PR.
@fliem Thanks! GO for it! Let us know if you need help.

Resolving patch:
diff --git a/nilearn/datasets/__init__.py b/nilearn/datasets/__init__.py
--- a/nilearn/datasets/__init__.py
+++ b/nilearn/datasets/__init__.py
@@ -24,7 +24,8 @@
                     fetch_atlas_allen_2011,
                     fetch_atlas_surf_destrieux,
                     fetch_atlas_talairach,
-                    fetch_atlas_pauli_2017)
+                    fetch_atlas_pauli_2017,
+                    fetch_atlas_schaefer_2018)
 
 from .utils import get_data_dirs
 from .neurovault import (fetch_neurovault,
@@ -41,6 +42,7 @@
            'fetch_abide_pcp', 'fetch_localizer_calculation_task',
            'fetch_atlas_craddock_2012', 'fetch_atlas_destrieux_2009',
            'fetch_atlas_harvard_oxford', 'fetch_atlas_msdl',
+           'fetch_atlas_schaefer_2018',
            'fetch_coords_power_2011',
            'fetch_atlas_smith_2009',
            'fetch_atlas_allen_2011',
diff --git a/nilearn/datasets/atlas.py b/nilearn/datasets/atlas.py
--- a/nilearn/datasets/atlas.py
+++ b/nilearn/datasets/atlas.py
@@ -1185,3 +1185,107 @@ def fetch_atlas_pauli_2017(version='prob', data_dir=None, verbose=1):
     return Bunch(maps=atlas_file,
                  labels=labels,
                  description=fdescr)
+
+
+
+def fetch_atlas_schaefer_2018(n_rois=400, yeo_networks=7, resolution_mm=1,
+                              data_dir=None, base_url=None, resume=True,
+                              verbose=1):
+    """Download and return file names for the Schaefer 2018 parcellation
+
+    .. versionadded:: 0.5.1
+
+    The provided images are in MNI152 space.
+
+    Parameters
+    ----------
+    n_rois: int
+        number of regions of interest {100, 200, 300, 400 (default), 500, 600,
+        800, 1000}
+
+    yeo_networks: int
+        ROI annotation according to yeo networks {7 (default), 17}
+
+    resolution_mm: int
+        Spatial resolution of atlas image in mm {1 (default), 2}
+
+    data_dir: string
+        directory where data should be downloaded and unpacked.
+
+    base_url: string
+        base_url of files to download (None results in default base_url).
+
+    resume: bool
+        whether to resumed download of a partly-downloaded file.
+
+    verbose: int
+        verbosity level (0 means no message).
+
+    Returns
+    -------
+    data: sklearn.datasets.base.Bunch
+        Dictionary-like object, contains:
+
+        - maps: 3D Nifti image, values are indices in the list of labels.
+        - labels: ROI labels including Yeo-network annotation,list of strings.
+        - description: A short description of the atlas and some references.
+
+    References
+    ----------
+    For more information on this dataset, see
+    https://github.com/ThomasYeoLab/CBIG/tree/v0.8.1-Schaefer2018_LocalGlobal/stable_projects/brain_parcellation/Schaefer2018_LocalGlobal
+
+    Schaefer A, Kong R, Gordon EM, Laumann TO, Zuo XN, Holmes AJ,
+    Eickhoff SB, Yeo BTT. Local-Global parcellation of the human
+    cerebral cortex from intrinsic functional connectivity MRI,
+    Cerebral Cortex, 29:3095-3114, 2018.
+
+    Yeo BT, Krienen FM, Sepulcre J, Sabuncu MR, Lashkari D, Hollinshead M,
+    Roffman JL, Smoller JW, Zollei L., Polimeni JR, Fischl B, Liu H,
+    Buckner RL. The organization of the human cerebral cortex estimated by
+    intrinsic functional connectivity. J Neurophysiol 106(3):1125-65, 2011.
+
+    Licence: MIT.
+    """
+    valid_n_rois = [100, 200, 300, 400, 500, 600, 800, 1000]
+    valid_yeo_networks = [7, 17]
+    valid_resolution_mm = [1, 2]
+    if n_rois not in valid_n_rois:
+        raise ValueError("Requested n_rois={} not available. Valid "
+                         "options: {}".format(n_rois, valid_n_rois))
+    if yeo_networks not in valid_yeo_networks:
+        raise ValueError("Requested yeo_networks={} not available. Valid "
+                         "options: {}".format(yeo_networks,valid_yeo_networks))
+    if resolution_mm not in valid_resolution_mm:
+        raise ValueError("Requested resolution_mm={} not available. Valid "
+                         "options: {}".format(resolution_mm,
+                                              valid_resolution_mm)
+                         )
+
+    if base_url is None:
+        base_url = ('https://raw.githubusercontent.com/ThomasYeoLab/CBIG/'
+                    'v0.8.1-Schaefer2018_LocalGlobal/stable_projects/'
+                    'brain_parcellation/Schaefer2018_LocalGlobal/'
+                    'Parcellations/MNI/'
+                    )
+
+    files = []
+    labels_file_template = 'Schaefer2018_{}Parcels_{}Networks_order.txt'
+    img_file_template = ('Schaefer2018_{}Parcels_'
+                         '{}Networks_order_FSLMNI152_{}mm.nii.gz')
+    for f in [labels_file_template.format(n_rois, yeo_networks),
+              img_file_template.format(n_rois, yeo_networks, resolution_mm)]:
+        files.append((f, base_url + f, {}))
+
+    dataset_name = 'schaefer_2018'
+    data_dir = _get_dataset_dir(dataset_name, data_dir=data_dir,
+                                verbose=verbose)
+    labels_file, atlas_file = _fetch_files(data_dir, files, resume=resume,
+                                           verbose=verbose)
+
+    labels = np.genfromtxt(labels_file, usecols=1, dtype="S", delimiter="\t")
+    fdescr = _get_dataset_descr(dataset_name)
+
+    return Bunch(maps=atlas_file,
+                 labels=labels,
+                 description=fdescr)


Test patch:
diff --git a/nilearn/datasets/tests/test_atlas.py b/nilearn/datasets/tests/test_atlas.py
--- a/nilearn/datasets/tests/test_atlas.py
+++ b/nilearn/datasets/tests/test_atlas.py
@@ -544,3 +544,32 @@ def test_fetch_atlas_pauli_2017():
 
     data = atlas.fetch_atlas_pauli_2017('prob', data_dir)
     assert_equal(nibabel.load(data.maps).shape[-1], 16)
+
+@with_setup(tst.setup_tmpdata, tst.teardown_tmpdata)
+def test_fetch_atlas_schaefer_2018():
+    valid_n_rois = [100, 200, 300, 400, 500, 600, 800, 1000]
+    valid_yeo_networks = [7, 17]
+    valid_resolution_mm = [1, 2]
+
+    assert_raises(ValueError, atlas.fetch_atlas_schaefer_2018, n_rois=44)
+    assert_raises(ValueError, atlas.fetch_atlas_schaefer_2018, yeo_networks=10)
+    assert_raises(ValueError, atlas.fetch_atlas_schaefer_2018, resolution_mm=3)
+
+    for n_rois, yeo_networks, resolution_mm in \
+            itertools.product(valid_n_rois, valid_yeo_networks,
+                              valid_resolution_mm):
+        data = atlas.fetch_atlas_schaefer_2018(n_rois=n_rois,
+                                               yeo_networks=yeo_networks,
+                                               resolution_mm=resolution_mm,
+                                               data_dir=tst.tmpdir,
+                                               verbose=0)
+        assert_not_equal(data.description, '')
+        assert_true(isinstance(data.maps, _basestring))
+        assert_true(isinstance(data.labels, np.ndarray))
+        assert_equal(len(data.labels), n_rois)
+        assert_true(data.labels[0].astype(str).startswith("{}Networks".
+                                              format(yeo_networks)))
+        img = nibabel.load(data.maps)
+        assert_equal(img.header.get_zooms()[0], resolution_mm)
+        assert_true(np.array_equal(np.unique(img.dataobj),
+                                   np.arange(n_rois+1)))