Skip to content

Commit 9d83d50

Browse files
authored
Merge pull request #101 from oesteban/fix/90-bad-b0-reference
FIX: Minor refactor of DWI/brainmasks utilities and dtypes
2 parents a27fc16 + a66d685 commit 9d83d50

File tree

2 files changed

+26
-34
lines changed

2 files changed

+26
-34
lines changed

dmriprep/interfaces/images.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ def _run_interface(self, runtime):
4747
out_file = fname_presuffix(
4848
self.inputs.in_file,
4949
suffix='_b0',
50-
use_ext=True,
5150
newpath=str(Path(runtime.cwd).absolute()),
5251
)
5352

5453
self._results['out_file'] = extract_b0(
55-
self.inputs.in_file, self.inputs.b0_ixs, out_file
54+
self.inputs.in_file, self.inputs.b0_ixs,
55+
out_path=out_file
5656
)
5757
return runtime
5858

@@ -65,6 +65,7 @@ class _RescaleB0InputSpec(BaseInterfaceInputSpec):
6565
class _RescaleB0OutputSpec(TraitedSpec):
6666
out_ref = File(exists=True, desc='One average b0 file')
6767
out_b0s = File(exists=True, desc='series of rescaled b0 volumes')
68+
signal_drift = traits.List(traits.Float, desc='estimated signal drift factors')
6869

6970

7071
class RescaleB0(SimpleInterface):
@@ -90,17 +91,15 @@ def _run_interface(self, runtime):
9091
out_b0s = fname_presuffix(
9192
self.inputs.in_file,
9293
suffix='_rescaled',
93-
use_ext=True,
9494
newpath=str(Path(runtime.cwd).absolute())
9595
)
9696
out_ref = fname_presuffix(
9797
self.inputs.in_file,
9898
suffix='_ref',
99-
use_ext=True,
10099
newpath=str(Path(runtime.cwd).absolute())
101100
)
102101

103-
self._results['out_b0s'] = rescale_b0(
102+
self._results['out_b0s'], self._results['signal_drift'] = rescale_b0(
104103
self.inputs.in_file,
105104
self.inputs.mask_file, out_b0s
106105
)

dmriprep/utils/images.py

Lines changed: 22 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,21 @@
1-
import nibabel as nb
1+
"""Utilities to handle images."""
22
import numpy as np
3+
import nibabel as nb
34
from nipype.utils.filemanip import fname_presuffix
45

56

67
def extract_b0(in_file, b0_ixs, out_path=None):
78
"""Extract the *b0* volumes from a DWI dataset."""
89
if out_path is None:
9-
out_path = fname_presuffix(
10-
in_file, suffix='_b0', use_ext=True)
10+
out_path = fname_presuffix(in_file, suffix='_b0')
1111

1212
img = nb.load(in_file)
13-
data = img.get_fdata()
14-
15-
b0 = data[..., b0_ixs]
13+
bzeros = np.squeeze(np.asanyarray(img.dataobj)[..., b0_ixs])
1614

1715
hdr = img.header.copy()
18-
hdr.set_data_shape(b0.shape)
16+
hdr.set_data_shape(bzeros.shape)
1917
hdr.set_xyzt_units('mm')
20-
nb.Nifti1Image(b0.astype(hdr.get_data_dtype()), img.affine, hdr).to_filename(out_path)
18+
nb.Nifti1Image(bzeros, img.affine, hdr).to_filename(out_path)
2119
return out_path
2220

2321

@@ -27,24 +25,25 @@ def rescale_b0(in_file, mask_file, out_path=None):
2725
out_path = fname_presuffix(
2826
in_file, suffix='_rescaled', use_ext=True)
2927

30-
img = nb.load(in_file)
28+
img = nb.squeeze_image(nb.load(in_file))
3129
if img.dataobj.ndim == 3:
32-
return in_file
30+
return in_file, [1.0]
3331

32+
mask_data = nb.load(mask_file).get_fdata() > 0
33+
34+
dtype = img.get_data_dtype()
3435
data = img.get_fdata()
35-
mask_img = nb.load(mask_file)
36-
mask_data = mask_img.get_fdata()
3736

38-
median_signal = np.median(data[mask_data > 0, ...], axis=0)
39-
rescaled_data = 1000 * data / median_signal
40-
hdr = img.header.copy()
41-
nb.Nifti1Image(
42-
rescaled_data.astype(hdr.get_data_dtype()), img.affine, hdr
43-
).to_filename(out_path)
44-
return out_path
37+
median_signal = np.median(data[mask_data, ...], axis=0)
38+
# Normalize to the first volume
39+
signal_drift = median_signal[0] / median_signal
40+
data /= signal_drift
4541

42+
nb.Nifti1Image(data.astype(dtype), img.affine, img.header).to_filename(out_path)
43+
return out_path, signal_drift.tolist()
4644

47-
def median(in_file, dtype=None, out_path=None):
45+
46+
def median(in_file, out_path=None):
4847
"""Average a 4D dataset across the last dimension using median."""
4948
if out_path is None:
5049
out_path = fname_presuffix(
@@ -57,14 +56,8 @@ def median(in_file, dtype=None, out_path=None):
5756
nb.squeeze_image(img).to_filename(out_path)
5857
return out_path
5958

60-
median_data = np.median(img.get_fdata(dtype=dtype),
61-
axis=-1)
59+
dtype = img.get_data_dtype()
60+
median_data = np.median(img.get_fdata(), axis=-1)
6261

63-
hdr = img.header.copy()
64-
hdr.set_xyzt_units('mm')
65-
if dtype is not None:
66-
hdr.set_data_dtype(dtype)
67-
else:
68-
dtype = hdr.get_data_dtype()
69-
nb.Nifti1Image(median_data.astype(dtype), img.affine, hdr).to_filename(out_path)
62+
nb.Nifti1Image(median_data.astype(dtype), img.affine, img.header).to_filename(out_path)
7063
return out_path

0 commit comments

Comments
 (0)