Repository: nilearn/nilearn

Issue:
Function name fetch_atlas_aal_spm_12 is too specific
If we want to update the atlas to a new version, we will break all the existing scripts. We should change it to `fetch_atlas_aal_spm` or `fetch_atlas_aal`.



Discussion:
Originally I wrote fetch_atlas_aal. But I was told to make it more specific,  I guees if a new aal spm version is included, it would be as a separate atlas function. Actually the file structure is so different between versions that it might be better to just have them in separate fetch functions.

>  But I was told to make it more specific

If I remember well, I told you to make the name of dataset folder more specific, not the name of the function itself. My concern is that, if a new version of SPM is released, we will probably drop the support of the old one. As a consequence, we will break all the scripts that uses `fetch_aal_spm_12`. An option would be to have a `fetch_aal` function and a `version="spm12"'` parameter for which we can change the default value (this is an example).

We'll wait for Gael to come back to take a final decision.

ahhh, i really understood you wanted me to change everything, actually i was passing a version parameter at the beginning, I would completely agree with that, If you want I can implement the change, its a second... 

Then the parameter would be used also to create the dataset folder with the version attached, nonetheless I think it would be misleading for a user to have the parameter in the function exposed when at the moment there is no download of other versions, so maybe we would also need to point out in the docs that other versions are not downloadable yet?

I really don't know what is the right behavior here. So I suggest that we wait for Gaël's opinion before moving forward ;).

Ping @GaelVaroquaux 

> Ping @GaelVaroquaux

.... @GaelVaroquaux is alive.

More seriously: fetch_atlas_aal is good. People don't even realize that
there is an SPM version of the AAL.


Resolving patch:
diff --git a/nilearn/datasets/__init__.py b/nilearn/datasets/__init__.py
--- a/nilearn/datasets/__init__.py
+++ b/nilearn/datasets/__init__.py
@@ -12,7 +12,8 @@
                     fetch_harvard_oxford, fetch_atlas_msdl, fetch_msdl_atlas,
                     fetch_atlas_power_2011, fetch_atlas_smith_2009,
                     fetch_smith_2009, fetch_atlas_yeo_2011,
-                    fetch_yeo_2011_atlas, fetch_atlas_aal_spm_12)
+                    fetch_yeo_2011_atlas, fetch_atlas_aal_spm_12,
+                    fetch_atlas_aal)
 
 __all__ = ['fetch_icbm152_2009', 'load_mni152_template', 'fetch_oasis_vbm',
            'fetch_haxby_simple', 'fetch_haxby', 'fetch_nyu_rest', 'fetch_adhd',
@@ -24,4 +25,4 @@
            'fetch_atlas_power_2011', 'fetch_atlas_smith_2009',
            'fetch_smith_2009', 'fetch_atlas_yeo_2011',
            'fetch_yeo_2011_atlas', 'fetch_mixed_gambles',
-           'fetch_atlas_aal_spm_12']
+           'fetch_atlas_aal_spm_12', 'fetch_atlas_aal']
diff --git a/nilearn/datasets/atlas.py b/nilearn/datasets/atlas.py
--- a/nilearn/datasets/atlas.py
+++ b/nilearn/datasets/atlas.py
@@ -579,7 +579,15 @@ def fetch_yeo_2011_atlas(data_dir=None, url=None, resume=True, verbose=1):
         verbose=verbose)
 
 
+@deprecated('it has been replace by fetch_atlas_aal and '
+            'will be removed in nilearn 0.1.5')
 def fetch_atlas_aal_spm_12(data_dir=None, url=None, resume=True, verbose=1):
+    return fetch_atlas_aal(version='SPM12', data_dir=data_dir, url=url,
+                           resume=resume, verbose=verbose)
+
+
+def fetch_atlas_aal(version='SPM12', data_dir=None, url=None, resume=True,
+                    verbose=1):
     """Downloads and returns the AAL template for SPM 12.
 
     This atlas is the result of an automated anatomical parcellation of the
@@ -589,6 +597,10 @@ def fetch_atlas_aal_spm_12(data_dir=None, url=None, resume=True, verbose=1):
 
     Parameters
     ----------
+    version: string, optional
+        The version of the AAL atlas. Must be SPM5, SPM8 or SPM12. Default is
+        SPM12.
+
     data_dir: string
         directory where data should be downloaded and unpacked.
 
@@ -624,17 +636,22 @@ def fetch_atlas_aal_spm_12(data_dir=None, url=None, resume=True, verbose=1):
 
     Licence: unknown.
     """
