def _run_interface(self, runtime): in_files = self.inputs.in_files if not isinstance(in_files, list): in_files = [self.inputs.in_files] # Generate output average name early self._results['out_avg'] = genfname(self.inputs.in_files[0], suffix='avg') if self.inputs.to_ras: in_files = [reorient(inf) for inf in in_files] if len(in_files) == 1: filenii = nb.load(in_files[0]) filedata = filenii.get_data() # magnitude files can have an extra dimension empty if filedata.ndim == 5: sqdata = np.squeeze(filedata) if sqdata.ndim == 5: raise RuntimeError('Input image (%s) is 5D' % in_files[0]) else: in_files = [genfname(in_files[0], suffix='squeezed')] nb.Nifti1Image(sqdata, filenii.get_affine(), filenii.get_header()).to_filename( in_files[0]) if np.squeeze(nb.load(in_files[0]).get_data()).ndim < 4: self._results['out_file'] = in_files[0] self._results['out_avg'] = in_files[0] # TODO: generate identity out_mats and zero-filled out_movpar return runtime in_files = in_files[0] else: magmrg = fsl.Merge(dimension='t', in_files=self.inputs.in_files) in_files = magmrg.run().outputs.merged_file mcflirt = fsl.MCFLIRT(cost='normcorr', save_mats=True, save_plots=True, ref_vol=0, in_file=in_files) mcres = mcflirt.run() self._results['out_mats'] = mcres.outputs.mat_file self._results['out_movpar'] = mcres.outputs.par_file self._results['out_file'] = mcres.outputs.out_file hmcnii = nb.load(mcres.outputs.out_file) hmcdat = hmcnii.get_data().mean(axis=3) if self.inputs.zero_based_avg: hmcdat -= hmcdat.min() nb.Nifti1Image(hmcdat, hmcnii.get_affine(), hmcnii.get_header()).to_filename( self._results['out_avg']) return runtime
def _run_interface(self, runtime): in_files = self.inputs.in_files if not isinstance(in_files, list): in_files = [self.inputs.in_files] # Generate output average name early self._results['out_avg'] = genfname(self.inputs.in_files[0], suffix='avg') if self.inputs.to_ras: in_files = [reorient(inf) for inf in in_files] if len(in_files) == 1: filenii = nb.load(in_files[0]) filedata = filenii.get_data() # magnitude files can have an extra dimension empty if filedata.ndim == 5: sqdata = np.squeeze(filedata) if sqdata.ndim == 5: raise RuntimeError('Input image (%s) is 5D' % in_files[0]) else: in_files = [genfname(in_files[0], suffix='squeezed')] nb.Nifti1Image(sqdata, filenii.get_affine(), filenii.get_header()).to_filename(in_files[0]) if np.squeeze(nb.load(in_files[0]).get_data()).ndim < 4: self._results['out_file'] = in_files[0] self._results['out_avg'] = in_files[0] # TODO: generate identity out_mats and zero-filled out_movpar return runtime in_files = in_files[0] else: magmrg = fsl.Merge(dimension='t', in_files=self.inputs.in_files) in_files = magmrg.run().outputs.merged_file mcflirt = fsl.MCFLIRT(cost='normcorr', save_mats=True, save_plots=True, ref_vol=0, in_file=in_files) mcres = mcflirt.run() self._results['out_mats'] = mcres.outputs.mat_file self._results['out_movpar'] = mcres.outputs.par_file self._results['out_file'] = mcres.outputs.out_file hmcnii = nb.load(mcres.outputs.out_file) hmcdat = hmcnii.get_data().mean(axis=3) if self.inputs.zero_based_avg: hmcdat -= hmcdat.min() nb.Nifti1Image( hmcdat, hmcnii.get_affine(), hmcnii.get_header()).to_filename( self._results['out_avg']) return runtime
def _run_interface(self, runtime): target_affine = None target_shape = None if isdefined(self.inputs.target_affine): target_affine = self.inputs.target_affine if isdefined(self.inputs.target_shape): target_shape = self.inputs.target_shape masknii = compute_epi_mask( self.inputs.in_files, lower_cutoff=self.inputs.lower_cutoff, upper_cutoff=self.inputs.upper_cutoff, connected=self.inputs.connected, opening=self.inputs.opening, exclude_zeros=self.inputs.exclude_zeros, ensure_finite=self.inputs.ensure_finite, target_affine=target_affine, target_shape=target_shape ) self._results['out_mask'] = genfname( self.inputs.in_files[0], suffix='mask') masknii.to_filename(self._results['out_mask']) return runtime
def _run_interface(self, runtime): out_file = genfname(self.inputs.in_file, 'brainmask') nii = nb.load(self.inputs.in_file) data = nii.get_data() data[nb.load(self.inputs.in_mask).get_data() <= 0] = 0 nb.Nifti1Image(data, nii.affine, nii.header).to_filename(out_file) self._results['out_file'] = out_file return runtime
def _run_interface(self, runtime): out_file = genfname(self.inputs.in_file, 'brainmask') nii = nb.load(self.inputs.in_file) data = nii.get_data() data[nb.load(self.inputs.in_mask).get_data() <= 0] = 0 nb.Nifti1Image(data, nii.affine, nii.header).to_filename(out_file) self._results['out_file'] = out_file return runtime
def _hz2rads(in_file, out_file=None): """Transform a fieldmap in Hz into rad/s""" from math import pi import nibabel as nb from fmriprep.utils.misc import genfname if out_file is None: out_file = genfname(in_file, 'rads') nii = nb.load(in_file) data = nii.get_data() * 2.0 * pi nb.Nifti1Image(data, nii.get_affine(), nii.get_header()).to_filename(out_file) return out_file
def _hz2rads(in_file, out_file=None): """Transform a fieldmap in Hz into rad/s""" from math import pi import nibabel as nb from fmriprep.utils.misc import genfname if out_file is None: out_file = genfname(in_file, 'rads') nii = nb.load(in_file) data = nii.get_data() * 2.0 * pi nb.Nifti1Image(data, nii.get_affine(), nii.get_header()).to_filename(out_file) return out_file
def reorient(in_file, out_file=None): import nibabel as nb from fmriprep.utils.misc import genfname from builtins import (str, bytes) if out_file is None: out_file = genfname(in_file, suffix='ras') if isinstance(in_file, (str, bytes)): nii = nb.load(in_file) nii = nb.as_closest_canonical(nii) nii.to_filename(out_file) return out_file
def _gen_reference(fixed_image, moving_image, out_file=None): import numpy from nilearn.image import resample_img, load_img if out_file is None: out_file = genfname(fixed_image, suffix='reference') new_zooms = load_img(moving_image).header.get_zooms()[:3] # Avoid small differences in reported resolution to cause changes to # FOV. See https://github.com/poldracklab/fmriprep/issues/512 new_zooms_round = numpy.round(new_zooms, 3) resample_img(fixed_image, target_affine=numpy.diag(new_zooms_round), interpolation='nearest').to_filename(out_file) return out_file
def reorient(in_file, out_file=None): import nibabel as nb from fmriprep.utils.misc import genfname from builtins import (str, bytes) if out_file is None: out_file = genfname(in_file, suffix='ras') if isinstance(in_file, (str, bytes)): nii = nb.load(in_file) nii = nb.as_closest_canonical(nii) nii.to_filename(out_file) return out_file
def _gen_reference(fixed_image, moving_image, out_file=None): import numpy from nilearn.image import resample_img, load_img if out_file is None: out_file = genfname(fixed_image, suffix='reference') new_zooms = load_img(moving_image).header.get_zooms()[:3] # Avoid small differences in reported resolution to cause changes to # FOV. See https://github.com/poldracklab/fmriprep/issues/512 new_zooms_round = numpy.round(new_zooms, 3) resample_img(fixed_image, target_affine=numpy.diag(new_zooms_round), interpolation='nearest').to_filename(out_file) return out_file
def _flatten_split_merge(in_files): from builtins import bytes, str if isinstance(in_files, (bytes, str)): in_files = [in_files] nfiles = len(in_files) all_nii = [] for fname in in_files: nii = nb.squeeze_image(nb.load(fname)) if nii.get_data().ndim > 3: all_nii += nb.four_to_three(nii) else: all_nii.append(nii) if len(all_nii) == 1: LOGGER.warn('File %s cannot be split', all_nii[0]) return in_files[0], in_files if len(all_nii) == nfiles: flat_split = in_files else: splitname = genfname(in_files[0], suffix='split%04d') flat_split = [] for i, nii in enumerate(all_nii): flat_split.append(splitname % i) nii.to_filename(flat_split[-1]) # Only one 4D file was supplied if nfiles == 1: merged = in_files[0] else: # More that one in_files - need merge merged = genfname(in_files[0], suffix='merged') nb.concat_images(all_nii).to_filename(merged) return merged, flat_split
def _tohz(in_file, cutoff_hz, out_file=None): from math import pi import nibabel as nb from fmriprep.utils.misc import genfname if out_file is None: out_file = genfname(in_file, suffix='hz') fmapnii = nb.load(in_file) fmapdata = fmapnii.get_data() fmapdata *= (cutoff_hz / pi) nb.Nifti1Image(fmapdata, fmapnii.affine, fmapnii.header).to_filename(out_file) return out_file
def _demean(in_file, in_mask, out_file=None): import numpy as np import nibabel as nb from fmriprep.utils.misc import genfname if out_file is None: out_file = genfname(in_file, 'demeaned') nii = nb.load(in_file) msk = nb.load(in_mask).get_data() data = nii.get_data() data -= np.median(data[msk > 0]) nb.Nifti1Image(data, nii.affine, nii.header).to_filename(out_file) return out_file
def _flatten_split_merge(in_files): from builtins import bytes, str if isinstance(in_files, (bytes, str)): in_files = [in_files] nfiles = len(in_files) all_nii = [] for fname in in_files: nii = nb.squeeze_image(nb.load(fname)) if nii.get_data().ndim > 3: all_nii += nb.four_to_three(nii) else: all_nii.append(nii) if len(all_nii) == 1: LOGGER.warn('File %s cannot be split', all_nii[0]) return in_files[0], in_files if len(all_nii) == nfiles: flat_split = in_files else: splitname = genfname(in_files[0], suffix='split%04d') flat_split = [] for i, nii in enumerate(all_nii): flat_split.append(splitname % i) nii.to_filename(flat_split[-1]) # Only one 4D file was supplied if nfiles == 1: merged = in_files[0] else: # More that one in_files - need merge merged = genfname(in_files[0], suffix='merged') nb.concat_images(all_nii).to_filename(merged) return merged, flat_split
def _demean(in_file, in_mask, out_file=None): import numpy as np import nibabel as nb from fmriprep.utils.misc import genfname if out_file is None: out_file = genfname(in_file, 'demeaned') nii = nb.load(in_file) msk = nb.load(in_mask).get_data() data = nii.get_data() data -= np.median(data[msk > 0]) nb.Nifti1Image(data, nii.affine, nii.header).to_filename( out_file) return out_file
def _run_interface(self, runtime): self._results['out_file'] = genfname( self.inputs.in_files[0], suffix='merged') new_nii = concat_imgs(self.inputs.in_files, dtype=self.inputs.dtype) if isdefined(self.inputs.header_source): src_hdr = nb.load(self.inputs.header_source).header new_nii.header.set_xyzt_units(t=src_hdr.get_xyzt_units()[-1]) new_nii.header.set_zooms(list(new_nii.header.get_zooms()[:3]) + [src_hdr.get_zooms()[3]]) new_nii.to_filename(self._results['out_file']) return runtime
def _tohz(in_file, cutoff_hz, out_file=None): from math import pi import nibabel as nb from fmriprep.utils.misc import genfname if out_file is None: out_file = genfname(in_file, suffix='hz') fmapnii = nb.load(in_file) fmapdata = fmapnii.get_data() fmapdata = fmapdata * (cutoff_hz / pi) out_img = nb.Nifti1Image(fmapdata, fmapnii.affine, fmapnii.header) out_img.set_data_dtype('float32') out_img.to_filename(out_file) return out_file
def _run_interface(self, runtime): self._results['out_file'] = genfname(self.inputs.in_files[0], suffix='merged') new_nii = concat_imgs(self.inputs.in_files, dtype=self.inputs.dtype) if isdefined(self.inputs.header_source): src_hdr = nb.load(self.inputs.header_source).header new_nii.header.set_xyzt_units(t=src_hdr.get_xyzt_units()[-1]) new_nii.header.set_zooms( list(new_nii.header.get_zooms()[:3]) + [src_hdr.get_zooms()[3]]) new_nii.to_filename(self._results['out_file']) return runtime
def _torads(in_file, out_file=None): from math import pi import nibabel as nb import numpy as np from fmriprep.utils.misc import genfname if out_file is None: out_file = genfname(in_file, suffix='rad') fmapnii = nb.load(in_file) fmapdata = fmapnii.get_data() cutoff = max(abs(fmapdata.min()), fmapdata.max()) fmapdata *= (pi / cutoff) nb.Nifti1Image(fmapdata, fmapnii.affine, fmapnii.header).to_filename(out_file) return out_file, cutoff
def _torads(in_file, out_file=None): from math import pi import nibabel as nb from fmriprep.utils.misc import genfname if out_file is None: out_file = genfname(in_file, suffix='rad') fmapnii = nb.load(in_file) fmapdata = fmapnii.get_data() cutoff = max(abs(fmapdata.min()), fmapdata.max()) fmapdata = fmapdata * (pi / cutoff) out_img = nb.Nifti1Image(fmapdata, fmapnii.affine, fmapnii.header) out_img.set_data_dtype('float32') out_img.to_filename(out_file) return out_file, cutoff
def _run_interface(self, runtime): nii = nb.load(self.inputs.in_file) phaseEncDim = {'i': 0, 'j': 1, 'k': 2}[self.inputs.pe_dir[0]] if len(self.inputs.pe_dir) == 2: phaseEncSign = 1.0 else: phaseEncSign = -1.0 # Fix header hdr = nii.header.copy() hdr.set_data_dtype(np.dtype('<f4')) hdr.set_intent('vector', (), '') # Get data, convert to mm data = nii.get_data() aff = np.diag([1.0, 1.0, -1.0]) if np.linalg.det(aff) < 0 and phaseEncDim != 0: # Reverse direction since ITK is LPS aff *= -1.0 aff = aff.dot(nii.affine[:3, :3]) data *= phaseEncSign * nii.header.get_zooms()[phaseEncDim] # Add missing dimensions zeros = np.zeros_like(data) field = [zeros, zeros] field.insert(phaseEncDim, data) field = np.stack(field, -1) # Add empty axis field = field[:, :, :, np.newaxis, :] # Write out self._results['out_file'] = genfname( self.inputs.in_file, suffix='antswarp') nb.Nifti1Image( field.astype(np.dtype('<f4')), nii.affine, hdr).to_filename( self._results['out_file']) return runtime
def _run_interface(self, runtime): target_affine = None target_shape = None if isdefined(self.inputs.target_affine): target_affine = self.inputs.target_affine if isdefined(self.inputs.target_shape): target_shape = self.inputs.target_shape masknii = compute_epi_mask(self.inputs.in_files, lower_cutoff=self.inputs.lower_cutoff, upper_cutoff=self.inputs.upper_cutoff, connected=self.inputs.connected, opening=self.inputs.opening, exclude_zeros=self.inputs.exclude_zeros, ensure_finite=self.inputs.ensure_finite, target_affine=target_affine, target_shape=target_shape) self._results['out_mask'] = genfname(self.inputs.in_files[0], suffix='mask') masknii.to_filename(self._results['out_mask']) return runtime
def _run_interface(self, runtime): from scipy import ndimage as sim fmap_nii = nb.load(self.inputs.in_file) data = np.squeeze(fmap_nii.get_data().astype(np.float32)) # Despike / denoise (no-mask) if self.inputs.despike: data = _despike2d(data, self.inputs.despike_threshold) mask = None if isdefined(self.inputs.in_mask): masknii = nb.load(self.inputs.in_mask) mask = masknii.get_data().astype(np.uint8) # Dilate mask if self.inputs.mask_erode > 0: struc = sim.iterate_structure( sim.generate_binary_structure(3, 2), 1) mask = sim.binary_erosion( mask, struc, iterations=self.inputs.mask_erode).astype(np.uint8) # pylint: disable=no-member self._results['out_file'] = genfname(self.inputs.in_file, suffix='enh') datanii = nb.Nifti1Image(data, fmap_nii.affine, fmap_nii.header) if self.inputs.unwrap: data = _unwrap(data, self.inputs.in_magnitude, mask) self._results['out_unwrapped'] = genfname(self.inputs.in_file, suffix='unwrap') nb.Nifti1Image(data, fmap_nii.affine, fmap_nii.header).to_filename( self._results['out_unwrapped']) if not self.inputs.bspline_smooth: datanii.to_filename(self._results['out_file']) return runtime else: from fmriprep.utils import bspline as fbsp from statsmodels.robust.scale import mad # Fit BSplines (coarse) bspobj = fbsp.BSplineFieldmap(datanii, weights=mask, njobs=self.inputs.njobs) bspobj.fit() smoothed1 = bspobj.get_smoothed() # Manipulate the difference map diffmap = data - smoothed1.get_data() sderror = mad(diffmap[mask > 0]) LOGGER.info('SD of error after B-Spline fitting is %f', sderror) errormask = np.zeros_like(diffmap) errormask[np.abs(diffmap) > (10 * sderror)] = 1 errormask *= mask nslices = 0 try: errorslice = np.squeeze( np.argwhere(errormask.sum(0).sum(0) > 0)) nslices = errorslice[-1] - errorslice[0] except IndexError: # mask is empty, do not refine pass if nslices > 1: diffmapmsk = mask[..., errorslice[0]:errorslice[-1]] diffmapnii = nb.Nifti1Image( diffmap[..., errorslice[0]:errorslice[-1]] * diffmapmsk, datanii.affine, datanii.header) bspobj2 = fbsp.BSplineFieldmap(diffmapnii, knots_zooms=[24., 24., 4.], njobs=self.inputs.njobs) bspobj2.fit() smoothed2 = bspobj2.get_smoothed().get_data() final = smoothed1.get_data().copy() final[..., errorslice[0]:errorslice[-1]] += smoothed2 else: final = smoothed1.get_data() nb.Nifti1Image(final, datanii.affine, datanii.header).to_filename( self._results['out_file']) return runtime
def _run_interface(self, runtime): from scipy import ndimage as sim fmap_nii = nb.load(self.inputs.in_file) data = np.squeeze(fmap_nii.get_data().astype(np.float32)) # Despike / denoise (no-mask) if self.inputs.despike: data = _despike2d(data, self.inputs.despike_threshold) mask = None if isdefined(self.inputs.in_mask): masknii = nb.load(self.inputs.in_mask) mask = masknii.get_data().astype(np.uint8) # Dilate mask if self.inputs.mask_erode > 0: struc = sim.iterate_structure(sim.generate_binary_structure(3, 2), 1) mask = sim.binary_erosion( mask, struc, iterations=self.inputs.mask_erode ).astype(np.uint8) # pylint: disable=no-member self._results['out_file'] = genfname(self.inputs.in_file, suffix='enh') datanii = nb.Nifti1Image(data, fmap_nii.affine, fmap_nii.header) if self.inputs.unwrap: data = _unwrap(data, self.inputs.in_magnitude, mask) self._results['out_unwrapped'] = genfname(self.inputs.in_file, suffix='unwrap') nb.Nifti1Image(data, fmap_nii.affine, fmap_nii.header).to_filename( self._results['out_unwrapped']) if not self.inputs.bspline_smooth: datanii.to_filename(self._results['out_file']) return runtime else: from fmriprep.utils import bspline as fbsp from statsmodels.robust.scale import mad # Fit BSplines (coarse) bspobj = fbsp.BSplineFieldmap(datanii, weights=mask, njobs=self.inputs.njobs) bspobj.fit() smoothed1 = bspobj.get_smoothed() # Manipulate the difference map diffmap = data - smoothed1.get_data() sderror = mad(diffmap[mask > 0]) LOGGER.info('SD of error after B-Spline fitting is %f', sderror) errormask = np.zeros_like(diffmap) errormask[np.abs(diffmap) > (10 * sderror)] = 1 errormask *= mask nslices = 0 try: errorslice = np.squeeze(np.argwhere(errormask.sum(0).sum(0) > 0)) nslices = errorslice[-1] - errorslice[0] except IndexError: # mask is empty, do not refine pass if nslices > 1: diffmapmsk = mask[..., errorslice[0]:errorslice[-1]] diffmapnii = nb.Nifti1Image( diffmap[..., errorslice[0]:errorslice[-1]] * diffmapmsk, datanii.affine, datanii.header) bspobj2 = fbsp.BSplineFieldmap(diffmapnii, knots_zooms=[24., 24., 4.], njobs=self.inputs.njobs) bspobj2.fit() smoothed2 = bspobj2.get_smoothed().get_data() final = smoothed1.get_data().copy() final[..., errorslice[0]:errorslice[-1]] += smoothed2 else: final = smoothed1.get_data() nb.Nifti1Image(final, datanii.affine, datanii.header).to_filename( self._results['out_file']) return runtime