From 6877fa12f7abcd5441b71c097796e512276fb67c Mon Sep 17 00:00:00 2001 From: mjoseph Date: Tue, 25 Feb 2020 15:25:28 -0500 Subject: [PATCH 1/9] update out_path --- dmriprep/interfaces/images.py | 65 ++-------------------------------- dmriprep/utils/images.py | 66 +++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 63 deletions(-) create mode 100644 dmriprep/utils/images.py diff --git a/dmriprep/interfaces/images.py b/dmriprep/interfaces/images.py index a59fedfb..20904b43 100644 --- a/dmriprep/interfaces/images.py +++ b/dmriprep/interfaces/images.py @@ -1,12 +1,11 @@ """Image tools interfaces.""" -import numpy as np -import nibabel as nb -from nipype.utils.filemanip import fname_presuffix from nipype import logging from nipype.interfaces.base import ( traits, TraitedSpec, BaseInterfaceInputSpec, SimpleInterface, File ) +from dmriprep.utils.images import extract_b0, rescale_b0, median + LOGGER = logging.getLogger('nipype.interface') @@ -45,24 +44,6 @@ def _run_interface(self, runtime): return runtime -def extract_b0(in_file, b0_ixs, newpath=None): - """Extract the *b0* volumes from a DWI dataset.""" - out_file = fname_presuffix( - in_file, suffix='_b0', newpath=newpath) - - img = nb.load(in_file) - data = img.get_fdata(dtype='float32') - - b0 = data[..., b0_ixs] - - hdr = img.header.copy() - hdr.set_data_shape(b0.shape) - hdr.set_xyzt_units('mm') - hdr.set_data_dtype(np.float32) - nb.Nifti1Image(b0, img.affine, hdr).to_filename(out_file) - return out_file - - class _RescaleB0InputSpec(BaseInterfaceInputSpec): in_file = File(exists=True, mandatory=True, desc='b0s file') mask_file = File(exists=True, mandatory=True, desc='mask file') @@ -101,45 +82,3 @@ def _run_interface(self, runtime): newpath=runtime.cwd ) return runtime - - -def rescale_b0(in_file, mask_file, newpath=None): - """Rescale the input volumes using the median signal intensity.""" - out_file = fname_presuffix( - in_file, suffix='_rescaled_b0', newpath=newpath) - - img = nb.load(in_file) - if img.dataobj.ndim == 3: - return in_file - - data = img.get_fdata(dtype='float32') - mask_img = nb.load(mask_file) - mask_data = mask_img.get_fdata(dtype='float32') - - median_signal = np.median(data[mask_data > 0, ...], axis=0) - rescaled_data = 1000 * data / median_signal - hdr = img.header.copy() - nb.Nifti1Image(rescaled_data, img.affine, hdr).to_filename(out_file) - return out_file - - -def median(in_file, newpath=None): - """Average a 4D dataset across the last dimension using median.""" - out_file = fname_presuffix( - in_file, suffix='_b0ref', newpath=newpath) - - img = nb.load(in_file) - if img.dataobj.ndim == 3: - return in_file - if img.shape[-1] == 1: - nb.squeeze_image(img).to_filename(out_file) - return out_file - - median_data = np.median(img.get_fdata(dtype='float32'), - axis=-1) - - hdr = img.header.copy() - hdr.set_xyzt_units('mm') - hdr.set_data_dtype(np.float32) - nb.Nifti1Image(median_data, img.affine, hdr).to_filename(out_file) - return out_file diff --git a/dmriprep/utils/images.py b/dmriprep/utils/images.py new file mode 100644 index 00000000..257a6cbe --- /dev/null +++ b/dmriprep/utils/images.py @@ -0,0 +1,66 @@ +import numpy as np +import nibabel as nb +from nipype.utils.filemanip import fname_presuffix + + +def extract_b0(in_file, b0_ixs, out_path=None): + """Extract the *b0* volumes from a DWI dataset.""" + if out_path is None: + out_path = fname_presuffix( + in_file, suffix='_b0', use_ext=True) + + img = nb.load(in_file) + data = img.get_fdata(dtype='float32') + + b0 = data[..., b0_ixs] + + hdr = img.header.copy() + hdr.set_data_shape(b0.shape) + hdr.set_xyzt_units('mm') + hdr.set_data_dtype(np.float32) + nb.Nifti1Image(b0, img.affine, hdr).to_filename(out_path) + return out_path + + +def rescale_b0(in_file, mask_file, out_path=None): + """Rescale the input volumes using the median signal intensity.""" + if out_path is None: + out_path = fname_presuffix( + in_file, suffix='_rescaled_b0', use_ext=True) + + img = nb.load(in_file) + if img.dataobj.ndim == 3: + return in_file + + data = img.get_fdata(dtype='float32') + mask_img = nb.load(mask_file) + mask_data = mask_img.get_fdata(dtype='float32') + + median_signal = np.median(data[mask_data > 0, ...], axis=0) + rescaled_data = 1000 * data / median_signal + hdr = img.header.copy() + nb.Nifti1Image(rescaled_data, img.affine, hdr).to_filename(out_path) + return out_path + + +def median(in_file, out_path=None): + """Average a 4D dataset across the last dimension using median.""" + if out_path is None: + out_path = fname_presuffix( + in_file, suffix='_b0ref', use_ext=True) + + img = nb.load(in_file) + if img.dataobj.ndim == 3: + return in_file + if img.shape[-1] == 1: + nb.squeeze_image(img).to_filename(out_path) + return out_path + + median_data = np.median(img.get_fdata(dtype='float32'), + axis=-1) + + hdr = img.header.copy() + hdr.set_xyzt_units('mm') + hdr.set_data_dtype(np.float32) + nb.Nifti1Image(median_data, img.affine, hdr).to_filename(out_path) + return out_path From 2bfe9bb7fa201ba0bb9cf623c0401ccac30b5a95 Mon Sep 17 00:00:00 2001 From: Michael Joseph Date: Tue, 25 Feb 2020 16:22:50 -0500 Subject: [PATCH 2/9] Update dmriprep/utils/images.py Co-Authored-By: Oscar Esteban --- dmriprep/utils/images.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmriprep/utils/images.py b/dmriprep/utils/images.py index 257a6cbe..7e8d4fc2 100644 --- a/dmriprep/utils/images.py +++ b/dmriprep/utils/images.py @@ -43,7 +43,7 @@ def rescale_b0(in_file, mask_file, out_path=None): return out_path -def median(in_file, out_path=None): +def median(in_file, dtype=None, out_path=None): """Average a 4D dataset across the last dimension using median.""" if out_path is None: out_path = fname_presuffix( From da9daad10f912ca840d0298d8d76e078656f6aef Mon Sep 17 00:00:00 2001 From: Michael Joseph Date: Tue, 25 Feb 2020 16:23:00 -0500 Subject: [PATCH 3/9] Update dmriprep/utils/images.py Co-Authored-By: Oscar Esteban --- dmriprep/utils/images.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dmriprep/utils/images.py b/dmriprep/utils/images.py index 7e8d4fc2..7d53a0c9 100644 --- a/dmriprep/utils/images.py +++ b/dmriprep/utils/images.py @@ -61,6 +61,7 @@ def median(in_file, dtype=None, out_path=None): hdr = img.header.copy() hdr.set_xyzt_units('mm') - hdr.set_data_dtype(np.float32) + if dtype is not None: + hdr.set_data_dtype(dtype) nb.Nifti1Image(median_data, img.affine, hdr).to_filename(out_path) return out_path From 098004e099657d19df7bd6044cb1f23757b25c6f Mon Sep 17 00:00:00 2001 From: Michael Joseph Date: Tue, 25 Feb 2020 16:29:37 -0500 Subject: [PATCH 4/9] Update dmriprep/utils/images.py Co-Authored-By: Oscar Esteban --- dmriprep/utils/images.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmriprep/utils/images.py b/dmriprep/utils/images.py index 7d53a0c9..5dacca7c 100644 --- a/dmriprep/utils/images.py +++ b/dmriprep/utils/images.py @@ -56,7 +56,7 @@ def median(in_file, dtype=None, out_path=None): nb.squeeze_image(img).to_filename(out_path) return out_path - median_data = np.median(img.get_fdata(dtype='float32'), + median_data = np.median(img.get_fdata(dtype=dtype), axis=-1) hdr = img.header.copy() From fb5d070f12ab18162698b3326ec32417009d7c54 Mon Sep 17 00:00:00 2001 From: Michael Joseph Date: Tue, 25 Feb 2020 16:46:54 -0500 Subject: [PATCH 5/9] Apply @oesteban's suggestions Co-Authored-By: Oscar Esteban --- dmriprep/utils/images.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/dmriprep/utils/images.py b/dmriprep/utils/images.py index 5dacca7c..33a64fc3 100644 --- a/dmriprep/utils/images.py +++ b/dmriprep/utils/images.py @@ -17,8 +17,7 @@ def extract_b0(in_file, b0_ixs, out_path=None): hdr = img.header.copy() hdr.set_data_shape(b0.shape) hdr.set_xyzt_units('mm') - hdr.set_data_dtype(np.float32) - nb.Nifti1Image(b0, img.affine, hdr).to_filename(out_path) + nb.Nifti1Image(b0.astype(hdr.get_data_dtype()), img.affine, hdr).to_filename(out_path) return out_path @@ -32,14 +31,14 @@ def rescale_b0(in_file, mask_file, out_path=None): if img.dataobj.ndim == 3: return in_file - data = img.get_fdata(dtype='float32') + data = img.get_fdata() mask_img = nb.load(mask_file) - mask_data = mask_img.get_fdata(dtype='float32') + mask_data = mask_img.get_fdata() median_signal = np.median(data[mask_data > 0, ...], axis=0) rescaled_data = 1000 * data / median_signal hdr = img.header.copy() - nb.Nifti1Image(rescaled_data, img.affine, hdr).to_filename(out_path) + nb.Nifti1Image(rescaled_data.astype(hdr.get_data_dtype()), img.affine, hdr).to_filename(out_path) return out_path @@ -63,5 +62,7 @@ def median(in_file, dtype=None, out_path=None): hdr.set_xyzt_units('mm') if dtype is not None: hdr.set_data_dtype(dtype) - nb.Nifti1Image(median_data, img.affine, hdr).to_filename(out_path) + else: + dtype = hdr.get_data_dtype() + nb.Nifti1Image(median_data.astype(dtype), img.affine, hdr).to_filename(out_path) return out_path From e253ae82ba2645b21146fa369262041595ee076e Mon Sep 17 00:00:00 2001 From: mjoseph Date: Tue, 25 Feb 2020 17:02:05 -0500 Subject: [PATCH 6/9] fix pep8 --- dmriprep/utils/images.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/dmriprep/utils/images.py b/dmriprep/utils/images.py index 33a64fc3..ec913f44 100644 --- a/dmriprep/utils/images.py +++ b/dmriprep/utils/images.py @@ -38,7 +38,9 @@ def rescale_b0(in_file, mask_file, out_path=None): median_signal = np.median(data[mask_data > 0, ...], axis=0) rescaled_data = 1000 * data / median_signal hdr = img.header.copy() - nb.Nifti1Image(rescaled_data.astype(hdr.get_data_dtype()), img.affine, hdr).to_filename(out_path) + nb.Nifti1Image( + rescaled_data.astype(hdr.get_data_dtype()), img.affine, hdr + ).to_filename(out_path) return out_path From 76c934d411dcb072622ef210c4f5d8cb02fa0f1a Mon Sep 17 00:00:00 2001 From: Michael Joseph Date: Tue, 25 Feb 2020 17:03:14 -0500 Subject: [PATCH 7/9] Update dmriprep/utils/images.py Co-Authored-By: Oscar Esteban --- dmriprep/utils/images.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dmriprep/utils/images.py b/dmriprep/utils/images.py index ec913f44..26898000 100644 --- a/dmriprep/utils/images.py +++ b/dmriprep/utils/images.py @@ -10,7 +10,7 @@ def extract_b0(in_file, b0_ixs, out_path=None): in_file, suffix='_b0', use_ext=True) img = nb.load(in_file) - data = img.get_fdata(dtype='float32') + data = img.get_fdata() b0 = data[..., b0_ixs] From 68c0c0998ebf723ecd659960cab20518c89b9fd5 Mon Sep 17 00:00:00 2001 From: mjoseph Date: Wed, 11 Mar 2020 11:45:03 -0400 Subject: [PATCH 8/9] modify newpath to out_path --- dmriprep/interfaces/images.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dmriprep/interfaces/images.py b/dmriprep/interfaces/images.py index 20904b43..33526b3f 100644 --- a/dmriprep/interfaces/images.py +++ b/dmriprep/interfaces/images.py @@ -40,7 +40,7 @@ def _run_interface(self, runtime): self._results['out_file'] = extract_b0( self.inputs.in_file, self.inputs.b0_ixs, - newpath=runtime.cwd) + out_path=runtime.cwd) return runtime @@ -75,10 +75,10 @@ def _run_interface(self, runtime): self._results['out_b0s'] = rescale_b0( self.inputs.in_file, self.inputs.mask_file, - newpath=runtime.cwd + out_path=runtime.cwd ) self._results['out_ref'] = median( self._results['out_b0s'], - newpath=runtime.cwd + out_path=runtime.cwd ) return runtime From a0e205cc69964d9dac8a7c21f92397be8f6fca8b Mon Sep 17 00:00:00 2001 From: mjoseph Date: Tue, 17 Mar 2020 15:25:36 -0400 Subject: [PATCH 9/9] fix image interfaces --- dmriprep/interfaces/images.py | 49 +++++++++++++++++++++++++++-------- dmriprep/utils/images.py | 4 +-- 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/dmriprep/interfaces/images.py b/dmriprep/interfaces/images.py index 33526b3f..5d278145 100644 --- a/dmriprep/interfaces/images.py +++ b/dmriprep/interfaces/images.py @@ -1,22 +1,27 @@ """Image tools interfaces.""" +from pathlib import Path + from nipype import logging from nipype.interfaces.base import ( - traits, TraitedSpec, BaseInterfaceInputSpec, SimpleInterface, File + BaseInterfaceInputSpec, + File, + SimpleInterface, + TraitedSpec, + traits ) -from dmriprep.utils.images import extract_b0, rescale_b0, median +from dmriprep.utils.images import extract_b0, median, rescale_b0 LOGGER = logging.getLogger('nipype.interface') class _ExtractB0InputSpec(BaseInterfaceInputSpec): in_file = File(exists=True, mandatory=True, desc='dwi file') - b0_ixs = traits.List(traits.Int, mandatory=True, - desc='Index of b0s') + b0_ixs = traits.List(traits.Int, mandatory=True, desc='Index of b0s') class _ExtractB0OutputSpec(TraitedSpec): - out_file = File(exists=True, desc='b0 file') + out_file = File(exists=True, desc='output b0 file') class ExtractB0(SimpleInterface): @@ -37,10 +42,18 @@ class ExtractB0(SimpleInterface): output_spec = _ExtractB0OutputSpec def _run_interface(self, runtime): - self._results['out_file'] = extract_b0( + from nipype.utils.filemanip import fname_presuffix + + out_file = fname_presuffix( self.inputs.in_file, - self.inputs.b0_ixs, - out_path=runtime.cwd) + suffix='_b0', + use_ext=True, + newpath=str(Path(runtime.cwd).absolute()), + ) + + self._results['out_file'] = extract_b0( + self.inputs.in_file, self.inputs.b0_ixs, out_file + ) return runtime @@ -72,13 +85,27 @@ class RescaleB0(SimpleInterface): output_spec = _RescaleB0OutputSpec def _run_interface(self, runtime): + from nipype.utils.filemanip import fname_presuffix + + out_b0s = fname_presuffix( + self.inputs.in_file, + suffix='_rescaled', + use_ext=True, + newpath=str(Path(runtime.cwd).absolute()) + ) + out_ref = fname_presuffix( + self.inputs.in_file, + suffix='_ref', + use_ext=True, + newpath=str(Path(runtime.cwd).absolute()) + ) + self._results['out_b0s'] = rescale_b0( self.inputs.in_file, - self.inputs.mask_file, - out_path=runtime.cwd + self.inputs.mask_file, out_b0s ) self._results['out_ref'] = median( self._results['out_b0s'], - out_path=runtime.cwd + out_path=out_ref ) return runtime diff --git a/dmriprep/utils/images.py b/dmriprep/utils/images.py index 26898000..1a9af57e 100644 --- a/dmriprep/utils/images.py +++ b/dmriprep/utils/images.py @@ -1,5 +1,5 @@ -import numpy as np import nibabel as nb +import numpy as np from nipype.utils.filemanip import fname_presuffix @@ -25,7 +25,7 @@ def rescale_b0(in_file, mask_file, out_path=None): """Rescale the input volumes using the median signal intensity.""" if out_path is None: out_path = fname_presuffix( - in_file, suffix='_rescaled_b0', use_ext=True) + in_file, suffix='_rescaled', use_ext=True) img = nb.load(in_file) if img.dataobj.ndim == 3: