@@ -73,6 +73,7 @@ def _sdc_unwarp(
73
73
coordinates : np .ndarray ,
74
74
pe_info : Tuple [int , float ],
75
75
hmc_xfm : np .ndarray | None ,
76
+ jacobian : bool ,
76
77
fmap_hz : np .ndarray ,
77
78
output_dtype : str | np .dtype | None = None ,
78
79
order : int = 3 ,
@@ -95,13 +96,6 @@ def _sdc_unwarp(
95
96
vsm = fmap_hz * pe_info [1 ]
96
97
coordinates [pe_info [0 ], ...] += vsm
97
98
98
- # The Jacobian determinant image is the amount of stretching in the PE direction.
99
- # Using central differences accounts for the shift in neighboring voxels.
100
- # The full Jacobian at each voxel would be a 3x3 matrix, but because there is
101
- # only warping in one direction, we end up with a diagonal matrix with two 1s.
102
- # The following is the other entry at each voxel, and hence the determinant.
103
- jacobian = 1 + np .gradient (vsm , axis = pe_info [0 ])
104
-
105
99
resampled = ndi .map_coordinates (
106
100
data ,
107
101
coordinates ,
@@ -110,7 +104,15 @@ def _sdc_unwarp(
110
104
mode = mode ,
111
105
cval = cval ,
112
106
prefilter = prefilter ,
113
- ) * jacobian
107
+ )
108
+
109
+ # The Jacobian determinant image is the amount of stretching in the PE direction.
110
+ # Using central differences accounts for the shift in neighboring voxels.
111
+ # The full Jacobian at each voxel would be a 3x3 matrix, but because there is
112
+ # only warping in one direction, we end up with a diagonal matrix with two 1s.
113
+ # The following is the other entry at each voxel, and hence the determinant.
114
+ if jacobian :
115
+ resampled *= 1 + np .gradient (vsm , axis = pe_info [0 ])
114
116
115
117
return resampled
116
118
@@ -138,6 +140,7 @@ async def unwarp_parallel(
138
140
fmap_hz : np .ndarray ,
139
141
pe_info : Sequence [Tuple [int , float ]],
140
142
xfms : Sequence [np .ndarray ],
143
+ jacobian : bool ,
141
144
order : int = 3 ,
142
145
mode : str = "constant" ,
143
146
cval : float = 0.0 ,
@@ -162,6 +165,8 @@ async def unwarp_parallel(
162
165
pe_info : :obj:`tuple` of (:obj:`int`, :obj:`float`)
163
166
A tuple containing the index of the phase-encoding axis in the data array and
164
167
the readout time (including sign, if displacements must be reversed)
168
+ jacobian : :class:`bool`
169
+ If :obj:`True`, apply Jacobian determinant correction after unwarping.
165
170
xfms : :obj:`list` of obj:`~numpy.ndarray`
166
171
A list of 4×4 matrices, each one formalizing
167
172
the estimated head motion alignment to the scan's reference.
@@ -200,6 +205,7 @@ async def unwarp_parallel(
200
205
201
206
func = partial (
202
207
_sdc_unwarp ,
208
+ jacobian = jacobian ,
203
209
fmap_hz = fmap_hz ,
204
210
output_dtype = output_dtype ,
205
211
order = order ,
@@ -370,6 +376,7 @@ def apply(
370
376
pe_dir : str | Sequence [str ],
371
377
ro_time : float | Sequence [float ],
372
378
xfms : Sequence [np .ndarray ] | None = None ,
379
+ jacobian : bool = True ,
373
380
xfm_data2fmap : np .ndarray | None = None ,
374
381
approx : bool = True ,
375
382
order : int = 3 ,
@@ -394,6 +401,8 @@ def apply(
394
401
A valid ``PhaseEncodingDirection`` metadata value.
395
402
ro_time : :obj:`float` or :obj:`list` of :obj:`float`
396
403
The total readout time in seconds.
404
+ jacobian : :class:`bool`
405
+ If :obj:`True`, apply Jacobian determinant correction after unwarping.
397
406
xfms : :obj:`None` or :obj:`list`
398
407
A list of 4×4 matrices, each one formalizing
399
408
the estimated head motion alignment to the scan's reference.
@@ -528,6 +537,7 @@ def apply(
528
537
self .mapped .get_fdata (dtype = "float32" ), # fieldmap in Hz
529
538
pe_info ,
530
539
xfms ,
540
+ jacobian ,
531
541
output_dtype = 'float32' ,
532
542
order = order ,
533
543
mode = mode ,
0 commit comments