Repository: nilearn/nilearn

Issue:
Add a resample_to_img
We already have 

```
resample_img(img, target_affine=None, target_shape=None, interpolation='continuous', copy=True, order='F')
```

http://nilearn.github.io/modules/generated/nilearn.image.resample_img.html

It would be nice to have a variant

```
resample_to_img(source_img, target_img, interpolation='continuous', copy=True, order='F')
```

that would take the shape and affine from "target_img".

It's just a simple helper function, but it would make the life of many non advanced users simpler.

We should reference each function in there respective seealso section of the docstrings.



Discussion:
I can have a look at this one too :)

+1000

+1


Resolving patch:
diff --git a/examples/04_manipulating_images/plot_affine_transformation.py b/examples/04_manipulating_images/plot_affine_transformation.py
--- a/examples/04_manipulating_images/plot_affine_transformation.py
+++ b/examples/04_manipulating_images/plot_affine_transformation.py
@@ -11,10 +11,10 @@
 matrix yields (x, y, z, 1), a 4-vector containing the millimeter position of
 the voxel.
 
-The resampling procedure in `resample_img` can attribute a new affine matrix
-and a new shape to your Nifti image while keeping its representation in
-millimeter space exactly the same (up to sampling error and possible
-clipping).
+The resampling procedure in :func:`nilearn.image.resample_img` can attribute
+a new affine matrix and a new shape to your Nifti image while keeping its
+representation in millimeter space exactly the same (up to sampling error and
+possible clipping).
 
 This example shows a 2D image in voxel space, and the position of the data in
 millimeter space, as encoded by the affine matrix. The image is the resampled
diff --git a/nilearn/image/__init__.py b/nilearn/image/__init__.py
--- a/nilearn/image/__init__.py
+++ b/nilearn/image/__init__.py
@@ -2,7 +2,7 @@
 Mathematical operations working on Niimg-like objects like -a (3+n)-D block of
 data, and an affine.
 """
-from .resampling import resample_img, reorder_img
+from .resampling import resample_img, resample_to_img, reorder_img
 from .image import high_variance_confounds, smooth_img, crop_img, \
     mean_img, swap_img_hemispheres, index_img, iter_img, threshold_img, \
     math_img
@@ -10,8 +10,8 @@
 from .._utils.niimg_conversions import concat_niimgs as concat_imgs
 from .._utils.niimg import copy_img
 
-__all__ = ['resample_img', 'high_variance_confounds', 'smooth_img',
-           'crop_img', 'mean_img', 'reorder_img',
+__all__ = ['resample_img', 'resample_to_img', 'high_variance_confounds',
+           'smooth_img', 'crop_img', 'mean_img', 'reorder_img',
            'swap_img_hemispheres', 'concat_imgs', 'copy_img',
            'index_img', 'iter_img', 'new_img_like', 'threshold_img',
            'math_img']
diff --git a/nilearn/image/resampling.py b/nilearn/image/resampling.py
--- a/nilearn/image/resampling.py
+++ b/nilearn/image/resampling.py
@@ -289,7 +289,8 @@ def resample_img(img, target_affine=None, target_shape=None,
         must also be given. (See notes)
 
     interpolation: str, optional
-        Can be 'continuous' (default) or 'nearest'. Indicate the resample method
+        Can be 'continuous' (default) or 'nearest'. Indicates the resample
+        method.
 
     copy: bool, optional
         If True, guarantees that output array has no memory in common with
@@ -306,6 +307,10 @@ def resample_img(img, target_affine=None, target_shape=None,
         input image, resampled to have respectively target_shape and
         target_affine as shape and affine.
 
+    See Also
+    --------
+    nilearn.image.resample_to_img
+
     Notes
     =====
 
@@ -484,6 +489,58 @@ def resample_img(img, target_affine=None, target_shape=None,
     return new_img_like(img, resampled_data, target_affine)
 
 
+def resample_to_img(source_img, target_img,
+                    interpolation='continuous', copy=True, order='F'):
+    """Resample a Niimg-like source object on a target Niimg-like object.
+
+    Parameters
+    ----------
+    source_img: Niimg-like object
+        See http://nilearn.github.io/manipulating_visualizing/manipulating_images.html#niimg.
+        Image(s) to resample.
+
+    target_img: Niimg-like object
+        See http://nilearn.github.io/manipulating_visualizing/manipulating_images.html#niimg.
+        Reference image taken for resampling.
+
+    interpolation: str, optional
+        Can be 'continuous' (default) or 'nearest'. Indicates the resample
+        method.
+
+    copy: bool, optional
+        If True, guarantees that output array has no memory in common with
+        input array.
+        In all cases, input images are never modified by this function.
+
+    order: "F" or "C"
+        Data ordering in output array. This function is slightly faster with
+        Fortran ordering.
+
+    Returns
+    -------
+    resampled: nibabel.Nifti1Image
+        input image, resampled to have respectively target image shape and
+        affine as shape and affine.
+
+    See Also
+    --------
+    nilearn.image.resample_img
+    """
+
+    target = _utils.check_niimg(target_img)
+    target_shape = target.shape
+
+    # When target shape is greater than 3, we reduce to 3, ti be compatible
+    # with uniderlying call to resample_img
+    if len(target_shape) > 3:
+        target_shape = target.shape[:3]
+
+    return resample_img(source_img,
+                        target_affine=target.get_affine(),
+                        target_shape=target_shape,
+                        interpolation=interpolation, copy=copy, order=order)
+
+
 def reorder_img(img, resample=None):
     """Returns an image with the affine diagonal (by permuting axes).
     The orientation of the new image will be RAS (Right, Anterior, Superior).


Test patch:
diff --git a/nilearn/image/tests/test_resampling.py b/nilearn/image/tests/test_resampling.py
--- a/nilearn/image/tests/test_resampling.py
+++ b/nilearn/image/tests/test_resampling.py
@@ -14,8 +14,9 @@
 
 from nibabel import Nifti1Image
 
-from nilearn.image.resampling import resample_img, BoundingBoxError, \
-        reorder_img, from_matrix_vector, coord_transform
+from nilearn.image.resampling import resample_img, resample_to_img, reorder_img
+from nilearn.image.resampling import from_matrix_vector, coord_transform
+from nilearn.image.resampling import BoundingBoxError
 from nilearn._utils import testing
 
 
@@ -421,8 +422,29 @@ def test_resampling_nan():
         target_affine=np.eye(4))
 
     resampled_data = resampled_img.get_data()
-    np.testing.assert_allclose(10,
-                resampled_data[np.isfinite(resampled_data)])
+    np.testing.assert_allclose(10, resampled_data[np.isfinite(resampled_data)])
+
+
+def test_resample_to_img():
+    # Testing resample to img function
+    rand_gen = np.random.RandomState(0)
+    shape = (6, 3, 6, 3)
+    data = rand_gen.random_sample(shape)
+
+    source_affine = np.eye(4)
+    source_img = Nifti1Image(data, source_affine)
+
+    target_affine = 2 * source_affine
+    target_img = Nifti1Image(data, target_affine)
+
+
+    result_img = resample_to_img(source_img, target_img,
+                                 interpolation='nearest')
+
+    downsampled = data[::2, ::2, ::2, ...]
+    x, y, z = downsampled.shape[:3]
+    np.testing.assert_almost_equal(downsampled,
+                                   result_img.get_data()[:x, :y, :z, ...])
 
 
 def test_reorder_img():