1
1
"""Image tools interfaces."""
2
- import numpy as np
3
- import nibabel as nb
4
- from nipype .utils .filemanip import fname_presuffix
2
+ from pathlib import Path
3
+
5
4
from nipype import logging
6
5
from nipype .interfaces .base import (
7
- traits , TraitedSpec , BaseInterfaceInputSpec , SimpleInterface , File
6
+ BaseInterfaceInputSpec ,
7
+ File ,
8
+ SimpleInterface ,
9
+ TraitedSpec ,
10
+ traits
8
11
)
9
12
13
+ from dmriprep .utils .images import extract_b0 , median , rescale_b0
14
+
10
15
LOGGER = logging .getLogger ('nipype.interface' )
11
16
12
17
13
18
class _ExtractB0InputSpec (BaseInterfaceInputSpec ):
14
19
in_file = File (exists = True , mandatory = True , desc = 'dwi file' )
15
- b0_ixs = traits .List (traits .Int , mandatory = True ,
16
- desc = 'Index of b0s' )
20
+ b0_ixs = traits .List (traits .Int , mandatory = True , desc = 'Index of b0s' )
17
21
18
22
19
23
class _ExtractB0OutputSpec (TraitedSpec ):
20
- out_file = File (exists = True , desc = 'b0 file' )
24
+ out_file = File (exists = True , desc = 'output b0 file' )
21
25
22
26
23
27
class ExtractB0 (SimpleInterface ):
@@ -38,29 +42,19 @@ class ExtractB0(SimpleInterface):
38
42
output_spec = _ExtractB0OutputSpec
39
43
40
44
def _run_interface (self , runtime ):
41
- self ._results ['out_file' ] = extract_b0 (
42
- self .inputs .in_file ,
43
- self .inputs .b0_ixs ,
44
- newpath = runtime .cwd )
45
- return runtime
46
-
47
-
48
- def extract_b0 (in_file , b0_ixs , newpath = None ):
49
- """Extract the *b0* volumes from a DWI dataset."""
50
- out_file = fname_presuffix (
51
- in_file , suffix = '_b0' , newpath = newpath )
52
-
53
- img = nb .load (in_file )
54
- data = img .get_fdata (dtype = 'float32' )
45
+ from nipype .utils .filemanip import fname_presuffix
55
46
56
- b0 = data [..., b0_ixs ]
47
+ out_file = fname_presuffix (
48
+ self .inputs .in_file ,
49
+ suffix = '_b0' ,
50
+ use_ext = True ,
51
+ newpath = str (Path (runtime .cwd ).absolute ()),
52
+ )
57
53
58
- hdr = img .header .copy ()
59
- hdr .set_data_shape (b0 .shape )
60
- hdr .set_xyzt_units ('mm' )
61
- hdr .set_data_dtype (np .float32 )
62
- nb .Nifti1Image (b0 , img .affine , hdr ).to_filename (out_file )
63
- return out_file
54
+ self ._results ['out_file' ] = extract_b0 (
55
+ self .inputs .in_file , self .inputs .b0_ixs , out_file
56
+ )
57
+ return runtime
64
58
65
59
66
60
class _RescaleB0InputSpec (BaseInterfaceInputSpec ):
@@ -91,55 +85,27 @@ class RescaleB0(SimpleInterface):
91
85
output_spec = _RescaleB0OutputSpec
92
86
93
87
def _run_interface (self , runtime ):
88
+ from nipype .utils .filemanip import fname_presuffix
89
+
90
+ out_b0s = fname_presuffix (
91
+ self .inputs .in_file ,
92
+ suffix = '_rescaled' ,
93
+ use_ext = True ,
94
+ newpath = str (Path (runtime .cwd ).absolute ())
95
+ )
96
+ out_ref = fname_presuffix (
97
+ self .inputs .in_file ,
98
+ suffix = '_ref' ,
99
+ use_ext = True ,
100
+ newpath = str (Path (runtime .cwd ).absolute ())
101
+ )
102
+
94
103
self ._results ['out_b0s' ] = rescale_b0 (
95
104
self .inputs .in_file ,
96
- self .inputs .mask_file ,
97
- newpath = runtime .cwd
105
+ self .inputs .mask_file , out_b0s
98
106
)
99
107
self ._results ['out_ref' ] = median (
100
108
self ._results ['out_b0s' ],
101
- newpath = runtime . cwd
109
+ out_path = out_ref
102
110
)
103
111
return runtime
104
-
105
-
106
- def rescale_b0 (in_file , mask_file , newpath = None ):
107
- """Rescale the input volumes using the median signal intensity."""
108
- out_file = fname_presuffix (
109
- in_file , suffix = '_rescaled_b0' , newpath = newpath )
110
-
111
- img = nb .load (in_file )
112
- if img .dataobj .ndim == 3 :
113
- return in_file
114
-
115
- data = img .get_fdata (dtype = 'float32' )
116
- mask_img = nb .load (mask_file )
117
- mask_data = mask_img .get_fdata (dtype = 'float32' )
118
-
119
- median_signal = np .median (data [mask_data > 0 , ...], axis = 0 )
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
137
-
138
- median_data = np .median (img .get_fdata (dtype = 'float32' ),
139
- axis = - 1 )
140
-
141
- hdr = img .header .copy ()
142
- hdr .set_xyzt_units ('mm' )
143
- hdr .set_data_dtype (np .float32 )
144
- nb .Nifti1Image (median_data , img .affine , hdr ).to_filename (out_file )
145
- return out_file
0 commit comments