def median(in_files): """Computes an average of the median of each realigned timeseries Parameters ---------- in_files: one or more realigned Nifti 4D time series Returns ------- out_file: a 3D Nifti file """ import nibabel as nb import numpy as np import os from nipype.utils.filemanip import filename_to_list from nipype.utils.filemanip import split_filename average = None for idx, filename in enumerate(filename_to_list(in_files)): img = nb.load(filename) data = np.median(img.get_data(), axis=3) if average is None: average = data else: average = average + data median_img = nb.Nifti1Image(average/float(idx + 1), img.get_affine(), img.get_header()) #filename = os.path.join(os.getcwd(), 'median.nii.gz') #median_img.to_filename(filename) _, base, _ = split_filename(filename_to_list(in_files)[0]) nb.save(median_img, base + "_median.nii.gz") return os.path.abspath(base + "_median.nii.gz") return filename
def _list_outputs(self): outputs = self._outputs().get() jobtype = self.inputs.jobtype if jobtype.startswith("est"): outputs["normalization_parameters"] = [] for imgf in filename_to_list(self.inputs.source): outputs["normalization_parameters"].append(fname_presuffix(imgf, suffix="_sn.mat", use_ext=False)) outputs["normalization_parameters"] = list_to_filename(outputs["normalization_parameters"]) if self.inputs.jobtype == "estimate": if isdefined(self.inputs.apply_to_files): outputs["normalized_files"] = self.inputs.apply_to_files outputs["normalized_source"] = self.inputs.source elif "write" in self.inputs.jobtype: outputs["normalized_files"] = [] if isdefined(self.inputs.apply_to_files): for imgf in filename_to_list(self.inputs.apply_to_files): outputs["normalized_files"].append(fname_presuffix(imgf, prefix="w")) if isdefined(self.inputs.source): outputs["normalized_source"] = [] for imgf in filename_to_list(self.inputs.source): outputs["normalized_source"].append(fname_presuffix(imgf, prefix="w")) return outputs
def __init__(self, input_names, output_names, function=None, **inputs): """ Parameters ---------- input_names: single str or list names corresponding to function inputs output_names: single str or list names corresponding to function outputs. has to match the number of outputs """ super(Function, self).__init__(**inputs) if function: if hasattr(function, '__call__'): try: self.inputs.function_str = getsource(function) except IOError: raise Exception('Interface Function does not accept ' \ 'function objects defined interactively in a python session') elif isinstance(function, str): self.inputs.function_str = function else: raise Exception('Unknown type of function') self.inputs.on_trait_change(self._set_function_string, 'function_str') self._input_names = filename_to_list(input_names) self._output_names = filename_to_list(output_names) add_traits(self.inputs, [name for name in self._input_names]) self._out = {} for name in self._output_names: self._out[name] = None
def build_filter1(motion_params, comp_norm, outliers): """Builds a regressor set comprisong motion parameters, composite norm and outliers The outliers are added as a single time point column for each outlier Parameters ---------- motion_params: a text file containing motion parameters and its derivatives comp_norm: a text file containing the composite norm outliers: a text file containing 0-based outlier indices Returns ------- components_file: a text file containing all the regressors """ out_files = [] for idx, filename in enumerate(filename_to_list(motion_params)): params = np.genfromtxt(filename) norm_val = np.genfromtxt(filename_to_list(comp_norm)[idx]) out_params = np.hstack((params, norm_val[:, None])) try: outlier_val = np.genfromtxt(filename_to_list(outliers)[idx]) except IOError: outlier_val = np.empty((0)) for index in np.atleast_1d(outlier_val): outlier_vector = np.zeros((out_params.shape[0], 1)) outlier_vector[index] = 1 out_params = np.hstack((out_params, outlier_vector)) filename = os.path.join(os.getcwd(), "filter_regressor%02d.txt" % idx) np.savetxt(filename, out_params, fmt="%.10f") out_files.append(filename) return out_files
def _list_outputs(self): outputs = self._outputs().get() jobtype = self.inputs.jobtype if jobtype.startswith('est'): outputs['normalization_parameters'] = [] for imgf in filename_to_list(self.inputs.source): outputs['normalization_parameters'].append(fname_presuffix(imgf, suffix='_sn.mat', use_ext=False)) outputs['normalization_parameters'] = list_to_filename(outputs['normalization_parameters']) if self.inputs.jobtype == "estimate": if isdefined(self.inputs.apply_to_files): outputs['normalized_files'] = self.inputs.apply_to_files outputs['normalized_source'] = self.inputs.source elif 'write' in self.inputs.jobtype: outputs['normalized_files'] = [] if isdefined(self.inputs.apply_to_files): for imgf in filename_to_list(self.inputs.apply_to_files): outputs['normalized_files'].append(fname_presuffix(imgf, prefix='w')) if isdefined(self.inputs.source): outputs['normalized_source'] = [] for imgf in filename_to_list(self.inputs.source): outputs['normalized_source'].append(fname_presuffix(imgf, prefix='w')) return outputs
def median(in_files): """Computes an average of the median of each realigned timeseries Parameters ---------- in_files: one or more realigned Nifti 4D time series Returns ------- out_file: a 3D Nifti file """ import nibabel as nb import numpy as np import os from nipype.utils.filemanip import filename_to_list from nipype.utils.filemanip import split_filename average = None for idx, filename in enumerate(filename_to_list(in_files)): img = nb.load(filename) data = np.median(img.get_data(), axis=3) if average is None: average = data else: average = average + data median_img = nb.Nifti1Image(average / float(idx + 1), img.get_affine(), img.get_header()) # filename = os.path.join(os.getcwd(), 'median.nii.gz') # median_img.to_filename(filename) _, base, _ = split_filename(filename_to_list(in_files)[0]) nb.save(median_img, base + "_median.nii.gz") return os.path.abspath(base + "_median.nii.gz") return filename
def __init__(self, input_names, output_names, function=None, **inputs): """ Parameters ---------- input_names: single str or list names corresponding to function inputs output_names: single str or list names corresponding to function outputs. has to match the number of outputs """ super(Function, self).__init__(**inputs) if function: if hasattr(function, '__call__'): try: self.inputs.function_str = getsource(function) except IOError: raise Exception('Interface Function does not accept ' \ 'function objects defined interactively in a python session') elif isinstance(function, str): self.inputs.function_str = dumps(function) else: raise Exception('Unknown type of function') self.inputs.on_trait_change(self._set_function_string, 'function_str') self._input_names = filename_to_list(input_names) self._output_names = filename_to_list(output_names) add_traits(self.inputs, [name for name in self._input_names]) self._out = {} for name in self._output_names: self._out[name] = None
def _list_outputs(self): outputs = self._outputs().get() if isdefined(self.inputs.in_files): outputs["realignment_parameters"] = [] for imgf in self.inputs.in_files: if isinstance(imgf, list): tmp_imgf = imgf[0] else: tmp_imgf = imgf outputs["realignment_parameters"].append( fname_presuffix(tmp_imgf, prefix="rp_", suffix=".txt", use_ext=False) ) if not isinstance(imgf, list) and func_is_3d(imgf): break if self.inputs.jobtype == "write" or self.inputs.jobtype == "estwrite": if isinstance(self.inputs.in_files[0], list): first_image = self.inputs.in_files[0][0] else: first_image = self.inputs.in_files[0] outputs["mean_image"] = fname_presuffix(first_image, prefix="mean") outputs["realigned_files"] = [] for imgf in filename_to_list(self.inputs.in_files): realigned_run = [] if isinstance(imgf, list): for inner_imgf in filename_to_list(imgf): realigned_run.append(fname_presuffix(inner_imgf, prefix="r")) else: realigned_run = fname_presuffix(imgf, prefix="r") outputs["realigned_files"].append(realigned_run) return outputs
def _list_outputs(self): outputs = self._outputs().get() if isdefined(self.inputs.in_files): outputs['realignment_parameters'] = [] for imgf in self.inputs.in_files: if isinstance(imgf,list): tmp_imgf = imgf[0] else: tmp_imgf = imgf outputs['realignment_parameters'].append(fname_presuffix(tmp_imgf, prefix='rp_', suffix='.txt', use_ext=False)) if not isinstance(imgf,list) and func_is_3d(imgf): break; #if self.inputs.jobtype == "write" or self.inputs.jobtype == "estwrite": if isinstance(self.inputs.in_files[0], list): first_image = self.inputs.in_files[0][0] else: first_image = self.inputs.in_files[0] outputs['mean_image'] = fname_presuffix(first_image, prefix='meanu') outputs['realigned_files'] = [] # get prefix for new files, or default 'u' file_prefix = self.inputs.write_prefix or 'u' for imgf in filename_to_list(self.inputs.in_files): realigned_run = [] if isinstance(imgf,list): for inner_imgf in filename_to_list(imgf): realigned_run.append(fname_presuffix(inner_imgf, prefix=file_prefix)) else: realigned_run = fname_presuffix(imgf, prefix=file_prefix) outputs['realigned_files'].append(realigned_run) return outputs
def build_filter1(motion_params, comp_norm, outliers): """Builds a regressor set comparison motion parameters, composite norm and outliers The outliers are added as a single time point column for each outlier Parameters ---------- motion_params: a text file containing motion parameters and its derivatives comp_norm: a text file containing the composite norm outliers: a text file containing 0-based outlier indices Returns ------- components_file: a text file containing all the regressors """ out_files = [] for idx, filename in enumerate(filename_to_list(motion_params)): params = np.genfromtxt(filename) norm_val = np.genfromtxt(filename_to_list(comp_norm)[idx]) out_params = np.hstack((params, norm_val[:, None])) try: outlier_val = np.genfromtxt(filename_to_list(outliers)[idx]) except IOError: outlier_val = np.empty((0)) for index in np.atleast_1d(outlier_val): outlier_vector = np.zeros((out_params.shape[0], 1)) outlier_vector[index] = 1 out_params = np.hstack((out_params, outlier_vector)) filename = os.path.join(os.getcwd(), "filter_regressor%02d.txt" % idx) np.savetxt(filename, out_params, fmt="%.10f") out_files.append(filename) return out_files
def detect_inputs(t1w_list, t2w_list=None, flair_list=None, hires_enabled=True): t1w_list = filename_to_list(t1w_list) t2w_list = filename_to_list(t2w_list) if t2w_list is not None else [] flair_list = filename_to_list(flair_list) if flair_list is not None else [] t1w_ref = nb.load(t1w_list[0]) # Use high resolution preprocessing if voxel size < 1.0mm # Tolerance of 0.05mm requires that rounds down to 0.9mm or lower hires = hires_enabled and max(t1w_ref.header.get_zooms()) < 1 - 0.05 t2w = None if t2w_list and max(nb.load(t2w_list[0]).header.get_zooms()) < 1.2: t2w = t2w_list[0] # Prefer T2w to FLAIR if both present and T2w satisfies flair = None if flair_list and not t2w and max( nb.load(flair_list[0]).header.get_zooms()) < 1.2: flair = flair_list[0] # https://surfer.nmr.mgh.harvard.edu/fswiki/SubmillimeterRecon mris_inflate = '-n 50' if hires else None return (t2w, flair, hires, mris_inflate)
def _list_outputs(self): outputs = self._outputs().get() jobtype = self.inputs.jobtype if jobtype.startswith('est'): outputs['normalization_parameters'] = [] for imgf in filename_to_list(self.inputs.source): outputs['normalization_parameters'].append(fname_presuffix(imgf, suffix='_sn.mat', use_ext=False)) outputs['normalization_parameters'] = list_to_filename(outputs['normalization_parameters']) if self.inputs.jobtype == "estimate": if isdefined(self.inputs.apply_to_files): outputs['normalized_files'] = self.inputs.apply_to_files outputs['normalized_source'] = self.inputs.source elif 'write' in self.inputs.jobtype: outputs['normalized_files'] = [] if isdefined(self.inputs.apply_to_files): filelist = filename_to_list(self.inputs.apply_to_files) for f in filelist: if isinstance(f, list): run = [fname_presuffix(in_f, prefix=self.inputs.out_prefix) for in_f in f] else: run = [fname_presuffix(f, prefix=self.inputs.out_prefix)] outputs['normalized_files'].extend(run) if isdefined(self.inputs.source): outputs['normalized_source'] = fname_presuffix(self.inputs.source, prefix=self.inputs.out_prefix) return outputs
def _run_interface(self, runtime): """Execute this module. """ funcfilelist = filename_to_list(self.inputs.realigned_files) motparamlist = filename_to_list(self.inputs.realignment_parameters) for i, imgf in enumerate(funcfilelist): self._detect_outliers_core(imgf, motparamlist[i], i, os.getcwd()) return runtime
def _run_interface(self, runtime): """Execute this module. """ funcfilelist = filename_to_list(self.inputs.realigned_files) motparamlist = filename_to_list(self.inputs.realignment_parameters) for i,imgf in enumerate(funcfilelist): self._detect_outliers_core(imgf ,motparamlist[i], i, os.getcwd()) return runtime
def test_filename_to_list(): x = filename_to_list('foo.nii') yield assert_equal, x, ['foo.nii'] x = filename_to_list(['foo.nii']) yield assert_equal, x, ['foo.nii'] x = filename_to_list(('foo', 'bar')) yield assert_equal, x, ['foo', 'bar'] x = filename_to_list(12.34) yield assert_equal, x, None
def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt == 'target' or opt == 'source': return scans_for_fnames(filename_to_list(val), keep4d=True) if opt == 'apply_to_files': return scans_for_fnames(filename_to_list(val)) return val
def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt == 'phase' or opt == 'magnitude' or opt == 'anat': return scans_for_fname(filename_to_list(val)) if opt == 'epi' or opt == 'magnitude': return scans_for_fname(filename_to_list(val)) return super(FieldMap, self)._format_arg(opt, spec, val)
def clean_working_directory(outputs, cwd, inputs, needed_outputs, config, files2keep=None, dirs2keep=None): """Removes all files not needed for further analysis from the directory """ if not outputs: return outputs_to_keep = outputs.get().keys() if needed_outputs and \ str2bool(config['execution']['remove_unnecessary_outputs']): outputs_to_keep = needed_outputs # build a list of needed files output_files = [] outputdict = outputs.get() for output in outputs_to_keep: output_files.extend(walk_outputs(outputdict[output])) needed_files = [path for path, type in output_files if type == 'f'] if str2bool(config['execution']['keep_inputs']): input_files = [] inputdict = inputs.get() input_files.extend(walk_outputs(inputdict)) needed_files += [path for path, type in input_files if type == 'f'] for extra in ['_0x*.json', 'provenance.xml', 'pyscript*.m', 'command.txt', 'result*.pklz', '_inputs.pklz', '_node.pklz']: needed_files.extend(glob(os.path.join(cwd, extra))) if files2keep: needed_files.extend(filename_to_list(files2keep)) needed_dirs = [path for path, type in output_files if type == 'd'] if dirs2keep: needed_dirs.extend(filename_to_list(dirs2keep)) for extra in ['_nipype', '_report']: needed_dirs.extend(glob(os.path.join(cwd, extra))) logger.debug('Needed files: %s' % (';'.join(needed_files))) logger.debug('Needed dirs: %s' % (';'.join(needed_dirs))) files2remove = [] if str2bool(config['execution']['remove_unnecessary_outputs']): for f in walk_files(cwd): if f not in needed_files: if len(needed_dirs) == 0: files2remove.append(f) elif not any([f.startswith(dirname) for dirname in needed_dirs]): files2remove.append(f) else: if not str2bool(config['execution']['keep_inputs']): input_files = [] inputdict = inputs.get() input_files.extend(walk_outputs(inputdict)) input_files = [path for path, type in input_files if type == 'f'] for f in walk_files(cwd): if f in input_files and f not in needed_files: files2remove.append(f) logger.debug('Removing files: %s' % (';'.join(files2remove))) for f in files2remove: os.remove(f) for key in outputs.copyable_trait_names(): if key not in outputs_to_keep: setattr(outputs, key, Undefined) return outputs
def create_correlation_matrix(infiles, roi, out_type, package): import os import numpy as np import scipy.io as sio import nibabel as nb from nipype.utils.filemanip import split_filename, filename_to_list for idx, fname in enumerate(filename_to_list(infiles)): data = np.squeeze(nb.load(fname).get_data()) if idx == 0: timeseries = data else: timeseries = np.vstack((timeseries, data)) roi_data = np.genfromtxt(roi) if not len(roi_data.shape) == 2: roi_data = roi_data[:, None] corrmat = np.zeros((roi_data.shape[1], timeseries.shape[0])) print timeseries.shape for i in xrange(roi_data.shape[1]): for j in xrange(timeseries.shape[0]): r = np.corrcoef(timeseries[j, :], roi_data[:, i])[0][1] corrmat[i, j] = np.sqrt(timeseries.shape[1] - 3) * 0.5 * np.log( (1 + r) / (1 - r)) #corrmat = np.corrcoef(timeseries,roi_data.T) print corrmat.shape _, name, _ = split_filename(filename_to_list(infiles)[0]) if len(filename_to_list(infiles)) > 1: name = 'combined_' + name if 'mat' in out_type: matfile = os.path.abspath(name + '.mat') sio.savemat(matfile, {'corrmat': corrmat}) output = matfile elif 'hdf5' in out_type: hdf5file = os.path.abspath(name + '.hf5') if package == 'h5py': import h5py f = h5py.File(hdf5file, 'w') f.create_dataset('corrmat', data=corrmat, compression=5) f.close() else: from tables import openFile, Float64Atom, Filters h5file = openFile(hdf5file, 'w') arr = h5file.createCArray(h5file.root, 'corrmat', Float64Atom(), corrmat.shape, filters=Filters(complevel=5)) arr[:] = corrmat h5file.close() output = hdf5file else: raise Exception('Unknown output type') return output
def create_correlation_matrix(infiles, roi, out_type, package): import os import numpy as np import scipy.io as sio import nibabel as nb from nipype.utils.filemanip import split_filename, filename_to_list for idx, fname in enumerate(filename_to_list(infiles)): data = np.squeeze(nb.load(fname).get_data()) if idx == 0: timeseries = data else: timeseries = np.vstack((timeseries, data)) roi_data = np.genfromtxt(roi) if not len(roi_data.shape) == 2: roi_data = roi_data[:, None] corrmat = np.zeros((roi_data.shape[1], timeseries.shape[0])) print timeseries.shape for i in xrange(roi_data.shape[1]): for j in xrange(timeseries.shape[0]): r = np.corrcoef(timeseries[j, :], roi_data[:, i])[0][1] corrmat[i, j] = np.sqrt(timeseries.shape[1] - 3) * 0.5 * np.log((1 + r) / (1 - r)) # corrmat = np.corrcoef(timeseries,roi_data.T) print corrmat.shape _, name, _ = split_filename(filename_to_list(infiles)[0]) if len(filename_to_list(infiles)) > 1: name = "combined_" + name if "mat" in out_type: matfile = os.path.abspath(name + ".mat") sio.savemat(matfile, {"corrmat": corrmat}) output = matfile elif "hdf5" in out_type: hdf5file = os.path.abspath(name + ".hf5") if package == "h5py": import h5py f = h5py.File(hdf5file, "w") f.create_dataset("corrmat", data=corrmat, compression=5) f.close() else: from tables import openFile, Float64Atom, Filters h5file = openFile(hdf5file, "w") arr = h5file.createCArray( h5file.root, "corrmat", Float64Atom(), corrmat.shape, filters=Filters(complevel=5) ) arr[:] = corrmat h5file.close() output = hdf5file else: raise Exception("Unknown output type") return output
def build_filter1(motion_params, outliers, comp_norm=None, detrend_poly=None): """From https://github.com/nipy/nipype/blob/master/examples/ rsfmri_vol_surface_preprocessing_nipy.py#L261 Builds a regressor set comprisong motion parameters, composite norm and outliers. The outliers are added as a single time point column for each outlier Parameters ---------- motion_params: a text file containing motion parameters and its derivatives comp_norm: a text file containing the composite norm outliers: a text file containing 0-based outlier indices detrend_poly: number of polynomials to add to detrend Returns ------- components_file: a text file containing all the regressors """ from nipype.utils.filemanip import filename_to_list import numpy as np import os from scipy.special import legendre out_files = [] for idx, filename in enumerate(filename_to_list(motion_params)): params = np.genfromtxt(filename) if comp_norm: norm_val = np.genfromtxt(filename_to_list(comp_norm)[idx]) out_params = np.hstack((params, norm_val[:, None])) else: out_params = params try: outlier_val = np.genfromtxt(filename_to_list(outliers)[idx]) except IOError: outlier_val = np.empty((0)) for index in np.atleast_1d(outlier_val): outlier_vector = np.zeros((out_params.shape[0], 1)) outlier_vector[index] = 1 out_params = np.hstack((out_params, outlier_vector)) if detrend_poly: timepoints = out_params.shape[0] X = np.ones((timepoints, 1)) for i in range(detrend_poly): X = np.hstack( (X, legendre(i + 1)(np.linspace(-1, 1, timepoints))[:, None])) out_params = np.hstack((out_params, X)) filename = os.path.join( os.getcwd(), "mcart_regressor.txt") #"filter_regressor%02d.txt" % idx) np.savetxt(filename, out_params, fmt="%.10f") out_files.append(filename) return out_files
def _generate_design(self): infolist = self.inputs.subject_info if self.inputs.concatenate_runs: infolist,nscans = self._concatenate_info(infolist) functional_runs = [filename_to_list(self.inputs.functional_runs)] else: functional_runs = filename_to_list(self.inputs.functional_runs) realignment_parameters = [] if isdefined(self.inputs.realignment_parameters): rpfiles = filename_to_list(self.inputs.realignment_parameters) realignment_parameters.insert(0,np.loadtxt(rpfiles[0])) for rpf in rpfiles[1:]: mc = np.loadtxt(rpf) if self.inputs.concatenate_runs: realignment_parameters[0] = np.concatenate((realignment_parameters[0],mc)) else: realignment_parameters.insert(len(realignment_parameters),mc) outliers = [] if isdefined(self.inputs.outlier_files): outfiles = filename_to_list(self.inputs.outlier_files) try: outindices = np.loadtxt(outfiles[0],dtype=int) if outindices.size == 1: outliers.insert(0,[outindices.tolist()]) else: outliers.insert(0,outindices.tolist()) except IOError: outliers.insert(0,[]) for i,rpf in enumerate(outfiles[1:]): try: out = np.loadtxt(rpf,dtype=int) except IOError: out = np.array([]) if self.inputs.concatenate_runs: if out.size>0: if out.size == 1: outliers[0].extend([(np.array(out)+sum(nscans[0:(i+1)])).tolist()]) else: outliers[0].extend((np.array(out)+sum(nscans[0:(i+1)])).tolist()) else: if out.size == 1: outliers.insert(len(outliers),[out.tolist()]) else: outliers.insert(len(outliers),out.tolist()) if self.inputs.is_sparse: infolist = self._generate_clustered_design(infolist) sessinfo = self._generate_standard_design(infolist, functional_runs=functional_runs, realignment_parameters=realignment_parameters, outliers=outliers) np.savez(self._get_outfilename(),session_info=sessinfo)
def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt == 'in_files': return scans_for_fnames(filename_to_list(val)) if opt == 'target': return scans_for_fname(filename_to_list(val)) if opt == 'deformation': return np.array([list_to_filename(val)], dtype=object) if opt == 'deformation_field': return np.array([list_to_filename(val)], dtype=object) return val
def _run_interface(self, execute=True, cwd=None): old_cwd = os.getcwd() if not cwd: cwd = self._output_directory() os.chdir(cwd) nitems = len(filename_to_list(getattr(self.inputs, self.iterfield[0]))) newnodes = [] nodenames = [] for i in range(nitems): nodenames.insert(i, '_' + self.name+str(i)) newnodes.insert(i, Node(deepcopy(self._interface), name=nodenames[i])) newnodes[i]._interface.inputs.set(**deepcopy(self._interface.inputs.get())) for field in self.iterfield: fieldvals = filename_to_list(getattr(self.inputs, field)) logger.debug('setting input %d %s %s'%(i, field, fieldvals[i])) setattr(newnodes[i].inputs, field, fieldvals[i]) workflowname = 'mapflow' iterflow = Workflow(name=workflowname) iterflow.base_dir = cwd iterflow.config = self.config iterflow.add_nodes(newnodes) iterflow.run(inseries=True) self._result = InterfaceResult(interface=[], runtime=[], outputs=self.outputs) for i in range(nitems): node = iterflow.get_exec_node('.'.join((workflowname, nodenames[i]))) runtime = Bunch(returncode = 0, environ = deepcopy(os.environ.data), hostname = gethostname()) self._result.runtime.insert(i, runtime) if node.result and hasattr(node.result, 'runtime'): self._result.runtime[i] = node.result.runtime if node.result.runtime.returncode != 0: raise Exception('iternode %s:%d did not run'%(node._id, i)) self._result.interface.insert(i, node.result.interface) for key, _ in self.outputs.items(): values = [] for i in range(nitems): node = iterflow.get_exec_node('.'.join((workflowname, nodenames[i]))) if node.result.outputs: values.insert(i, node.result.outputs.get()[key]) else: values.insert(i, None) if any([val != Undefined for val in values]) and self._result.outputs: #logger.debug('setting key %s with values %s' %(key, str(values))) setattr(self._result.outputs, key, values) #else: # logger.debug('no values for key %s' %key) os.chdir(old_cwd)
def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt == "target" or (opt == "source" and self.inputs.jobtype != "write"): return scans_for_fnames(filename_to_list(val), keep4d=True) if opt == "apply_to_files": return scans_for_fnames(filename_to_list(val)) if opt == "source" and self.inputs.jobtype == "write": if isdefined(self.inputs.apply_to_files): return scans_for_fnames(val + self.inputs.apply_to_files) else: return scans_for_fnames(val) return val
def build_filter1(motion_params, outliers, comp_norm=None, detrend_poly=None): """From https://github.com/nipy/nipype/blob/master/examples/ rsfmri_vol_surface_preprocessing_nipy.py#L261 Builds a regressor set comprisong motion parameters, composite norm and outliers. The outliers are added as a single time point column for each outlier Parameters ---------- motion_params: a text file containing motion parameters and its derivatives comp_norm: a text file containing the composite norm outliers: a text file containing 0-based outlier indices detrend_poly: number of polynomials to add to detrend Returns ------- components_file: a text file containing all the regressors """ from nipype.utils.filemanip import filename_to_list import numpy as np import os from scipy.special import legendre out_files = [] for idx, filename in enumerate(filename_to_list(motion_params)): params = np.genfromtxt(filename) if comp_norm: norm_val = np.genfromtxt(filename_to_list(comp_norm)[idx]) out_params = np.hstack((params, norm_val[:, None])) else: out_params = params try: outlier_val = np.genfromtxt(filename_to_list(outliers)[idx]) except IOError: outlier_val = np.empty((0)) for index in np.atleast_1d(outlier_val): outlier_vector = np.zeros((out_params.shape[0], 1)) outlier_vector[index] = 1 out_params = np.hstack((out_params, outlier_vector)) if detrend_poly: timepoints = out_params.shape[0] X = np.ones((timepoints, 1)) for i in range(detrend_poly): X = np.hstack((X, legendre( i + 1)(np.linspace(-1, 1, timepoints))[:, None])) out_params = np.hstack((out_params, X)) filename = os.path.join(os.getcwd(), "mcart_regressor.txt") #"filter_regressor%02d.txt" % idx) np.savetxt(filename, out_params, fmt="%.10f") out_files.append(filename) return out_files
def _list_outputs(self): """Execute this module. """ outdir = self.inputs.base_directory if not isdefined(outdir): outdir = '.' outdir = os.path.abspath(outdir) if isdefined(self.inputs.container): outdir = os.path.join(outdir, self.inputs.container) if not os.path.exists(outdir): os.makedirs(outdir) for key,files in self.inputs._outputs.items(): iflogger.debug("key: %s files: %s"%(key, str(files))) files = filename_to_list(files) outfiles = [] tempoutdir = outdir for d in key.split('.'): if d[0] == '@': continue tempoutdir = os.path.join(tempoutdir,d) # flattening list if isinstance(files, list): if isinstance(files[0], list): files = [item for sublist in files for item in sublist] for src in filename_to_list(files): src = os.path.abspath(src) if os.path.isfile(src): dst = self._get_dst(src) dst = os.path.join(tempoutdir, dst) dst = self._substitute(dst) path,_ = os.path.split(dst) if not os.path.exists(path): os.makedirs(path) iflogger.debug("copyfile: %s %s"%(src, dst)) copyfile(src, dst, copy=True) elif os.path.isdir(src): dst = self._get_dst(os.path.join(src,'')) dst = os.path.join(tempoutdir, dst) dst = self._substitute(dst) path,_ = os.path.split(dst) if not os.path.exists(path): os.makedirs(path) if os.path.exists(dst): iflogger.debug("removing: %s"%dst) shutil.rmtree(dst) iflogger.debug("copydir: %s %s"%(src, dst)) shutil.copytree(src, dst) return None
def _list_outputs(self): outputs = self._outputs().get() outputs["timecorrected_files"] = [] filelist = filename_to_list(self.inputs.in_files) for f in filelist: run = [] if isinstance(f, list): for inner_f in filename_to_list(f): run.append(fname_presuffix(inner_f, prefix="a")) else: realigned_run = fname_presuffix(f, prefix="a") outputs["timecorrected_files"].append(realigned_run) return outputs
def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt == 'target' or (opt == 'source' and self.inputs.jobtype != "write"): return scans_for_fnames(filename_to_list(val), keep4d=True) if opt == 'apply_to_files': return np.array(filename_to_list(val), dtype=object) if opt == 'source' and self.inputs.jobtype == "write": if isdefined(self.inputs.apply_to_files): return scans_for_fnames(val+self.inputs.apply_to_files) else: return scans_for_fnames(val) return val
def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt == "template": return scans_for_fname(filename_to_list(val)) if opt == "source": return scans_for_fname(filename_to_list(val)) if opt == "apply_to_files": return scans_for_fnames(filename_to_list(val)) if opt == "parameter_file": return np.array([list_to_filename(val)], dtype=object) if opt in ["write_wrap"]: if len(val) != 3: raise ValueError("%s must have 3 elements" % opt) return val
def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm """ if opt == 'template': return scans_for_fname(filename_to_list(val)) if opt == 'source': return scans_for_fname(filename_to_list(val)) if opt == 'apply_to_files': return scans_for_fnames(filename_to_list(val)) if opt == 'parameter_file': return np.array([list_to_filename(val)], dtype=object) if opt in ['write_wrap']: if len(val) != 3: raise ValueError('%s must have 3 elements' % opt) return super(Normalize, self)._format_arg(opt, spec, val)
def create_regressors(motion_params, comp_norm, outliers, detrend_poly=None): """Builds a regressor set comprising motion parameters, composite norm and outliers. The outliers are added as a single time point column for each outlier Parameters ---------- motion_params: a text file containing motion parameters and its derivatives comp_norm: a text file containing the composite norm outliers: a text file containing 0-based outlier indices detrend_poly: number of polynomials to add to detrend Returns ------- components_file: a text file containing all the regressors """ import os import numpy as np from nipype.utils.filemanip import filename_to_list from scipy.special import legendre out_files = [] for idx, filename in enumerate(filename_to_list(motion_params)): params = np.genfromtxt(filename) norm_val = np.genfromtxt(filename_to_list(comp_norm)[idx]) out_params = np.hstack((params, norm_val[:, None])) try: outlier_indices = np.genfromtxt(filename_to_list(outliers)[idx], dtype=int) except IOError: outlier_indices = np.empty((0)) for index in np.atleast_1d(outlier_indices): outlier_vector = np.zeros((out_params.shape[0], 1)) outlier_vector[index] = 1 out_params = np.hstack((out_params, outlier_vector)) if detrend_poly: timepoints = out_params.shape[0] X = np.empty((timepoints, 0)) for i in range(detrend_poly): X = np.hstack( (X, legendre(i + 1)(np.linspace(-1, 1, timepoints))[:, None])) out_params = np.hstack((out_params, X)) filename = os.path.join(os.getcwd(), "filter_regressor%02d.txt" % idx) np.savetxt(filename, out_params, fmt=b"%.10f") out_files.append(filename) return out_files
def checkT1s(T1_files, cw256=False): """Verifying size of inputs and setting workflow parameters""" import sys import nibabel as nib from nipype.utils.filemanip import filename_to_list T1_files = filename_to_list(T1_files) if len(T1_files) == 0: print("ERROR: No T1's Given") sys.exit(-1) shape = nib.load(T1_files[0]).shape for t1 in T1_files[1:]: if nib.load(t1).shape != shape: print("ERROR: T1s not the same size. Cannot process {0} and {1} " "together".format(T1_files[0], t1)) sys.exit(-1) origvol_names = ["{0:03d}.mgz".format(i + 1) for i in range(len(T1_files))] # check if cw256 is set to crop the images if size is larger than 256 if not cw256 and any(dim > 256 for dim in shape): print("Setting MRI Convert to crop images to 256 FOV") cw256 = True resample_type = 'cubic' if len(T1_files) > 1 else 'interpolate' return T1_files, cw256, resample_type, origvol_names
def analyze_pair_image_files(outdir, filelist, shape): for f in filename_to_list(filelist): hdr = nb.Nifti1Header() hdr.set_data_shape(shape) img = np.random.random(shape) analyze = nb.AnalyzeImage(img, np.eye(4), hdr) analyze.to_filename(os.path.join(outdir, f))
def motion_regressors(motion_params, order=0, derivatives=1): """Compute motion regressors upto given order and derivative motion + d(motion)/dt + d2(motion)/dt2 (linear + quadratic) """ from nipype.utils.filemanip import filename_to_list import numpy as np import os out_files = [] for idx, filename in enumerate(filename_to_list(motion_params)): params = np.genfromtxt(filename) out_params = params for d in range(1, derivatives + 1): cparams = np.vstack((np.repeat(params[0, :][None, :], d, axis=0), params)) out_params = np.hstack((out_params, np.diff(cparams, d, axis=0))) out_params2 = out_params for i in range(2, order + 1): out_params2 = np.hstack((out_params2, np.power(out_params, i))) filename = os.path.join(os.getcwd(), "motion_regressor_der%d_ord%d.txt" % (derivatives, order)) np.savetxt(filename, out_params2, fmt="%.10f") out_files.append(filename) return out_files
def fix_multi_source_name(in_files): """ Make up a generic source name when there are multiple >>> fix_multi_source_name([ ... '/path/to/sub-045_ses-test_T1w.nii.gz', ... '/path/to/sub-045_ses-retest_T1w.nii.gz']) '/path/to/sub-045_T1w.nii.gz' """ import re from pathlib import Path from nipype.utils.filemanip import filename_to_list if not isinstance(in_files, (tuple, list)): return in_files elif len(in_files) == 1: return in_files[0] p = Path(filename_to_list(in_files)[0]) # subject_label = p.name.split("_", 1)[0].split("-")[1] try: subj = re.search(r'(?<=^sub-)[a-zA-Z0-9]*', p.name).group() suffix = re.search(r'(?<=_)\w+(?=\.)', p.name).group() except AttributeError: raise AttributeError("Could not extract BIDS information") return str(p.parent / f"sub-{subj}_{suffix}.nii.gz")
def _list_outputs(self): outputs = self._outputs().get() outputs['outlier_files'] = [] outputs['intensity_files'] = [] outputs['statistic_files'] = [] if isdefined(self.inputs.use_norm) and self.inputs.use_norm: outputs['norm_files'] = [] if isdefined(self.inputs.save_plot) and self.inputs.save_plot: outputs['plot_files'] = [] for i, f in enumerate(filename_to_list(self.inputs.realigned_files)): outlierfile, intensityfile, statsfile, normfile, plotfile = self._get_output_filenames(f, os.getcwd()) outputs['outlier_files'].insert(i, outlierfile) outputs['intensity_files'].insert(i, intensityfile) outputs['statistic_files'].insert(i, statsfile) if isdefined(self.inputs.use_norm) and self.inputs.use_norm: outputs['norm_files'].insert(i, normfile) if isdefined(self.inputs.save_plot) and self.inputs.save_plot: outputs['plot_files'].insert(i, plotfile) ''' outputs['outlier_files'] = list_to_filename(outputs['outlier_files']) outputs['intensity_files'] = list_to_filename(outputs['intensity_files']) outputs['statistic_files'] = list_to_filename(outputs['statistic_files']) if isdefined(self.inputs.use_norm) and self.inputs.use_norm: outputs['norm_files'] = list_to_filename(outputs['norm_files']) if isdefined(self.inputs.save_plot) and self.inputs.save_plot: outputs['plot_files'] = list_to_filename(outputs['plot_files']) ''' return outputs
def _list_outputs(self): outputs = self._outputs().get() out = [] if self._numinputs == 0: values = getattr(self.inputs, 'in_lists') if not isdefined(values): return outputs else: getval = lambda idx: getattr(self.inputs, 'in%d' % (idx + 1)) # @IgnorePep8 values = [getval(idx) for idx in range(self._numinputs) if isdefined(getval(idx))] if self.inputs.axis == 'vstack': for value in values: if isinstance(value, list) and not self.inputs.no_flatten: out.extend(value) else: out.append(value) else: lists = [filename_to_list(val) for val in values] out = [[val[i] for val in lists] for i in range(len(lists[0]))] if out: outputs['out'] = out return outputs
def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm""" if opt == "deformation_field": return np.array([list_to_filename(val)], dtype=object) if opt == "in_files": return np.array(filename_to_list(val), dtype=object) return val
def bandpass_filter(files, lowpass_freq, highpass_freq, fs): """Bandpass filter the input files Parameters ---------- files: list of 4d nifti files lowpass_freq: cutoff frequency for the low pass filter (in Hz) highpass_freq: cutoff frequency for the high pass filter (in Hz) fs: sampling rate (in Hz) """ out_files = [] for filename in filename_to_list(files): path, name, ext = split_filename(filename) out_file = os.path.join(os.getcwd(), name + '_bp' + ext) img = nb.load(filename) timepoints = img.shape[-1] F = np.zeros((timepoints)) lowidx = timepoints / 2 + 1 if lowpass_freq > 0: lowidx = np.round(float(lowpass_freq) / fs * timepoints) highidx = 0 if highpass_freq > 0: highidx = np.round(float(highpass_freq) / fs * timepoints) F[highidx:lowidx] = 1 F = ((F + F[::-1]) > 0).astype(int) data = img.get_data() if np.all(F == 1): filtered_data = data else: filtered_data = np.real(np.fft.ifftn(np.fft.fftn(data) * F)) img_out = nb.Nifti1Image(filtered_data, img.get_affine(), img.get_header()) img_out.to_filename(out_file) out_files.append(out_file) return list_to_filename(out_files)
def _run_and_test(opts, output_base): outputs = fsl.FAST(**opts)._list_outputs() for output in outputs.values(): filenames = filename_to_list(output) if filenames is not None: for filename in filenames: assert filename[:len(output_base)] == output_base
def motion_regressors(motion_params, order=0, derivatives=1): """From https://github.com/nipy/nipype/blob/master/examples/ rsfmri_vol_surface_preprocessing_nipy.py#L261 Compute motion regressors upto given order and derivative motion + d(motion)/dt + d2(motion)/dt2 (linear + quadratic) """ from nipype.utils.filemanip import filename_to_list import numpy as np import os out_files = [] for idx, filename in enumerate(filename_to_list(motion_params)): params = np.genfromtxt(filename) out_params = params for d in range(1, derivatives + 1): cparams = np.vstack((np.repeat(params[0, :][None, :], d, axis=0), params)) out_params = np.hstack((out_params, np.diff(cparams, d, axis=0))) out_params2 = out_params for i in range(2, order + 1): out_params2 = np.hstack((out_params2, np.power(out_params, i))) filename = os.path.join(os.getcwd(), "motion_regressor%02d.txt" % idx) np.savetxt(filename, out_params2, fmt="%.10f") out_files.append(filename) return out_files
def bandpass_filter(files, lowpass_freq, highpass_freq, fs): """Bandpass filter the input files Parameters ---------- files: list of 4d nifti files lowpass_freq: cutoff frequency for the low pass filter (in Hz) highpass_freq: cutoff frequency for the high pass filter (in Hz) fs: sampling rate (in Hz) """ out_files = [] for filename in filename_to_list(files): path, name, ext = split_filename(filename) out_file = os.path.join(os.getcwd(), name + '_bp' + ext) img = nb.load(filename) timepoints = img.shape[-1] F = np.zeros((timepoints)) lowidx = int(timepoints / 2) + 1 if lowpass_freq > 0: lowidx = np.round(float(lowpass_freq) / fs * timepoints) highidx = 0 if highpass_freq > 0: highidx = np.round(float(highpass_freq) / fs * timepoints) F[highidx:lowidx] = 1 F = ((F + F[::-1]) > 0).astype(int) data = img.get_data() if np.all(F == 1): filtered_data = data else: filtered_data = np.real(np.fft.ifftn(np.fft.fftn(data) * F)) img_out = nb.Nifti1Image(filtered_data, img.affine, img.header) img_out.to_filename(out_file) out_files.append(out_file) return list_to_filename(out_files)
def _list_outputs(self): outputs = self._outputs().get() outputs["smoothed_files"] = [] for imgf in filename_to_list(self.inputs.in_files): outputs["smoothed_files"].append(fname_presuffix(imgf, prefix="s")) return outputs
def _run_and_test(opts, output_base): outputs = fsl.FAST(**opts)._list_outputs() for output in outputs.values(): if output: for filename in filename_to_list(output): assert os.path.realpath(filename).startswith( os.path.realpath(output_base))
def median(in_files): """Computes an average of the median of each realigned timeseries Parameters ---------- in_files: one or more realigned Nifti 4D time series Returns ------- out_file: a 3D Nifti file """ average = None for idx, filename in enumerate(filename_to_list(in_files)): img = nb.load(filename) data = np.median(img.get_data(), axis=3) if average is None: average = data else: average = average + data median_img = nb.Nifti1Image(average / float(idx + 1), img.affine, img.header) filename = os.path.join(os.getcwd(), 'median.nii.gz') median_img.to_filename(filename) return filename
def median(in_files): """Computes an average of the median of each realigned timeseries Parameters ---------- in_files: one or more realigned Nifti 4D time series Returns ------- out_file: a 3D Nifti file """ import numpy as np import nibabel as nb from nipype.utils import NUMPY_MMAP average = None for idx, filename in enumerate(filename_to_list(in_files)): img = nb.load(filename, mmap=NUMPY_MMAP) data = np.median(img.get_data(), axis=3) if average is None: average = data else: average = average + data median_img = nb.Nifti1Image(average / float(idx + 1), img.affine, img.header) filename = os.path.join(os.getcwd(), 'median.nii.gz') median_img.to_filename(filename) return filename
def motion_regressors(motion_params, order=0, derivatives=1): """Compute motion regressors upto given order and derivative motion + d(motion)/dt + d2(motion)/dt2 (linear + quadratic) """ from nipype.utils.filemanip import filename_to_list import numpy as np import os out_files = [] for idx, filename in enumerate(filename_to_list(motion_params)): params = np.genfromtxt(filename) out_params = params for d in range(1, derivatives + 1): cparams = np.vstack((np.repeat(params[0, :][None, :], d, axis=0), params)) out_params = np.hstack((out_params, np.diff(cparams, d, axis=0))) out_params2 = out_params for i in range(2, order + 1): out_params2 = np.hstack((out_params2, np.power(out_params, i))) filename = os.path.join( os.getcwd(), "motion_regressor_der%d_ord%d.txt" % (derivatives, order)) np.savetxt(filename, out_params2, fmt="%.10f") out_files.append(filename) return out_files
def median(in_files): """Computes an average of the median of each realigned timeseries Parameters ---------- in_files: one or more realigned Nifti 4D time series Returns ------- out_file: a 3D Nifti file """ average = None for idx, filename in enumerate(filename_to_list(in_files)): img = nb.load(filename) data = np.median(img.get_data(), axis=3) if average is None: average = data else: average = average + data median_img = nb.Nifti1Image(average/float(idx + 1), img.get_affine(), img.get_header()) filename = os.path.join(os.getcwd(), 'median.nii.gz') median_img.to_filename(filename) return filename
def checkT1s(T1_files, cw256=False): """Verifying size of inputs and setting workflow parameters""" import sys import nibabel as nb from nipype.utils.filemanip import filename_to_list T1_files = filename_to_list(T1_files) if len(T1_files) == 0: print("ERROR: No T1's Given") sys.exit(-1) shape = nb.load(T1_files[0]).shape for t1 in T1_files[1:]: if nb.load(t1, mmap=NUMPY_MMAP).shape != shape: print("ERROR: T1s not the same size. Cannot process {0} and {1} " "together".format(T1_files[0], t1)) sys.exit(-1) origvol_names = ["{0:03d}.mgz".format(i + 1) for i in range(len(T1_files))] # check if cw256 is set to crop the images if size is larger than 256 if not cw256 and any(dim > 256 for dim in shape): print("Setting MRI Convert to crop images to 256 FOV") cw256 = True resample_type = 'cubic' if len(T1_files) > 1 else 'interpolate' return T1_files, cw256, resample_type, origvol_names
def plot_segs(image_nii, seg_niis, mask_nii, out_file, masked=False, title=None, compress='auto', **plot_params): """ plot segmentation as contours over the image (e.g. anatomical). seg_niis should be a list of files. mask_nii helps determine the cut coordinates. plot_params will be passed on to nilearn plot_* functions. If seg_niis is a list of size one, it behaves as if it was plotting the mask. """ def _plot_anat_with_contours(image, segs=None, **plot_params): assert not segs is None assert len(segs) <= 3 plot_params = {} if plot_params is None else plot_params # anatomical plot_params['alpha'] = .7 svg = plot_anat(image, **plot_params) # segment contours for seg, color in zip(segs, ['r', 'g', 'y']): plot_params['colors'] = color plot_params['levels'] = [ 0.5 ] if 'levels' not in plot_params else plot_params['levels'] plot_params['alpha'] = 1 svg.add_contours(seg, **plot_params) svgs_list.append(extract_svg(svg, compress=compress)) svg.close() plot_params = {} if plot_params is None else plot_params image_nii = _3d_in_file(image_nii) data = image_nii.get_data() plot_params = robust_set_limits(data, plot_params) seg_niis = filemanip.filename_to_list(seg_niis) mask_nii = nb.load(mask_nii) if masked else nlimage.threshold_img( mask_nii, 1e-3) cuts = cuts_from_bbox(mask_nii, cuts=7) svgs_list = [] plot_xyz(image_nii, _plot_anat_with_contours, cuts, segs=seg_niis, **plot_params) save_html(template='segmentation.tpl', report_file_name=out_file, unique_string='seg' + str(uuid4()), base_image='<br />'.join(svgs_list), title=title)
def __init__(self, input_names, output_names, function=None, imports=None, **inputs): """ Parameters ---------- input_names: single str or list names corresponding to function inputs output_names: single str or list names corresponding to function outputs. has to match the number of outputs function : callable callable python object. must be able to execute in an isolated namespace (possibly in concert with the ``imports`` parameter) imports : list of strings list of import statements that allow the function to execute in an otherwise empty namespace """ super(Function, self).__init__(**inputs) if function: if hasattr(function, '__call__'): try: self.inputs.function_str = getsource(function) except IOError: raise Exception('Interface Function does not accept ' \ 'function objects defined interactively ' \ 'in a python session') elif isinstance(function, six.string_types): self.inputs.function_str = dumps(function) else: raise Exception('Unknown type of function') self.inputs.on_trait_change(self._set_function_string, 'function_str') self._input_names = filename_to_list(input_names) self._output_names = filename_to_list(output_names) add_traits(self.inputs, [name for name in self._input_names]) self.imports = imports self._out = {} for name in self._output_names: self._out[name] = None
def _parse_inputs(self): """validate spm realign options if set to None ignore """ einputs = super(Level1Design, self)._parse_inputs(skip=('mask_threshold')) for sessinfo in einputs[0]['sess']: sessinfo['scans'] = scans_for_fnames(filename_to_list(sessinfo['scans']), keep4d=False) if not isdefined(self.inputs.spm_mat_dir): einputs[0]['dir'] = np.array([str(os.getcwd())], dtype=object) return einputs
def _list_outputs(self): outputs = self._outputs().get() jobtype = self.inputs.jobtype if jobtype == "calculatevdm": outputs['vdm'] = [] for phase in filename_to_list(self.inputs.phase): outputs['vdm'].append(fname_presuffix(phase, prefix='vdm5_sc')) outputs['vdm'] = list_to_filename(outputs['vdm']) return outputs
def detect_inputs(t1w_list, t2w_list=[], hires_enabled=True): from nipype.interfaces.base import isdefined from nipype.utils.filemanip import filename_to_list from nipype.interfaces.traits_extension import Undefined import nibabel as nib t1w_list = filename_to_list(t1w_list) t2w_list = filename_to_list(t2w_list) if isdefined(t2w_list) else [] t1w_ref = nib.load(t1w_list[0]) # Use high resolution preprocessing if voxel size < 1.0mm # Tolerance of 0.05mm requires that rounds down to 0.9mm or lower hires = hires_enabled and max(t1w_ref.header.get_zooms()) < 1 - 0.05 t2w = Undefined if t2w_list and max(nib.load(t2w_list[0]).header.get_zooms()) < 1.2: t2w = t2w_list[0] # https://surfer.nmr.mgh.harvard.edu/fswiki/SubmillimeterRecon mris_inflate = '-n 50' if hires else Undefined return (t2w, isdefined(t2w), hires, mris_inflate)