Repository: nilearn/nilearn

Issue:
fetch_atlas_harvard_oxford and symmetric_split
I have 2 little issues with `symmetric_split`:
1) the type of the output changes if `symmetric_split` is True or False

``` Python
from nilearn import datasets
atlas = datasets.fetch_atlas_harvard_oxford('cort-maxprob-thr25-1mm', symmetric_split=True)
type(atlas['labels']), type(atlas['maps'])
```

(list, nibabel.nifti1.Nifti1Image)

``` Python
atlas = datasets.fetch_atlas_harvard_oxford('cort-maxprob-thr25-1mm', symmetric_split=False)
type(atlas['labels']), type(atlas['maps'])
```

(numpy.ndarray, str)
2) the parameter `symmetric_split` is allowed to be True for `'sub-maxprob-thr25-1mm'` but 

``` Python
datasets.fetch_atlas_harvard_oxford('sub-maxprob-thr25-1mm', symmetric_split=True)
```

throws an error `RuntimeError: data type not supported`.  May be not allowing for subcortical atlases as their labels already contain the information right/left



Discussion:
I have another question @AlexandreAbraham 

``` Python
atlas = datasets.fetch_atlas_harvard_oxford('cort-maxprob-thr25-1mm', symmetric_split=True)
```

`print(atlas.labels[:5])` gives the right regions

``` Python
['Background', 'Frontal Pole, right part', 'Insular Cortex, right part', 'Superior Frontal Gyrus, right part', 'Middle Frontal Gyrus, right part']
```

while `print(atlas.labels[-5:])` gives the left regions 

``` Python
['Planum Polare, left part', "Heschl's Gyrus (includes H1 and H2), left part", 'Planum Temporale, left part', 'Supracalcarine Cortex, left part', 'Occipital Pole, left part']
```

but when plotting they seem to me inverted because I expected the intensity growing from 0 for the Background to its maximum in occipital regions. Did I get something wrong ?

``` Python
from nilearn import plotting
plotting.plot_stat_map(atlas.maps)
```

