@@ -50,6 +50,11 @@ class ComputeDVARSInputSpec(BaseInterfaceInputSpec):
50
50
remove_zerovariance = traits .Bool (
51
51
True , usedefault = True , desc = "remove voxels with zero variance"
52
52
)
53
+ variance_tol = traits .Float (
54
+ 1e-7 ,
55
+ usedefault = True ,
56
+ desc = "maximum variance to consider \" close to\" zero for the purposes of removal" ,
57
+ )
53
58
save_std = traits .Bool (True , usedefault = True , desc = "save standardized DVARS" )
54
59
save_nstd = traits .Bool (False , usedefault = True , desc = "save non-standardized DVARS" )
55
60
save_vxstd = traits .Bool (
@@ -167,6 +172,7 @@ def _run_interface(self, runtime):
167
172
self .inputs .in_file ,
168
173
self .inputs .in_mask ,
169
174
remove_zerovariance = self .inputs .remove_zerovariance ,
175
+ variance_tol = self .inputs .variance_tol ,
170
176
intensity_normalization = self .inputs .intensity_normalization ,
171
177
)
172
178
@@ -994,8 +1000,19 @@ def _list_outputs(self):
994
1000
return self ._results
995
1001
996
1002
1003
+ def _AR_est_YW (x , order , rxx = None ):
1004
+ """Retrieve AR coefficients while dropping the sig_sq return value"""
1005
+ from nitime .algorithms import AR_est_YW
1006
+
1007
+ return AR_est_YW (x , order , rxx = rxx )[0 ]
1008
+
1009
+
997
1010
def compute_dvars (
998
- in_file , in_mask , remove_zerovariance = False , intensity_normalization = 1000
1011
+ in_file ,
1012
+ in_mask ,
1013
+ remove_zerovariance = False ,
1014
+ intensity_normalization = 1000 ,
1015
+ variance_tol = 0.0 ,
999
1016
):
1000
1017
"""
1001
1018
Compute the :abbr:`DVARS (D referring to temporal
@@ -1027,36 +1044,35 @@ def compute_dvars(
1027
1044
"""
1028
1045
import numpy as np
1029
1046
import nibabel as nb
1030
- from nitime .algorithms import AR_est_YW
1031
1047
import warnings
1032
1048
1033
- func = nb .load (in_file ).get_fdata ( dtype = np . float32 )
1034
- mask = np .asanyarray (nb .load (in_mask ).dataobj ). astype ( np . uint8 )
1049
+ func = np . float32 ( nb .load (in_file ).dataobj )
1050
+ mask = np .bool_ (nb .load (in_mask ).dataobj )
1035
1051
1036
1052
if len (func .shape ) != 4 :
1037
1053
raise RuntimeError ("Input fMRI dataset should be 4-dimensional" )
1038
1054
1039
- idx = np .where (mask > 0 )
1040
- mfunc = func [idx [0 ], idx [1 ], idx [2 ], :]
1055
+ mfunc = func [mask ]
1041
1056
1042
1057
if intensity_normalization != 0 :
1043
1058
mfunc = (mfunc / np .median (mfunc )) * intensity_normalization
1044
1059
1045
1060
# Robust standard deviation (we are using "lower" interpolation
1046
1061
# because this is what FSL is doing
1047
1062
func_sd = (
1048
- np .percentile (mfunc , 75 , axis = 1 , interpolation = "lower" )
1049
- - np .percentile (mfunc , 25 , axis = 1 , interpolation = "lower" )
1063
+ np .percentile (mfunc , 75 , axis = 1 , method = "lower" )
1064
+ - np .percentile (mfunc , 25 , axis = 1 , method = "lower" )
1050
1065
) / 1.349
1051
1066
1052
1067
if remove_zerovariance :
1053
- mfunc = mfunc [func_sd != 0 , :]
1054
- func_sd = func_sd [func_sd != 0 ]
1068
+ zero_variance_voxels = func_sd > variance_tol
1069
+ mfunc = mfunc [zero_variance_voxels , :]
1070
+ func_sd = func_sd [zero_variance_voxels ]
1055
1071
1056
1072
# Compute (non-robust) estimate of lag-1 autocorrelation
1057
1073
ar1 = np .apply_along_axis (
1058
- AR_est_YW , 1 , regress_poly (0 , mfunc , remove_mean = True )[0 ].astype (np .float32 ), 1
1059
- )[:, 0 ]
1074
+ _AR_est_YW , 1 , regress_poly (0 , mfunc , remove_mean = True )[0 ].astype (np .float32 ), 1
1075
+ )
1060
1076
1061
1077
# Compute (predicted) standard deviation of temporal difference time series
1062
1078
diff_sdhat = np .squeeze (np .sqrt (((1 - ar1 ) * 2 ).tolist ())) * func_sd
0 commit comments