def _run_interface(self, runtime): img = nb.load(self.inputs.in_file) ntotal = img.shape[-1] if img.dataobj.ndim == 4 else 1 t_mask = np.zeros((ntotal, ), dtype=bool) if ntotal == 1: self._results["t_mask"] = [True] self._results["n_dummy"] = 1 return runtime from nipype.algorithms.confounds import is_outlier data = img.get_fdata(dtype="float32")[..., :self.inputs.n_volumes] # Data can come with outliers showing very high numbers - preemptively prune data = np.clip( data, a_min=0.0 if self.inputs.nonnegative else np.percentile(data, 0.2), a_max=np.percentile(data, 99.8), ) self._results["n_dummy"] = is_outlier(np.mean(data, axis=(0, 1, 2))) start = 0 stop = self._results["n_dummy"] if stop < 2: stop = min(ntotal, self.inputs.n_volumes) start = max(0, stop - self.inputs.zero_dummy_masked) t_mask[start:stop] = True self._results["t_mask"] = t_mask.tolist() return runtime
def _get_vols_to_discard(img): ''' Takes a nifti file, extracts the mean signal of the first 50 volumes and computes which are outliers. is_outlier function: computes Modified Z-Scores (https://www.itl.nist.gov/div898/handbook/eda/section3/eda35h.htm) to determine which volumes are outliers. ''' from nipype.algorithms.confounds import is_outlier data_slice = sitk.GetArrayFromImage(img)[:50, :, :, :] global_signal = data_slice.mean(axis=-1).mean(axis=-1).mean(axis=-1) return is_outlier(global_signal)
def _get_series_len(bold_fname): from nipype.algorithms.confounds import is_outlier import nibabel as nb import numpy as np img = nb.load(bold_fname) if len(img.shape) < 4: return 1 data = img.get_fdata(dtype="float32") # Data can come with outliers showing very high numbers - preemptively prune data = np.clip( data, a_min=0.0, a_max=np.percentile(data, 99.8), ) outliers = is_outlier(np.mean(data, axis=(0, 1, 2))) return img.shape[3] - outliers
def _run_interface(self, runtime): in_nii = nb.load(self.inputs.in_file) data_slice = in_nii.dataobj[:, :, :, :50] global_signal = data_slice.mean(axis=0).mean(axis=0).mean(axis=0) n_volumes_to_discard = is_outlier(global_signal) out_ref_fname = os.path.abspath("ref_image.nii.gz") if n_volumes_to_discard == 0: if in_nii.shape[-1] > 40: slice = data_slice[:, :, :, 20:40] slice_fname = os.path.abspath("slice.nii.gz") nb.Nifti1Image(slice, in_nii.affine, in_nii.header).to_filename(slice_fname) else: slice_fname = self.inputs.in_file if self.inputs.mc_method == "AFNI": res = afni.Volreg(in_file=slice_fname, args='-Fourier -twopass', zpad=4, outputtype='NIFTI_GZ').run() elif self.inputs.mc_method == "FSL": res = fsl.MCFLIRT(in_file=slice_fname, ref_vol=0, interpolation='sinc').run() mc_slice_nii = nb.load(res.outputs.out_file) median_image_data = np.median(mc_slice_nii.get_data(), axis=3) nb.Nifti1Image(median_image_data, mc_slice_nii.affine, mc_slice_nii.header).to_filename(out_ref_fname) else: median_image_data = np.median( data_slice[:, :, :, :n_volumes_to_discard], axis=3) nb.Nifti1Image(median_image_data, in_nii.affine, in_nii.header).to_filename(out_ref_fname) self._results = dict() self._results["ref_image"] = out_ref_fname self._results["n_volumes_to_discard"] = n_volumes_to_discard return runtime
def _get_vols_to_discard(img): from nipype.algorithms.confounds import is_outlier data_slice = img.dataobj[:, :, :, :50] global_signal = data_slice.mean(axis=0).mean(axis=0).mean(axis=0) return is_outlier(global_signal)
def test_outliers(tmpdir): np.random.seed(0) in_data = np.random.randn(100) in_data[0] += 10 assert is_outlier(in_data) == 1