We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Latest nibabel release breaks test
### Summary
https://github.com/nipy/nipype/blob/fcbe28e58ecabedbcc2dcaf09bf9a7329ae43fcf/nipype/interfaces/tests/test_image.py#L17

blows up with nibabel 2.4.0
### Actual behavior
`AssertionError`
### Expected behavior
Pass
### How to replicate the behavior
View any recent CI build (e.g. https://travis-ci.org/nipy/nipype/jobs/514714882)

Relevant PR -  nipy/nibabel#741


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `nipype/interfaces/image.py`
Content:
```
1 # -*- coding: utf-8 -*-
2 # emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
3 # vi: set ft=python sts=4 ts=4 sw=4 et:
4 
5 from ..utils.filemanip import fname_presuffix
6 from .base import (SimpleInterface, TraitedSpec, BaseInterfaceInputSpec,
7                    traits, File)
8 
9 
10 class RescaleInputSpec(BaseInterfaceInputSpec):
11     in_file = File(exists=True, mandatory=True,
12                    desc='Skull-stripped image to rescale')
13     ref_file = File(exists=True, mandatory=True,
14                     desc='Skull-stripped reference image')
15     invert = traits.Bool(desc='Invert contrast of rescaled image')
16     percentile = traits.Range(low=0., high=50., value=0., usedefault=True,
17                               desc='Percentile to use for reference to allow '
18                                    'for outliers - 1 indicates the 1st and '
19                                    '99th percentiles in the input file will '
20                                    'be mapped to the 99th and 1st percentiles '
21                                    'in the reference; 0 indicates minima and '
22                                    'maxima will be mapped')
23 
24 
25 class RescaleOutputSpec(TraitedSpec):
26     out_file = File(exists=True, desc='Rescaled image')
27 
28 
29 class Rescale(SimpleInterface):
30     """Rescale an image
31 
32     Rescales the non-zero portion of ``in_file`` to match the bounds of the
33     non-zero portion of ``ref_file``.
34     Reference values in the input and reference images are defined by the
35     ``percentile`` parameter, and the reference values in each image are
36     identified and the remaining values are scaled accordingly.
37     In the case of ``percentile == 0``, the reference values are the maxima
38     and minima of each image.
39     If the ``invert`` parameter is set, the input file is inverted prior to
40     rescaling.
41 
42     Examples
43     --------
44 
45     To use a high-resolution T1w image as a registration target for a T2\*
46     image, it may be useful to invert the T1w image and rescale to the T2\*
47     range.
48     Using the 1st and 99th percentiles may reduce the impact of outlier
49     voxels.
50 
51     >>> from nipype.interfaces.image import Rescale
52     >>> invert_t1w = Rescale(invert=True)
53     >>> invert_t1w.inputs.in_file = 'structural.nii'
54     >>> invert_t1w.inputs.ref_file = 'functional.nii'
55     >>> invert_t1w.inputs.percentile = 1.
56     >>> res = invert_t1w.run()  # doctest: +SKIP
57 
58     """
59     input_spec = RescaleInputSpec
60     output_spec = RescaleOutputSpec
61 
62     def _run_interface(self, runtime):
63         import numpy as np
64         import nibabel as nb
65 
66         img = nb.load(self.inputs.in_file)
67         data = img.get_data()
68         ref_data = nb.load(self.inputs.ref_file).get_data()
69 
70         in_mask = data > 0
71         ref_mask = ref_data > 0
72 
73         q = [self.inputs.percentile, 100. - self.inputs.percentile]
74         in_low, in_high = np.percentile(data[in_mask], q)
75         ref_low, ref_high = np.percentile(ref_data[ref_mask], q)
76         scale_factor = (ref_high - ref_low) / (in_high - in_low)
77 
78         signal = in_high - data if self.inputs.invert else data - in_low
79         out_data = in_mask * (signal * scale_factor + ref_low)
80 
81         suffix = '_inv' if self.inputs.invert else '_rescaled'
82         out_file = fname_presuffix(self.inputs.in_file, suffix=suffix,
83                                    newpath=runtime.cwd)
84         img.__class__(out_data, img.affine, img.header).to_filename(out_file)
85 
86         self._results['out_file'] = out_file
87         return runtime
88 
89 
90 _axes = ('RL', 'AP', 'SI')
91 _orientations = tuple(
92     ''.join((x[i], y[j], z[k]))
93     for x in _axes for y in _axes for z in _axes
94     if x != y != z != x
95     for i in (0, 1) for j in (0, 1) for k in (0, 1))
96 
97 
98 class ReorientInputSpec(BaseInterfaceInputSpec):
99     in_file = File(exists=True, mandatory=True, desc='Input image')
100     orientation = traits.Enum(_orientations, usedefault=True,
101                               desc='Target axis orientation')
102 
103 
104 class ReorientOutputSpec(TraitedSpec):
105     out_file = File(exists=True, desc='Reoriented image')
106     transform = File(exists=True,
107                      desc='Affine transform from input orientation to output')
108 
109 
110 class Reorient(SimpleInterface):
111     """Conform an image to a given orientation
112 
113 Flips and reorder the image data array so that the axes match the
114 directions indicated in ``orientation``.
115 The default ``RAS`` orientation corresponds to the first axis being ordered
116 from left to right, the second axis from posterior to anterior, and the
117 third axis from inferior to superior.
118 
119 For oblique images, the original orientation is considered to be the
120 closest plumb orientation.
121 
122 No resampling is performed, and thus the output image is not de-obliqued
123 or registered to any other image or template.
124 
125 The effective transform is calculated from the original affine matrix to
126 the reoriented affine matrix.
127 
128 Examples
129 --------
130 
131 If an image is not reoriented, the original file is not modified
132 
133 .. testsetup::
134 
135     >>> def print_affine(matrix):
136     ...     print(str(matrix).replace(']', ' ').replace('[', ' '))
137 
138 >>> import numpy as np
139 >>> from nipype.interfaces.image import Reorient
140 >>> reorient = Reorient(orientation='LPS')
141 >>> reorient.inputs.in_file = 'segmentation0.nii.gz'
142 >>> res = reorient.run()
143 >>> res.outputs.out_file
144 'segmentation0.nii.gz'
145 
146 >>> print_affine(np.loadtxt(res.outputs.transform))
147 1.  0.  0.  0.
148 0.  1.  0.  0.
149 0.  0.  1.  0.
150 0.  0.  0.  1.
151 
152 >>> reorient.inputs.orientation = 'RAS'
153 >>> res = reorient.run()
154 >>> res.outputs.out_file  # doctest: +ELLIPSIS
155 '.../segmentation0_ras.nii.gz'
156 
157 >>> print_affine(np.loadtxt(res.outputs.transform))
158 -1.   0.   0.  60.
159  0.  -1.   0.  72.
160  0.   0.   1.   0.
161  0.   0.   0.   1.
162 
163 .. testcleanup::
164 
165     >>> import os
166     >>> os.unlink(res.outputs.out_file)
167     >>> os.unlink(res.outputs.transform)
168 
169 """
170     input_spec = ReorientInputSpec
171     output_spec = ReorientOutputSpec
172 
173     def _run_interface(self, runtime):
174         import numpy as np
175         import nibabel as nb
176         from nibabel.orientations import (
177             axcodes2ornt, ornt_transform, inv_ornt_aff)
178 
179         fname = self.inputs.in_file
180         orig_img = nb.load(fname)
181 
182         # Find transform from current (approximate) orientation to
183         # target, in nibabel orientation matrix and affine forms
184         orig_ornt = nb.io_orientation(orig_img.affine)
185         targ_ornt = axcodes2ornt(self.inputs.orientation)
186         transform = ornt_transform(orig_ornt, targ_ornt)
187         affine_xfm = inv_ornt_aff(transform, orig_img.shape)
188 
189         # Check can be eliminated when minimum nibabel version >= 2.2
190         if hasattr(orig_img, 'as_reoriented'):
191             reoriented = orig_img.as_reoriented(transform)
192         else:
193             reoriented = _as_reoriented_backport(orig_img, transform)
194 
195         # Image may be reoriented
196         if reoriented is not orig_img:
197             suffix = '_' + self.inputs.orientation.lower()
198             out_name = fname_presuffix(fname, suffix=suffix,
199                                        newpath=runtime.cwd)
200             reoriented.to_filename(out_name)
201         else:
202             out_name = fname
203 
204         mat_name = fname_presuffix(fname, suffix='.mat',
205                                    newpath=runtime.cwd, use_ext=False)
206         np.savetxt(mat_name, affine_xfm, fmt='%.08f')
207 
208         self._results['out_file'] = out_name
209         self._results['transform'] = mat_name
210 
211         return runtime
212 
213 
214 def _as_reoriented_backport(img, ornt):
215     """Backport of img.as_reoriented as of nibabel 2.2.0"""
216     import numpy as np
217     import nibabel as nb
218     from nibabel.orientations import inv_ornt_aff
219     if np.array_equal(ornt, [[0, 1], [1, 1], [2, 1]]):
220         return img
221 
222     t_arr = nb.apply_orientation(img.get_data(), ornt)
223     new_aff = img.affine.dot(inv_ornt_aff(ornt, img.shape))
224     reoriented = img.__class__(t_arr, new_aff, img.header)
225 
226     if isinstance(reoriented, nb.Nifti1Pair):
227         # Also apply the transform to the dim_info fields
228         new_dim = list(reoriented.header.get_dim_info())
229         for idx, value in enumerate(new_dim):
230             # For each value, leave as None if it was that way,
231             # otherwise check where we have mapped it to
232             if value is None:
233                 continue
234             new_dim[idx] = np.where(ornt[:, 0] == idx)[0]
235 
236         reoriented.header.set_dim_info(*new_dim)
237 
238     return reoriented
239
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/nipype/interfaces/image.py b/nipype/interfaces/image.py
--- a/nipype/interfaces/image.py
+++ b/nipype/interfaces/image.py
@@ -5,6 +5,7 @@
 from ..utils.filemanip import fname_presuffix
 from .base import (SimpleInterface, TraitedSpec, BaseInterfaceInputSpec,
                    traits, File)
+from .. import LooseVersion
 
 
 class RescaleInputSpec(BaseInterfaceInputSpec):
@@ -186,8 +187,8 @@
         transform = ornt_transform(orig_ornt, targ_ornt)
         affine_xfm = inv_ornt_aff(transform, orig_img.shape)
 
-        # Check can be eliminated when minimum nibabel version >= 2.2
-        if hasattr(orig_img, 'as_reoriented'):
+        # Check can be eliminated when minimum nibabel version >= 2.4
+        if LooseVersion(nb.__version__) >= LooseVersion('2.4.0'):
             reoriented = orig_img.as_reoriented(transform)
         else:
             reoriented = _as_reoriented_backport(orig_img, transform)
@@ -212,7 +213,7 @@
 
 
 def _as_reoriented_backport(img, ornt):
-    """Backport of img.as_reoriented as of nibabel 2.2.0"""
+    """Backport of img.as_reoriented as of nibabel 2.4.0"""
     import numpy as np
     import nibabel as nb
     from nibabel.orientations import inv_ornt_aff
@@ -225,13 +226,8 @@
 
     if isinstance(reoriented, nb.Nifti1Pair):
         # Also apply the transform to the dim_info fields
-        new_dim = list(reoriented.header.get_dim_info())
-        for idx, value in enumerate(new_dim):
-            # For each value, leave as None if it was that way,
-            # otherwise check where we have mapped it to
-            if value is None:
-                continue
-            new_dim[idx] = np.where(ornt[:, 0] == idx)[0]
+        new_dim = [None if orig_dim is None else int(ornt[orig_dim, 0])
+                   for orig_dim in img.header.get_dim_info()]
 
         reoriented.header.set_dim_info(*new_dim)

{"golden_diff": "diff --git a/nipype/interfaces/image.py b/nipype/interfaces/image.py\n--- a/nipype/interfaces/image.py\n+++ b/nipype/interfaces/image.py\n@@ -5,6 +5,7 @@\n from ..utils.filemanip import fname_presuffix\n from .base import (SimpleInterface, TraitedSpec, BaseInterfaceInputSpec,\n                    traits, File)\n+from .. import LooseVersion\n \n \n class RescaleInputSpec(BaseInterfaceInputSpec):\n@@ -186,8 +187,8 @@\n         transform = ornt_transform(orig_ornt, targ_ornt)\n         affine_xfm = inv_ornt_aff(transform, orig_img.shape)\n \n-        # Check can be eliminated when minimum nibabel version >= 2.2\n-        if hasattr(orig_img, 'as_reoriented'):\n+        # Check can be eliminated when minimum nibabel version >= 2.4\n+        if LooseVersion(nb.__version__) >= LooseVersion('2.4.0'):\n             reoriented = orig_img.as_reoriented(transform)\n         else:\n             reoriented = _as_reoriented_backport(orig_img, transform)\n@@ -212,7 +213,7 @@\n \n \n def _as_reoriented_backport(img, ornt):\n-    \"\"\"Backport of img.as_reoriented as of nibabel 2.2.0\"\"\"\n+    \"\"\"Backport of img.as_reoriented as of nibabel 2.4.0\"\"\"\n     import numpy as np\n     import nibabel as nb\n     from nibabel.orientations import inv_ornt_aff\n@@ -225,13 +226,8 @@\n \n     if isinstance(reoriented, nb.Nifti1Pair):\n         # Also apply the transform to the dim_info fields\n-        new_dim = list(reoriented.header.get_dim_info())\n-        for idx, value in enumerate(new_dim):\n-            # For each value, leave as None if it was that way,\n-            # otherwise check where we have mapped it to\n-            if value is None:\n-                continue\n-            new_dim[idx] = np.where(ornt[:, 0] == idx)[0]\n+        new_dim = [None if orig_dim is None else int(ornt[orig_dim, 0])\n+                   for orig_dim in img.header.get_dim_info()]\n \n         reoriented.header.set_dim_info(*new_dim)\n", "issue": "Latest nibabel release breaks test\n### Summary\r\nhttps://github.com/nipy/nipype/blob/fcbe28e58ecabedbcc2dcaf09bf9a7329ae43fcf/nipype/interfaces/tests/test_image.py#L17\r\n\r\nblows up with nibabel 2.4.0\r\n### Actual behavior\r\n`AssertionError`\r\n### Expected behavior\r\nPass\r\n### How to replicate the behavior\r\nView any recent CI build (e.g. https://travis-ci.org/nipy/nipype/jobs/514714882)\r\n\r\nRelevant PR -  nipy/nibabel#741\r\n\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\n# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-\n# vi: set ft=python sts=4 ts=4 sw=4 et:\n\nfrom ..utils.filemanip import fname_presuffix\nfrom .base import (SimpleInterface, TraitedSpec, BaseInterfaceInputSpec,\n                   traits, File)\n\n\nclass RescaleInputSpec(BaseInterfaceInputSpec):\n    in_file = File(exists=True, mandatory=True,\n                   desc='Skull-stripped image to rescale')\n    ref_file = File(exists=True, mandatory=True,\n                    desc='Skull-stripped reference image')\n    invert = traits.Bool(desc='Invert contrast of rescaled image')\n    percentile = traits.Range(low=0., high=50., value=0., usedefault=True,\n                              desc='Percentile to use for reference to allow '\n                                   'for outliers - 1 indicates the 1st and '\n                                   '99th percentiles in the input file will '\n                                   'be mapped to the 99th and 1st percentiles '\n                                   'in the reference; 0 indicates minima and '\n                                   'maxima will be mapped')\n\n\nclass RescaleOutputSpec(TraitedSpec):\n    out_file = File(exists=True, desc='Rescaled image')\n\n\nclass Rescale(SimpleInterface):\n    \"\"\"Rescale an image\n\n    Rescales the non-zero portion of ``in_file`` to match the bounds of the\n    non-zero portion of ``ref_file``.\n    Reference values in the input and reference images are defined by the\n    ``percentile`` parameter, and the reference values in each image are\n    identified and the remaining values are scaled accordingly.\n    In the case of ``percentile == 0``, the reference values are the maxima\n    and minima of each image.\n    If the ``invert`` parameter is set, the input file is inverted prior to\n    rescaling.\n\n    Examples\n    --------\n\n    To use a high-resolution T1w image as a registration target for a T2\\*\n    image, it may be useful to invert the T1w image and rescale to the T2\\*\n    range.\n    Using the 1st and 99th percentiles may reduce the impact of outlier\n    voxels.\n\n    >>> from nipype.interfaces.image import Rescale\n    >>> invert_t1w = Rescale(invert=True)\n    >>> invert_t1w.inputs.in_file = 'structural.nii'\n    >>> invert_t1w.inputs.ref_file = 'functional.nii'\n    >>> invert_t1w.inputs.percentile = 1.\n    >>> res = invert_t1w.run()  # doctest: +SKIP\n\n    \"\"\"\n    input_spec = RescaleInputSpec\n    output_spec = RescaleOutputSpec\n\n    def _run_interface(self, runtime):\n        import numpy as np\n        import nibabel as nb\n\n        img = nb.load(self.inputs.in_file)\n        data = img.get_data()\n        ref_data = nb.load(self.inputs.ref_file).get_data()\n\n        in_mask = data > 0\n        ref_mask = ref_data > 0\n\n        q = [self.inputs.percentile, 100. - self.inputs.percentile]\n        in_low, in_high = np.percentile(data[in_mask], q)\n        ref_low, ref_high = np.percentile(ref_data[ref_mask], q)\n        scale_factor = (ref_high - ref_low) / (in_high - in_low)\n\n        signal = in_high - data if self.inputs.invert else data - in_low\n        out_data = in_mask * (signal * scale_factor + ref_low)\n\n        suffix = '_inv' if self.inputs.invert else '_rescaled'\n        out_file = fname_presuffix(self.inputs.in_file, suffix=suffix,\n                                   newpath=runtime.cwd)\n        img.__class__(out_data, img.affine, img.header).to_filename(out_file)\n\n        self._results['out_file'] = out_file\n        return runtime\n\n\n_axes = ('RL', 'AP', 'SI')\n_orientations = tuple(\n    ''.join((x[i], y[j], z[k]))\n    for x in _axes for y in _axes for z in _axes\n    if x != y != z != x\n    for i in (0, 1) for j in (0, 1) for k in (0, 1))\n\n\nclass ReorientInputSpec(BaseInterfaceInputSpec):\n    in_file = File(exists=True, mandatory=True, desc='Input image')\n    orientation = traits.Enum(_orientations, usedefault=True,\n                              desc='Target axis orientation')\n\n\nclass ReorientOutputSpec(TraitedSpec):\n    out_file = File(exists=True, desc='Reoriented image')\n    transform = File(exists=True,\n                     desc='Affine transform from input orientation to output')\n\n\nclass Reorient(SimpleInterface):\n    \"\"\"Conform an image to a given orientation\n\nFlips and reorder the image data array so that the axes match the\ndirections indicated in ``orientation``.\nThe default ``RAS`` orientation corresponds to the first axis being ordered\nfrom left to right, the second axis from posterior to anterior, and the\nthird axis from inferior to superior.\n\nFor oblique images, the original orientation is considered to be the\nclosest plumb orientation.\n\nNo resampling is performed, and thus the output image is not de-obliqued\nor registered to any other image or template.\n\nThe effective transform is calculated from the original affine matrix to\nthe reoriented affine matrix.\n\nExamples\n--------\n\nIf an image is not reoriented, the original file is not modified\n\n.. testsetup::\n\n    >>> def print_affine(matrix):\n    ...     print(str(matrix).replace(']', ' ').replace('[', ' '))\n\n>>> import numpy as np\n>>> from nipype.interfaces.image import Reorient\n>>> reorient = Reorient(orientation='LPS')\n>>> reorient.inputs.in_file = 'segmentation0.nii.gz'\n>>> res = reorient.run()\n>>> res.outputs.out_file\n'segmentation0.nii.gz'\n\n>>> print_affine(np.loadtxt(res.outputs.transform))\n1.  0.  0.  0.\n0.  1.  0.  0.\n0.  0.  1.  0.\n0.  0.  0.  1.\n\n>>> reorient.inputs.orientation = 'RAS'\n>>> res = reorient.run()\n>>> res.outputs.out_file  # doctest: +ELLIPSIS\n'.../segmentation0_ras.nii.gz'\n\n>>> print_affine(np.loadtxt(res.outputs.transform))\n-1.   0.   0.  60.\n 0.  -1.   0.  72.\n 0.   0.   1.   0.\n 0.   0.   0.   1.\n\n.. testcleanup::\n\n    >>> import os\n    >>> os.unlink(res.outputs.out_file)\n    >>> os.unlink(res.outputs.transform)\n\n\"\"\"\n    input_spec = ReorientInputSpec\n    output_spec = ReorientOutputSpec\n\n    def _run_interface(self, runtime):\n        import numpy as np\n        import nibabel as nb\n        from nibabel.orientations import (\n            axcodes2ornt, ornt_transform, inv_ornt_aff)\n\n        fname = self.inputs.in_file\n        orig_img = nb.load(fname)\n\n        # Find transform from current (approximate) orientation to\n        # target, in nibabel orientation matrix and affine forms\n        orig_ornt = nb.io_orientation(orig_img.affine)\n        targ_ornt = axcodes2ornt(self.inputs.orientation)\n        transform = ornt_transform(orig_ornt, targ_ornt)\n        affine_xfm = inv_ornt_aff(transform, orig_img.shape)\n\n        # Check can be eliminated when minimum nibabel version >= 2.2\n        if hasattr(orig_img, 'as_reoriented'):\n            reoriented = orig_img.as_reoriented(transform)\n        else:\n            reoriented = _as_reoriented_backport(orig_img, transform)\n\n        # Image may be reoriented\n        if reoriented is not orig_img:\n            suffix = '_' + self.inputs.orientation.lower()\n            out_name = fname_presuffix(fname, suffix=suffix,\n                                       newpath=runtime.cwd)\n            reoriented.to_filename(out_name)\n        else:\n            out_name = fname\n\n        mat_name = fname_presuffix(fname, suffix='.mat',\n                                   newpath=runtime.cwd, use_ext=False)\n        np.savetxt(mat_name, affine_xfm, fmt='%.08f')\n\n        self._results['out_file'] = out_name\n        self._results['transform'] = mat_name\n\n        return runtime\n\n\ndef _as_reoriented_backport(img, ornt):\n    \"\"\"Backport of img.as_reoriented as of nibabel 2.2.0\"\"\"\n    import numpy as np\n    import nibabel as nb\n    from nibabel.orientations import inv_ornt_aff\n    if np.array_equal(ornt, [[0, 1], [1, 1], [2, 1]]):\n        return img\n\n    t_arr = nb.apply_orientation(img.get_data(), ornt)\n    new_aff = img.affine.dot(inv_ornt_aff(ornt, img.shape))\n    reoriented = img.__class__(t_arr, new_aff, img.header)\n\n    if isinstance(reoriented, nb.Nifti1Pair):\n        # Also apply the transform to the dim_info fields\n        new_dim = list(reoriented.header.get_dim_info())\n        for idx, value in enumerate(new_dim):\n            # For each value, leave as None if it was that way,\n            # otherwise check where we have mapped it to\n            if value is None:\n                continue\n            new_dim[idx] = np.where(ornt[:, 0] == idx)[0]\n\n        reoriented.header.set_dim_info(*new_dim)\n\n    return reoriented\n", "path": "nipype/interfaces/image.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\n# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-\n# vi: set ft=python sts=4 ts=4 sw=4 et:\n\nfrom ..utils.filemanip import fname_presuffix\nfrom .base import (SimpleInterface, TraitedSpec, BaseInterfaceInputSpec,\n                   traits, File)\nfrom .. import LooseVersion\n\n\nclass RescaleInputSpec(BaseInterfaceInputSpec):\n    in_file = File(exists=True, mandatory=True,\n                   desc='Skull-stripped image to rescale')\n    ref_file = File(exists=True, mandatory=True,\n                    desc='Skull-stripped reference image')\n    invert = traits.Bool(desc='Invert contrast of rescaled image')\n    percentile = traits.Range(low=0., high=50., value=0., usedefault=True,\n                              desc='Percentile to use for reference to allow '\n                                   'for outliers - 1 indicates the 1st and '\n                                   '99th percentiles in the input file will '\n                                   'be mapped to the 99th and 1st percentiles '\n                                   'in the reference; 0 indicates minima and '\n                                   'maxima will be mapped')\n\n\nclass RescaleOutputSpec(TraitedSpec):\n    out_file = File(exists=True, desc='Rescaled image')\n\n\nclass Rescale(SimpleInterface):\n    \"\"\"Rescale an image\n\n    Rescales the non-zero portion of ``in_file`` to match the bounds of the\n    non-zero portion of ``ref_file``.\n    Reference values in the input and reference images are defined by the\n    ``percentile`` parameter, and the reference values in each image are\n    identified and the remaining values are scaled accordingly.\n    In the case of ``percentile == 0``, the reference values are the maxima\n    and minima of each image.\n    If the ``invert`` parameter is set, the input file is inverted prior to\n    rescaling.\n\n    Examples\n    --------\n\n    To use a high-resolution T1w image as a registration target for a T2\\*\n    image, it may be useful to invert the T1w image and rescale to the T2\\*\n    range.\n    Using the 1st and 99th percentiles may reduce the impact of outlier\n    voxels.\n\n    >>> from nipype.interfaces.image import Rescale\n    >>> invert_t1w = Rescale(invert=True)\n    >>> invert_t1w.inputs.in_file = 'structural.nii'\n    >>> invert_t1w.inputs.ref_file = 'functional.nii'\n    >>> invert_t1w.inputs.percentile = 1.\n    >>> res = invert_t1w.run()  # doctest: +SKIP\n\n    \"\"\"\n    input_spec = RescaleInputSpec\n    output_spec = RescaleOutputSpec\n\n    def _run_interface(self, runtime):\n        import numpy as np\n        import nibabel as nb\n\n        img = nb.load(self.inputs.in_file)\n        data = img.get_data()\n        ref_data = nb.load(self.inputs.ref_file).get_data()\n\n        in_mask = data > 0\n        ref_mask = ref_data > 0\n\n        q = [self.inputs.percentile, 100. - self.inputs.percentile]\n        in_low, in_high = np.percentile(data[in_mask], q)\n        ref_low, ref_high = np.percentile(ref_data[ref_mask], q)\n        scale_factor = (ref_high - ref_low) / (in_high - in_low)\n\n        signal = in_high - data if self.inputs.invert else data - in_low\n        out_data = in_mask * (signal * scale_factor + ref_low)\n\n        suffix = '_inv' if self.inputs.invert else '_rescaled'\n        out_file = fname_presuffix(self.inputs.in_file, suffix=suffix,\n                                   newpath=runtime.cwd)\n        img.__class__(out_data, img.affine, img.header).to_filename(out_file)\n\n        self._results['out_file'] = out_file\n        return runtime\n\n\n_axes = ('RL', 'AP', 'SI')\n_orientations = tuple(\n    ''.join((x[i], y[j], z[k]))\n    for x in _axes for y in _axes for z in _axes\n    if x != y != z != x\n    for i in (0, 1) for j in (0, 1) for k in (0, 1))\n\n\nclass ReorientInputSpec(BaseInterfaceInputSpec):\n    in_file = File(exists=True, mandatory=True, desc='Input image')\n    orientation = traits.Enum(_orientations, usedefault=True,\n                              desc='Target axis orientation')\n\n\nclass ReorientOutputSpec(TraitedSpec):\n    out_file = File(exists=True, desc='Reoriented image')\n    transform = File(exists=True,\n                     desc='Affine transform from input orientation to output')\n\n\nclass Reorient(SimpleInterface):\n    \"\"\"Conform an image to a given orientation\n\nFlips and reorder the image data array so that the axes match the\ndirections indicated in ``orientation``.\nThe default ``RAS`` orientation corresponds to the first axis being ordered\nfrom left to right, the second axis from posterior to anterior, and the\nthird axis from inferior to superior.\n\nFor oblique images, the original orientation is considered to be the\nclosest plumb orientation.\n\nNo resampling is performed, and thus the output image is not de-obliqued\nor registered to any other image or template.\n\nThe effective transform is calculated from the original affine matrix to\nthe reoriented affine matrix.\n\nExamples\n--------\n\nIf an image is not reoriented, the original file is not modified\n\n.. testsetup::\n\n    >>> def print_affine(matrix):\n    ...     print(str(matrix).replace(']', ' ').replace('[', ' '))\n\n>>> import numpy as np\n>>> from nipype.interfaces.image import Reorient\n>>> reorient = Reorient(orientation='LPS')\n>>> reorient.inputs.in_file = 'segmentation0.nii.gz'\n>>> res = reorient.run()\n>>> res.outputs.out_file\n'segmentation0.nii.gz'\n\n>>> print_affine(np.loadtxt(res.outputs.transform))\n1.  0.  0.  0.\n0.  1.  0.  0.\n0.  0.  1.  0.\n0.  0.  0.  1.\n\n>>> reorient.inputs.orientation = 'RAS'\n>>> res = reorient.run()\n>>> res.outputs.out_file  # doctest: +ELLIPSIS\n'.../segmentation0_ras.nii.gz'\n\n>>> print_affine(np.loadtxt(res.outputs.transform))\n-1.   0.   0.  60.\n 0.  -1.   0.  72.\n 0.   0.   1.   0.\n 0.   0.   0.   1.\n\n.. testcleanup::\n\n    >>> import os\n    >>> os.unlink(res.outputs.out_file)\n    >>> os.unlink(res.outputs.transform)\n\n\"\"\"\n    input_spec = ReorientInputSpec\n    output_spec = ReorientOutputSpec\n\n    def _run_interface(self, runtime):\n        import numpy as np\n        import nibabel as nb\n        from nibabel.orientations import (\n            axcodes2ornt, ornt_transform, inv_ornt_aff)\n\n        fname = self.inputs.in_file\n        orig_img = nb.load(fname)\n\n        # Find transform from current (approximate) orientation to\n        # target, in nibabel orientation matrix and affine forms\n        orig_ornt = nb.io_orientation(orig_img.affine)\n        targ_ornt = axcodes2ornt(self.inputs.orientation)\n        transform = ornt_transform(orig_ornt, targ_ornt)\n        affine_xfm = inv_ornt_aff(transform, orig_img.shape)\n\n        # Check can be eliminated when minimum nibabel version >= 2.4\n        if LooseVersion(nb.__version__) >= LooseVersion('2.4.0'):\n            reoriented = orig_img.as_reoriented(transform)\n        else:\n            reoriented = _as_reoriented_backport(orig_img, transform)\n\n        # Image may be reoriented\n        if reoriented is not orig_img:\n            suffix = '_' + self.inputs.orientation.lower()\n            out_name = fname_presuffix(fname, suffix=suffix,\n                                       newpath=runtime.cwd)\n            reoriented.to_filename(out_name)\n        else:\n            out_name = fname\n\n        mat_name = fname_presuffix(fname, suffix='.mat',\n                                   newpath=runtime.cwd, use_ext=False)\n        np.savetxt(mat_name, affine_xfm, fmt='%.08f')\n\n        self._results['out_file'] = out_name\n        self._results['transform'] = mat_name\n\n        return runtime\n\n\ndef _as_reoriented_backport(img, ornt):\n    \"\"\"Backport of img.as_reoriented as of nibabel 2.4.0\"\"\"\n    import numpy as np\n    import nibabel as nb\n    from nibabel.orientations import inv_ornt_aff\n    if np.array_equal(ornt, [[0, 1], [1, 1], [2, 1]]):\n        return img\n\n    t_arr = nb.apply_orientation(img.get_data(), ornt)\n    new_aff = img.affine.dot(inv_ornt_aff(ornt, img.shape))\n    reoriented = img.__class__(t_arr, new_aff, img.header)\n\n    if isinstance(reoriented, nb.Nifti1Pair):\n        # Also apply the transform to the dim_info fields\n        new_dim = [None if orig_dim is None else int(ornt[orig_dim, 0])\n                   for orig_dim in img.header.get_dim_info()]\n\n        reoriented.header.set_dim_info(*new_dim)\n\n    return reoriented\n", "path": "nipype/interfaces/image.py"}]}