Skip to content

Commit 7f5fd97

Browse files
committed
enh: calcmedian interface
1 parent 32e724c commit 7f5fd97

File tree

2 files changed

+62
-2
lines changed

2 files changed

+62
-2
lines changed

nipype/algorithms/misc.py

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
InputMultiPath, OutputMultiPath,
3434
BaseInterfaceInputSpec, isdefined,
3535
DynamicTraitedSpec, Undefined)
36-
from ..utils.filemanip import fname_presuffix, split_filename
36+
from ..utils.filemanip import fname_presuffix, split_filename, filename_to_list
3737
from ..utils import NUMPY_MMAP
3838

3939
from . import confounds
@@ -1380,6 +1380,51 @@ def merge_rois(in_files, in_idxs, in_ref,
13801380
return out_file
13811381

13821382

1383+
class CalculateMedianInputSpec(BaseInterfaceInputSpec):
1384+
in_file = InputMultiPath(File(exists=True, mandatory=True,
1385+
desc="One or more realigned Nifti 4D timeseries"))
1386+
median_file = traits.Str('median.nii.gz', usedefault=True,
1387+
desc="Filename to store median image")
1388+
1389+
class CalculateMedianOutputSpec(TraitedSpec):
1390+
median_file = File(exists=True)
1391+
1392+
class CalculateMedian(BaseInterface):
1393+
"""
1394+
Computes an average of the median across one or more 4D Nifti timeseries
1395+
1396+
Example
1397+
-------
1398+
1399+
>>> from nipype.algorithms.misc import CalculateMedian
1400+
>>> mean = CalculateMedian()
1401+
>>> mean.inputs.in_file = 'functional.nii'
1402+
>>> mean.run() # doctest: +SKIP
1403+
1404+
"""
1405+
input_spec = CalculateMedianInputSpec
1406+
output_spec = CalculateMedianOutputSpec
1407+
1408+
def _run_interface(self, runtime):
1409+
total = None
1410+
for idx, fname in enumerate(filename_to_list(self.inputs.in_file)):
1411+
img = nb.load(fname, mmap=NUMPY_MMAP)
1412+
data = np.median(img.get_data(), axis=3)
1413+
if total is None:
1414+
total = data
1415+
else:
1416+
total += data
1417+
median_img = nb.Nifti1Image(total/(idx + 1), img.affine, img.header)
1418+
filename = os.path.join(os.getcwd(), self.inputs.median_file)
1419+
median_img.to_filename(filename)
1420+
return runtime
1421+
1422+
def _list_outputs(self):
1423+
outputs = self._outputs().get()
1424+
outputs['median_file'] = os.path.abspath(self.inputs.median_file)
1425+
return outputs
1426+
1427+
13831428
# Deprecated interfaces ------------------------------------------------------
13841429

13851430
class Distance(nam.Distance):

nipype/algorithms/tests/test_misc.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from nipype.algorithms import misc
1010
from nipype.utils.filemanip import fname_presuffix
1111
from nipype.testing.fixtures import create_analyze_pair_file_in_directory
12+
from nipype.utils import NUMPY_MMAP
1213

1314

1415
def test_CreateNifti(create_analyze_pair_file_in_directory):
@@ -31,4 +32,18 @@ def test_CreateNifti(create_analyze_pair_file_in_directory):
3132
result = create_nifti.run()
3233

3334
assert os.path.exists(result.outputs.nifti_file)
34-
assert nb.load(result.outputs.nifti_file)
35+
assert nb.load(result.outputs.nifti_file, mmap=NUMPY_MMAP)
36+
37+
def test_CalculateMedian(create_analyze_pair_file_in_directory):
38+
39+
filelist, outdir = create_analyze_pair_file_in_directory
40+
41+
mean = misc.CalculateMedian()
42+
43+
with pytest.raises(TypeError): mean.run()
44+
45+
mean.inputs.in_file = filelist[0]
46+
eg = mean.run()
47+
48+
assert os.path.exists(eg.outputs.median_file)
49+
assert nb.load(eg.outputs.median_file, mmap=NUMPY_MMAP)

0 commit comments

Comments
 (0)