1
1
"""Image tools interfaces."""
2
-
2
+ import numpy as np
3
+ import nibabel as nb
4
+ from nipype .utils .filemanip import fname_presuffix
3
5
from nipype import logging
4
6
from nipype .interfaces .base import (
5
7
traits , TraitedSpec , BaseInterfaceInputSpec , SimpleInterface , File
@@ -45,10 +47,6 @@ def _run_interface(self, runtime):
45
47
46
48
def extract_b0 (in_file , b0_ixs , newpath = None ):
47
49
"""Extract the *b0* volumes from a DWI dataset."""
48
- import numpy as np
49
- import nibabel as nb
50
- from nipype .utils .filemanip import fname_presuffix
51
-
52
50
out_file = fname_presuffix (
53
51
in_file , suffix = '_b0' , newpath = newpath )
54
52
@@ -71,13 +69,13 @@ class _RescaleB0InputSpec(BaseInterfaceInputSpec):
71
69
72
70
73
71
class _RescaleB0OutputSpec (TraitedSpec ):
74
- out_file = File (exists = True , desc = 'b0 file' )
72
+ out_ref = File (exists = True , desc = 'One average b0 file' )
73
+ out_b0s = File (exists = True , desc = 'series of rescaled b0 volumes' )
75
74
76
75
77
76
class RescaleB0 (SimpleInterface ):
78
77
"""
79
- Rescale the b0 volumes to deal with average signal decay over time
80
- and output the median image.
78
+ Rescale the b0 volumes to deal with average signal decay over time.
81
79
82
80
Example
83
81
-------
@@ -93,44 +91,54 @@ class RescaleB0(SimpleInterface):
93
91
output_spec = _RescaleB0OutputSpec
94
92
95
93
def _run_interface (self , runtime ):
96
- self ._results ['out_file ' ] = rescale_b0 (
94
+ self ._results ['out_b0s ' ] = rescale_b0 (
97
95
self .inputs .in_file ,
98
96
self .inputs .mask_file ,
99
- newpath = runtime .cwd )
97
+ newpath = runtime .cwd
98
+ )
99
+ self ._results ['out_ref' ] = median (
100
+ self ._results ['out_b0s' ],
101
+ newpath = runtime .cwd
102
+ )
100
103
return runtime
101
104
102
105
103
106
def rescale_b0 (in_file , mask_file , newpath = None ):
104
- """
105
- Rescale the input volumes using the median signal intensity
106
- and output a median image.
107
- """
108
- import numpy as np
109
- import nibabel as nb
110
- from nipype .utils .filemanip import fname_presuffix
111
-
107
+ """Rescale the input volumes using the median signal intensity."""
112
108
out_file = fname_presuffix (
113
- in_file , suffix = '_median_b0 ' , newpath = newpath )
109
+ in_file , suffix = '_rescaled_b0 ' , newpath = newpath )
114
110
115
111
img = nb .load (in_file )
116
112
if img .dataobj .ndim == 3 :
117
113
return in_file
118
- if img .shape [- 1 ] == 1 :
119
- nb .squeeze_image (img ).to_filename (out_file )
120
- return out_file
121
114
122
115
data = img .get_fdata (dtype = 'float32' )
123
116
mask_img = nb .load (mask_file )
124
117
mask_data = mask_img .get_fdata (dtype = 'float32' )
125
118
126
- median_signal = data [mask_data > 0 , ...].median (axis = 0 )
127
-
119
+ median_signal = np .median (data [mask_data > 0 , ...], axis = 0 )
128
120
rescaled_data = 1000 * data / median_signal
121
+ hdr = img .header .copy ()
122
+ nb .Nifti1Image (rescaled_data , img .affine , hdr ).to_filename (out_file )
123
+ return out_file
124
+
125
+
126
+ def median (in_file , newpath = None ):
127
+ """Average a 4D dataset across the last dimension using median."""
128
+ out_file = fname_presuffix (
129
+ in_file , suffix = '_b0ref' , newpath = newpath )
130
+
131
+ img = nb .load (in_file )
132
+ if img .dataobj .ndim == 3 :
133
+ return in_file
134
+ if img .shape [- 1 ] == 1 :
135
+ nb .squeeze_image (img ).to_filename (out_file )
136
+ return out_file
129
137
130
- median_data = np .median (rescaled_data , axis = - 1 )
138
+ median_data = np .median (img .get_fdata (dtype = 'float32' ),
139
+ axis = - 1 )
131
140
132
141
hdr = img .header .copy ()
133
- hdr .set_data_shape (median_data .shape )
134
142
hdr .set_xyzt_units ('mm' )
135
143
hdr .set_data_dtype (np .float32 )
136
144
nb .Nifti1Image (median_data , img .affine , hdr ).to_filename (out_file )
0 commit comments