![ho_atlas](https://cloud.githubusercontent.com/assets/7080143/11842318/3336b2e6-a403-11e5-98be-06b0e8800a17.png)


Resolving patch:
diff --git a/nilearn/datasets/atlas.py b/nilearn/datasets/atlas.py
--- a/nilearn/datasets/atlas.py
+++ b/nilearn/datasets/atlas.py
@@ -231,7 +231,7 @@ def fetch_atlas_harvard_oxford(atlas_name, data_dir=None,
     names[0] = 'Background'
     for label in ElementTree.parse(label_file).findall('.//label'):
         names[int(label.get('index')) + 1] = label.text
-    names = np.asarray(list(names.values()))
+    names = list(names.values())
 
     if not symmetric_split:
         return Bunch(maps=atlas_img, labels=names)
@@ -245,35 +245,37 @@ def fetch_atlas_harvard_oxford(atlas_name, data_dir=None,
     atlas = atlas_img.get_data()
 
     labels = np.unique(atlas)
-    # ndimage.find_objects output contains None elements for labels
-    # that do not exist
-    found_slices = (s for s in ndimage.find_objects(atlas)
-                    if s is not None)
+    # Build a mask of both halves of the brain
     middle_ind = (atlas.shape[0] - 1) // 2
-    crosses_middle = [s.start < middle_ind and s.stop > middle_ind
-                      for s, _, _ in found_slices]
-
-    # Split every zone crossing the median plane into two parts.
-    # Assumes that the background label is zero.
-    half = np.zeros(atlas.shape, dtype=np.bool)
-    half[:middle_ind, ...] = True
-    new_label = max(labels) + 1
     # Put zeros on the median plane
     atlas[middle_ind, ...] = 0
-    for label, crosses in zip(labels[1:], crosses_middle):
-        if not crosses:
-            continue
-        atlas[np.logical_and(atlas == label, half)] = new_label
-        new_label += 1
+    # Split every zone crossing the median plane into two parts.
+    left_atlas = atlas.copy()
+    left_atlas[middle_ind:, ...] = 0
+    right_atlas = atlas.copy()
+    right_atlas[:middle_ind, ...] = 0
 
-    # Duplicate labels for right and left
+    new_label = 0
+    new_atlas = atlas.copy()
+    # Assumes that the background label is zero.
     new_names = [names[0]]
-    for n in names[1:]:
-        new_names.append(n + ', right part')
-    for n in names[1:]:
-        new_names.append(n + ', left part')
+    for label, name in zip(labels[1:], names[1:]):
+        new_label += 1
+        left_elements = (left_atlas == label).sum()
+        right_elements = (right_atlas == label).sum()
+        n_elements = float(left_elements + right_elements)
+        if (left_elements / n_elements < 0.05 or
+                right_elements / n_elements < 0.05):
+            new_atlas[atlas == label] = new_label
+            new_names.append(name)
+            continue
+        new_atlas[right_atlas == label] = new_label
+        new_names.append(name + ', left part')
+        new_label += 1
+        new_atlas[left_atlas == label] = new_label
+        new_names.append(name + ', right part')
 
-    atlas_img = new_img_like(atlas_img, atlas, atlas_img.get_affine())
+    atlas_img = new_img_like(atlas_img, new_atlas, atlas_img.get_affine())
     return Bunch(maps=atlas_img, labels=new_names)
 
 


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
@@ -109,20 +109,44 @@ def test_fail_fetch_atlas_harvard_oxford():
     os.makedirs(nifti_dir)
 
     target_atlas_nii = os.path.join(nifti_dir, target_atlas_fname)
-    struct.load_mni152_template().to_filename(target_atlas_nii)
+
+    # Create false atlas
+    atlas_data = np.zeros((10, 10, 10), dtype=int)
+
+    # Create an interhemispheric map
+    atlas_data[:, :2, :] = 1
+
+    # Create a left map
+    atlas_data[:5, 3:5, :] = 2
+
+    # Create a right map, with one voxel on the left side
+    atlas_data[5:, 7:9, :] = 3
+    atlas_data[4, 7, 0] = 3
+
+    nibabel.Nifti1Image(atlas_data, np.eye(4) * 3).to_filename(
+        target_atlas_nii)
 
     dummy = open(os.path.join(ho_dir, 'HarvardOxford-Cortical.xml'), 'w')
-    dummy.write("<?xml version='1.0' encoding='us-ascii'?> "
-                "<metadata>"
-                "</metadata>")
+    dummy.write("<?xml version='1.0' encoding='us-ascii'?>\n"
+                "<data>\n"
+                '<label index="0" x="48" y="94" z="35">R1</label>\n'
+                '<label index="1" x="25" y="70" z="32">R2</label>\n'
+                '<label index="2" x="33" y="73" z="63">R3</label>\n'
+                "</data>")
     dummy.close()
 
     ho = atlas.fetch_atlas_harvard_oxford(target_atlas,
-                                          data_dir=tst.tmpdir)
-
-    assert_true(isinstance(nibabel.load(ho.maps), nibabel.Nifti1Image))
-    assert_true(isinstance(ho.labels, np.ndarray))
-    assert_true(len(ho.labels) > 0)
+                                          data_dir=tst.tmpdir,
+                                          symmetric_split=True)
+
+    assert_true(isinstance(ho.maps, nibabel.Nifti1Image))
+    assert_true(isinstance(ho.labels, list))
+    assert_equal(len(ho.labels), 5)
+    assert_equal(ho.labels[0], "Background")
+    assert_equal(ho.labels[1], "R1, left part")
+    assert_equal(ho.labels[2], "R1, right part")
+    assert_equal(ho.labels[3], "R2")
+    assert_equal(ho.labels[4], "R3")
 
 
 @with_setup(setup_mock, teardown_mock)