1
1
# emacs: -*- mode: python; py-indent-offset: 4; indent-tabs-mode: nil -*-
2
2
# vi: set ft=python sts=4 ts=4 sw=4 et:
3
3
"""Within-baby registration of a T1w into a T2w image."""
4
- from typing import Optional
4
+ from __future__ import annotations
5
5
6
6
from nipype .interfaces import utility as niu
7
7
from nipype .pipeline import engine as pe
8
- from pkg_resources import resource_filename as pkgr_fn
8
+ from niworkflows . interfaces . fixes import FixHeaderApplyTransforms as ApplyTransforms
9
9
10
10
11
11
def init_coregistration_wf (
12
12
* ,
13
13
bspline_fitting_distance : int = 200 ,
14
14
mem_gb : float = 3.0 ,
15
- omp_nthreads : Optional [ int ] = None ,
15
+ omp_nthreads : int | None = None ,
16
16
sloppy : bool = False ,
17
17
debug : bool = False ,
18
- precomputed_mask : bool = False ,
18
+ t1w_mask : bool = False ,
19
+ probmap : bool = False ,
19
20
name : str = "coregistration_wf" ,
20
21
):
21
22
"""
@@ -52,11 +53,12 @@ def init_coregistration_wf(
52
53
Run in *sloppy* mode.
53
54
debug : :obj:`bool`
54
55
Produce intermediate registration files
55
- precomputed_mask : :obj:`bool`
56
+ t1w_mask : :obj:`bool`
56
57
A precomputed mask for the T1w is available. In this case, generate a
57
58
quick mask to assist in coregistration, but use the precomputed mask
58
59
as the final output.
59
-
60
+ probmap: :obj:`bool`
61
+ A probabilistic brainmask is present in T2w space.
60
62
61
63
Inputs
62
64
------
@@ -66,8 +68,8 @@ def init_coregistration_wf(
66
68
The preprocessed input T2w image (Denoising/INU/Clipping)
67
69
in_mask : :obj:`str`
68
70
The brainmask.
69
- If `precomputed_mask ` is False, will be in T2w space.
70
- If `precomputed_mask ` is True, will be in T1w space.
71
+ If `t1w_mask ` is False, will be in T2w space.
72
+ If `t1w_mask ` is True, will be in T1w space.
71
73
in_probmap : :obj:`str`
72
74
The probabilistic brainmask, as obtained in T2w space.
73
75
@@ -172,7 +174,7 @@ def init_coregistration_wf(
172
174
])
173
175
# fmt: on
174
176
175
- if precomputed_mask :
177
+ if t1w_mask :
176
178
# The input mask is already in T1w space.
177
179
# Generate a quick, rough mask of the T2w to be used to facilitate co-registration.
178
180
from sdcflows .interfaces .brainmask import BrainExtraction
@@ -187,7 +189,9 @@ def init_coregistration_wf(
187
189
(inputnode , outputnode , [("in_mask" , "t1w_mask" )]),
188
190
])
189
191
# fmt:on
190
- else :
192
+ return workflow
193
+
194
+ if probmap :
191
195
# The T2w mask from the brain extraction workflow will be mapped to T1w space
192
196
map_mask = pe .Node (ApplyTransforms (interpolation = "Gaussian" ), name = "map_mask" , mem_gb = 1 )
193
197
thr_mask = pe .Node (Binarize (thresh_low = 0.80 ), name = "thr_mask" )
@@ -207,4 +211,72 @@ def init_coregistration_wf(
207
211
(thr_mask , apply_mask , [("out_mask" , "in_mask" )]),
208
212
])
209
213
# fmt:on
214
+ return workflow
215
+
216
+ # A precomputed T2w mask was provided
217
+ map_precomp_mask = pe .Node (
218
+ ApplyTransforms (interpolation = "MultiLabel" ), name = 'map_precomp_mask'
219
+ )
220
+ # fmt:off
221
+ workflow .connect ([
222
+ (inputnode , map_precomp_mask , [
223
+ ('in_t1w' , 'reference_image' ),
224
+ ('in_mask' , 'input_image' )]),
225
+ (coreg , map_precomp_mask , [
226
+ ("reverse_transforms" , "transforms" ),
227
+ ("reverse_invert_flags" , "invert_transform_flags" )]),
228
+ (map_precomp_mask , final_n4 , [('output_image' , 'weight_image' )]),
229
+ (map_precomp_mask , outputnode , [('output_image' , 't1w_mask' )]),
230
+ (map_precomp_mask , apply_mask , [('output_image' , 'in_mask' )]),
231
+ ])
232
+ # fmt:on
233
+ return workflow
234
+
235
+
236
+ def init_coregister_derivatives_wf (
237
+ * , t1w_mask : bool , t1w_aseg : bool , t2w_aseg : bool , name : str = 'coregister_derivatives_wf'
238
+ ):
239
+ """Move derivatives from T1w / T2w space."""
240
+ workflow = pe .Workflow (name = name )
241
+ inputnode = pe .Node (
242
+ niu .IdentityInterface (
243
+ fields = ['t1w_ref' , 't2w_ref' , 't1w_mask' , 't1w_aseg' , 't2w_aseg' , 't1w2t2w_xfm' ]
244
+ ),
245
+ name = 'inputnode' ,
246
+ )
247
+ outputnode = pe .Node (niu .IdentityInterface (fields = ['t2w_mask' , 't1w_aseg' ]), name = 'outputnode' )
248
+
249
+ if t1w_mask :
250
+ t1wmask2t2w = pe .Node (ApplyTransforms (interpolation = "MultiLabel" ), name = 't1wmask2t2w' )
251
+ # fmt:off
252
+ workflow .connect ([
253
+ (inputnode , t1wmask2t2w , [
254
+ ('t1w_mask' , 'input_image' ),
255
+ ('t1w2t2w_xfm' , 'transforms' ),
256
+ ('t2w_ref' , 'reference_image' )]),
257
+ (t1wmask2t2w , outputnode , [('output_image' , 't2w_mask' )])
258
+ ])
259
+ # fmt:on
260
+ if t1w_aseg :
261
+ # fmt:off
262
+ t1waseg2t2w = pe .Node (ApplyTransforms (interpolation = "MultiLabel" ), name = 't2wmask2t1w' )
263
+ workflow .connect ([
264
+ (inputnode , t1waseg2t2w , [
265
+ ('t2w_aseg' , 'input_image' ),
266
+ ('t1w2t2w_xfm' , 'transforms' ),
267
+ ('t1w_ref' , 'reference_image' )]),
268
+ (t1waseg2t2w , outputnode , [('output_image' , 't1w_aseg' )])
269
+ ])
270
+ # fmt:on
271
+ if t2w_aseg :
272
+ # fmt:off
273
+ t2waseg2t1w = pe .Node (ApplyTransforms (interpolation = "MultiLabel" ), name = 't2wmask2t1w' )
274
+ workflow .connect ([
275
+ (inputnode , t2waseg2t1w , [
276
+ ('t2w_aseg' , 'input_image' ),
277
+ ('t1w2t2w_xfm' , 'reverse_transforms' ),
278
+ ('t1w_ref' , 'reference_image' )]),
279
+ (t2waseg2t1w , outputnode , [('output_image' , 't1w_aseg' )])
280
+ ])
281
+ # fmt:on
210
282
return workflow
0 commit comments