-    spm_version = 12
+    versions = ['SPM5', 'SPM8', 'SPM12']
+    if version not in versions:
+        raise ValueError('The version of AAL requested "%s" does not exist.'
+                         'Please choose one among %s.' %
+                         (version, str(versions)))
+
     if url is None:
-        baseurl = "http://www.gin.cnrs.fr/AAL_files/aal_for_SPM%i.tar.gz"
-        url = baseurl % spm_version
+        baseurl = "http://www.gin.cnrs.fr/AAL_files/aal_for_%s.tar.gz"
+        url = baseurl % version
     opts = {'uncompress': True}
 
-    dataset_name = "aal_spm_12"
+    dataset_name = "aal_" + version
     # keys and basenames would need to be handled for each spm_version
     # for now spm_version 12 is hardcoded.
     basenames = ("AAL.nii", "AAL.xml")
-    filenames = [(os.path.join("aal_for_SPM%i" % spm_version, f), url, opts)
+    filenames = [(os.path.join('aal', 'atlas', f), url, opts)
                  for f in basenames]
 
     data_dir = _get_dataset_dir(dataset_name, data_dir=data_dir,


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
@@ -12,7 +12,7 @@
 import nibabel
 
 from nose import with_setup
-from nose.tools import assert_true, assert_equal
+from nose.tools import assert_true, assert_equal, assert_not_equal
 
 from nilearn._utils.testing import (mock_request, wrap_chunk_read_,
                                     FetchFilesMock, assert_raises_regex)
@@ -189,6 +189,7 @@ def test_fetch_atlas_craddock_2012():
     assert_equal(len(mock_url_request.urls), 1)
     for key, fn in zip(keys, filenames):
         assert_equal(bunch[key], os.path.join(tmpdir, 'craddock_2012', fn))
+    assert_not_equal(bunch.description, '')
 
 
 @with_setup(setup_mock, teardown_mock)
@@ -210,11 +211,13 @@ def test_fetch_atlas_smith_2009():
     assert_equal(len(mock_url_request.urls), 6)
     for key, fn in zip(keys, filenames):
         assert_equal(bunch[key], os.path.join(tmpdir, 'smith_2009', fn))
+    assert_not_equal(bunch.description, '')
 
 
 def test_fetch_atlas_power_2011_atlas():
     bunch = atlas.fetch_atlas_power_2011()
     assert_equal(len(bunch.rois), 264)
+    assert_not_equal(bunch.description, '')
 
 
 @with_setup(setup_mock, teardown_mock)
@@ -252,6 +255,7 @@ def test_fetch_atlas_msdl():
     assert_true(isinstance(dataset.labels, _basestring))
     assert_true(isinstance(dataset.maps, _basestring))
     assert_equal(len(mock_url_request.urls), 1)
+    assert_not_equal(dataset.description, '')
 
 
 @with_setup(setup_mock, teardown_mock)
@@ -266,18 +270,25 @@ def test_fetch_atlas_yeo_2011():
     assert_true(isinstance(dataset.thin_17, _basestring))
     assert_true(isinstance(dataset.thin_7, _basestring))
     assert_equal(len(mock_url_request.urls), 1)
+    assert_not_equal(dataset.description, '')
 
 
 @with_setup(setup_mock, teardown_mock)
 @with_setup(setup_tmpdata, teardown_tmpdata)
-def test_fetch_atlas_aal_spm_12():
-    ho_dir = os.path.join(tmpdir, 'aal_spm_12', 'aal_for_SPM12')
+def test_fetch_atlas_aal():
+    ho_dir = os.path.join(tmpdir, 'aal_SPM12', 'aal', 'atlas')
     os.makedirs(ho_dir)
     with open(os.path.join(ho_dir, 'AAL.xml'), 'w') as xml_file:
         xml_file.write("<?xml version='1.0' encoding='us-ascii'?> "
                        "<metadata>"
                        "</metadata>")
-    dataset = atlas.fetch_atlas_aal_spm_12(data_dir=tmpdir, verbose=0)
+    dataset = atlas.fetch_atlas_aal(data_dir=tmpdir, verbose=0)
     assert_true(isinstance(dataset.regions, _basestring))
     assert_true(isinstance(dataset.labels, dict))
     assert_equal(len(mock_url_request.urls), 1)
+
+    assert_raises_regex(ValueError, 'The version of AAL requested "FLS33"',
+                        atlas.fetch_atlas_aal, version="FLS33",
+                        data_dir=tmpdir, verbose=0)
+
+    assert_not_equal(dataset.description, '')
diff --git a/nilearn/datasets/tests/test_func.py b/nilearn/datasets/tests/test_func.py
--- a/nilearn/datasets/tests/test_func.py
+++ b/nilearn/datasets/tests/test_func.py
@@ -12,7 +12,8 @@
 from sklearn.utils import check_random_state
 
 from nose import with_setup
-from nose.tools import assert_true, assert_equal, assert_raises
+from nose.tools import (assert_true, assert_equal, assert_raises,
+                        assert_not_equal)
 
 from nilearn.datasets import utils, func
 from nilearn._utils.testing import (mock_request, wrap_chunk_read_,
@@ -142,6 +143,7 @@ def test_fetch_haxby():
         assert_equal(len(haxby.mask_face_little), i)
         assert_equal(len(haxby.mask_house_little), i)
         mock_url_request.reset()
+        assert_not_equal(haxby.description, '')
 
 
 @with_setup(setup_mock, teardown_mock)
@@ -168,6 +170,7 @@ def test_fetch_nyu_rest():
     assert_true(np.all(s[:12] == 1))
     assert_true(np.all(s[12:24] == 2))
     assert_true(np.all(s[24:] == 3))
+    assert_not_equal(nyu.description, '')
 
 
 @with_setup(setup_mock, teardown_mock)
@@ -199,6 +202,7 @@ def test_fetch_adhd():
     assert_equal(len(adhd.func), 12)
     assert_equal(len(adhd.confounds), 12)
     assert_equal(len(mock_url_request.urls), 13)  # Subjects + phenotypic
+    assert_not_equal(adhd.description, '')
 
 
 @with_setup(setup_mock, teardown_mock)
@@ -210,6 +214,7 @@ def test_miyawaki2008():
     assert_true(isinstance(dataset.mask, _basestring))
     assert_equal(len(dataset.mask_roi), 38)
     assert_equal(len(mock_url_request.urls), 1)
+    assert_not_equal(dataset.description, '')
 
 
 @with_setup(setup_mock, teardown_mock)
@@ -326,6 +331,7 @@ def test_fetch_localizer_contrasts():
     assert_equal(len(dataset.cmaps), 94)
     assert_equal(len(dataset.masks), 94)
     assert_equal(len(dataset.tmaps), 94)
+    assert_not_equal(dataset.description, '')
 
 
 @with_setup(setup_mock, teardown_mock)
@@ -356,6 +362,7 @@ def test_fetch_localizer_calculation_task():
     assert_true(isinstance(dataset.cmaps[0], _basestring))
     assert_equal(dataset.ext_vars.size, 20)
     assert_equal(len(dataset.cmaps), 20)
+    assert_not_equal(dataset.description, '')
 
 
 @with_setup(setup_mock, teardown_mock)
@@ -374,6 +381,7 @@ def test_fetch_abide_pcp():
     dataset = func.fetch_abide_pcp(data_dir=tmpdir, url=local_url,
                                    quality_checked=False, verbose=0)
     assert_equal(len(dataset.func_preproc), 400)
+    assert_not_equal(dataset.description, '')
 
 
 def test__load_mixed_gambles():
diff --git a/nilearn/datasets/tests/test_struct.py b/nilearn/datasets/tests/test_struct.py
--- a/nilearn/datasets/tests/test_struct.py
+++ b/nilearn/datasets/tests/test_struct.py
@@ -10,7 +10,7 @@
 from tempfile import mkdtemp
 
 from nose import with_setup
-from nose.tools import assert_true, assert_equal
+from nose.tools import assert_true, assert_equal, assert_not_equal
 
 from nilearn.datasets import utils, struct
 from nilearn._utils.testing import (mock_request, wrap_chunk_read_,
@@ -149,6 +149,7 @@ def test_fetch_icbm152_2009():
     assert_true(isinstance(dataset.t2_relax, _basestring))
     assert_true(isinstance(dataset.wm, _basestring))
     assert_equal(len(mock_url_request.urls), 1)
+    assert_not_equal(dataset.description, '')
 
 
 @with_setup(setup_mock, teardown_mock)