def load_vols(vols): if isinstance(vols, list): return [load_vol(vol) if isinstance(vol, basestring) else vol for vol in vols] elif isinstance(vols, basestring): return nibabel.four_to_three(nibabel.load(vols)) elif is_niimg(vols): return nibabel.four_to_three(vols) else: raise TypeError(type(vols))
def prep_data(self, nifti1, bval1, bvec1, nifti2, bval2, bvec2): ''' Load the reconstructed image files and generate the files that TOPUP needs. ''' ni1 = nb.load(nifti1) ni2 = nb.load(nifti2) phase_dim1 = ni1.get_header().get_dim_info()[1] phase_dim2 = ni2.get_header().get_dim_info()[1] bvals1 = np.loadtxt(bval1) bvals2 = np.loadtxt(bval2) bvecs1 = np.loadtxt(bvec1) bvecs2 = np.loadtxt(bvec2) nondwi1 = [im for i,im in enumerate(nb.four_to_three(ni1)) if bvals1[i]<10 and i<self.num_vols] nondwi2 = [im for i,im in enumerate(nb.four_to_three(ni2)) if bvals2[i]<10 and i<self.num_vols] b0 = nb.concat_images(nondwi1+nondwi2) # Topup requires an even number of slices if b0.shape[2]%2: d = b0.get_data() d = np.concatenate((d,np.zeros((d.shape[0],d.shape[1],1,d.shape[3]), dtype=d.dtype)),axis=2) b0 = nb.Nifti1Image(d, b0.get_affine()) nb.save(b0, self.b0_file) with open(self.acq_file, 'w') as f: for i in xrange(len(nondwi1)): row = ['0','0','0',str(self.readout_time1),'\n'] row[phase_dim1] = str(self.pe_dir1) f.write(' '.join(row)) for i in xrange(len(nondwi2)): row = ['0','0','0',str(self.readout_time2),'\n'] row[phase_dim2] = str(self.pe_dir2) f.write(' '.join(row)) mux_ims1 = nb.four_to_three(ni1)[self.num_cal1:] mux_ims2 = nb.four_to_three(ni2)[self.num_cal2:] all_ims = nb.concat_images(mux_ims1 + mux_ims2) if all_ims.shape[2]%2: d = all_ims.get_data() d = np.concatenate((d,np.zeros((d.shape[0],d.shape[1],1,d.shape[3]), dtype=d.dtype)),axis=2) all_ims = nb.Nifti1Image(d, all_ims.get_affine()) nb.save(all_ims, self.dwi_base+'.nii.gz') indices = ['1' for i in xrange(len(mux_ims1))] + [str(len(nondwi1)+1) for i in xrange(len(mux_ims2))] with open(self.index_file, 'w') as f: f.write(' '.join(indices)) bvals = np.concatenate((bvals1[self.num_cal1:],bvals2[self.num_cal2:]), axis=0) bvecs = np.concatenate((bvecs1[:,self.num_cal1:],bvecs2[:,self.num_cal2:]), axis=1) with open(self.bval_file, 'w') as f: f.write(' '.join(['%0.1f' % value for value in bvals])) with open(self.bvec_file, 'w') as f: f.write(' '.join(['%0.4f' % value for value in bvecs[0,:]]) + '\n') f.write(' '.join(['%0.4f' % value for value in bvecs[1,:]]) + '\n') f.write(' '.join(['%0.4f' % value for value in bvecs[2,:]]) + '\n')
def test_save_vols(): # setup n_scans = 10 output_dir = os.path.join(OUTPUT_DIR, inspect.stack()[0][3]) if not os.path.exists(output_dir): os.makedirs(output_dir) # create 4D film film = create_random_image(ndim=4, n_scans=n_scans) threeD_vols = nibabel.four_to_three(film) # save vols manually film_filename = os.path.join(output_dir, "film.nii.gz") threeD_vols_filenames = [os.path.join(output_dir, "fMETHODS-%06i" % i) for i in range(len(threeD_vols))] # check saving seperate 3D vols for stuff in [film, threeD_vols]: if isinstance(stuff, list): basenames = [os.path.basename(x) for x in threeD_vols_filenames] else: basenames = os.path.basename(film_filename) for concat in [False, True]: for bn in [None, basenames]: saved_vols_filenames = save_vols(stuff, output_dir, ext=".nii.gz", concat=concat, basenames=bn) if not concat and isinstance(stuff, list): assert_true(isinstance(saved_vols_filenames, list)) assert_equal(len(saved_vols_filenames), n_scans) if not bn is None: assert_equal(os.path.basename(saved_vols_filenames[7]), "fMETHODS-000007.nii.gz") else: assert_true(isinstance(saved_vols_filenames, basestring)) assert_true(saved_vols_filenames.endswith(".nii.gz"), msg=saved_vols_filenames) assert_true(is_4D(check_niimg_4d(saved_vols_filenames)))
def b0_average(in_dwi, in_bval, out_file=None): """ A function that averages the *b0* volumes from a DWI dataset. .. warning:: *b0* should be already registered (head motion artifact should be corrected). """ import numpy as np import nibabel as nb import os.path as op if out_file is None: fname, ext = op.splitext(op.basename(in_dwi)) if ext == ".gz": fname, ext2 = op.splitext(fname) ext = ext2 + ext out_file = op.abspath("%s_avg_b0%s" % (fname, ext)) imgs = np.array(nb.four_to_three(nb.load(in_dwi))) bval = np.loadtxt(in_bval) b0s = [im.get_data().astype(np.float32) for im in imgs[np.where(bval == 0)]] b0 = np.average(np.array(b0s), axis=0) hdr = imgs[0].get_header().copy() hdr.set_data_shape(b0.shape) hdr.set_xyzt_units('mm') hdr.set_data_dtype(np.float32) nb.Nifti1Image(b0, imgs[0].get_affine(), hdr).to_filename(out_file) return out_file
def b0_average(in_dwi, in_bval, max_b=10.0, out_file=None): """ A function that averages the *b0* volumes from a DWI dataset. As current dMRI data are being acquired with all b-values > 0.0, the *lowb* volumes are selected by specifying the parameter max_b. .. warning:: *b0* should be already registered (head motion artifact should be corrected). """ import numpy as np import nibabel as nb import os.path as op if out_file is None: fname, ext = op.splitext(op.basename(in_dwi)) if ext == ".gz": fname, ext2 = op.splitext(fname) ext = ext2 + ext out_file = op.abspath("%s_avg_b0%s" % (fname, ext)) imgs = np.array(nb.four_to_three(nb.load(in_dwi))) bval = np.loadtxt(in_bval) index = np.argwhere(bval <= max_b).flatten().tolist() b0s = [im.get_data().astype(np.float32) for im in imgs[index]] b0 = np.average(np.array(b0s), axis=0) hdr = imgs[0].get_header().copy() hdr.set_data_shape(b0.shape) hdr.set_xyzt_units('mm') hdr.set_data_dtype(np.float32) nb.Nifti1Image(b0, imgs[0].get_affine(), hdr).to_filename(out_file) return out_file
def time_avg(in_file, index=[0], out_file=None): """ Average the input time-series, selecting the indices given in index .. warning:: time steps should be already registered (corrected for head motion artifacts). """ import numpy as np import nibabel as nb import os.path as op if out_file is None: fname, ext = op.splitext(op.basename(in_file)) if ext == ".gz": fname, ext2 = op.splitext(fname) ext = ext2 + ext out_file = op.abspath("%s_baseline%s" % (fname, ext)) index = np.atleast_1d(index).tolist() imgs = np.array(nb.four_to_three(nb.load(in_file)))[index] if len(index) == 1: data = imgs[0].get_data().astype(np.float32) else: data = np.average(np.array([im.get_data().astype(np.float32) for im in imgs]), axis=0) hdr = imgs[0].get_header().copy() hdr.set_data_shape(data.shape) hdr.set_xyzt_units('mm') hdr.set_data_dtype(np.float32) nb.Nifti1Image(data, imgs[0].get_affine(), hdr).to_filename(out_file) return out_file
def test_load_4D_img(): # setup output_dir = os.path.join(OUTPUT_DIR, inspect.stack()[0][3]) if not os.path.exists(output_dir): os.makedirs(output_dir) # try loading from 4D niimg film = create_random_image(n_scans=10) loaded_4D_img = load_4D_img(film) assert_true(is_niimg(loaded_4D_img)) assert_equal(loaded_4D_img.shape, film.shape) # try loading from 4D image file film = create_random_image(n_scans=10) saved_img_filename = os.path.join(output_dir, "4D.nii.gz") nibabel.save(film, saved_img_filename) loaded_4D_img = load_4D_img(saved_img_filename) assert_true(is_niimg(loaded_4D_img)) assert_equal(loaded_4D_img.shape, film.shape) # try loading from list of 3D niimgs film = create_random_image(n_scans=10) loaded_4D_img = load_4D_img(nibabel.four_to_three(film)) assert_true(is_niimg(loaded_4D_img)) assert_equal(loaded_4D_img.shape, film.shape) # try loading from list of 3D image files film = create_random_image(n_scans=10) saved_vols_filenames = save_vols(film, output_dir, ext='.nii.gz', ) loaded_4D_img = load_4D_img(saved_vols_filenames) assert_true(is_niimg(loaded_4D_img)) assert_equal(loaded_4D_img.shape, film.shape)
def _run_interface(self, runtime): mask_imgs = [nb.load(fname) for fname in self.inputs.label_files] if len(mask_imgs) == 1: mask_imgs = nb.four_to_three(mask_imgs[0]) masks = [mask_img.get_data().astype(np.bool) for mask_img in mask_imgs] n_masks = len(masks) if n_masks != len(self.inputs.class_labels): raise ValueError("Number of masks must match number of labels") img = nb.load(self.inputs.in_file) series = np.zeros((img.shape[3], n_masks)) data = img.get_data() for j in range(n_masks): series[:, j] = data[masks[j], :].mean(axis=0) output = np.vstack((self.inputs.class_labels, series.astype(str))) self._results['out_file'] = os.path.join(runtime.cwd, self.inputs.out_file) np.savetxt( self._results['out_file'], output, fmt=b'%s', delimiter='\t') return runtime
def read_niftis(file_lists): """ Read niftis. Parameters ---------- file_lists: list of list of paths. Each list of file paths is a unique class. Returns ------- data, labels: tuple of array-like and list The data and corresponding labels """ data0 = load_image(file_lists[0][0]).get_data() if len(data0.shape) == 3: x, y, z = data0.shape t = 1 elif len(data0.shape) == 4: x, y, z, t = data0.shape else: raise ValueError("Cannot parse data with dimensions %r" % data0.shape) dt = (sum(len(fl) for fl in file_lists)) * t data = np.zeros((dt, x, y, z)) labels = [[i] * (len(fl) * t) for i, fl in enumerate(file_lists)] labels = [item for sublist in labels for item in sublist] for i, fl in enumerate(file_lists): assert len([j for j in labels if j == i]) == len(fl) * t flattened_list = [item for sublist in file_lists for item in sublist] for i, f in enumerate(flattened_list): logger.info("Loading subject from file: %s%s" % (f, '' * 30)) nifti = load_image(f) subject_data = nifti.get_data() if len(subject_data.shape) == 3: data[i] = subject_data elif len(subject_data.shape) == 4: data[i * t: (i + 1) * t] = subject_data.transpose((3, 0, 1, 2)) else: raise ValueError("Cannot parse subject data with dimensions %r" % subject_data.shape) logger.info("\rLoading subject from file: %s\n" % ('DONE' + " "*30)) if data.shape[0] != len(labels): raise ValueError("Data and labels have different number of samples.") base_file = flattened_list[0] # Use nibabel in case we need to convert from 4d to 3d base = nib.load(base_file) if len(base.shape) == 4: base = nib.four_to_three(base)[0] return data, labels, base
def _run_interface(self, runtime): if not self._have_nipy: raise RuntimeError('nipy is not installed') from nipy.algorithms.registration.histogram_registration import HistogramRegistration from nipy.algorithms.registration.affine import Affine vol1_nii = nb.load(self.inputs.volume1) vol2_nii = nb.load(self.inputs.volume2) dims = vol1_nii.get_data().ndim if dims == 3 or dims == 2: vols1 = [vol1_nii] vols2 = [vol2_nii] if dims == 4: vols1 = nb.four_to_three(vol1_nii) vols2 = nb.four_to_three(vol2_nii) if dims < 2 or dims > 4: raise RuntimeError('Image dimensions not supported (detected %dD file)' % dims) if isdefined(self.inputs.mask1): mask1 = nb.load(self.inputs.mask1).get_data() == 1 else: mask1 = None if isdefined(self.inputs.mask2): mask2 = nb.load(self.inputs.mask2).get_data() == 1 else: mask2 = None self._similarity = [] for ts1, ts2 in zip(vols1, vols2): histreg = HistogramRegistration(from_img=ts1, to_img=ts2, similarity=self.inputs.metric, from_mask=mask1, to_mask=mask2) self._similarity.append(histreg.eval(Affine())) return runtime
def test_load_specific_vol(): # setup output_dir = os.path.join(OUTPUT_DIR, inspect.stack()[0][3]) if not os.path.exists(output_dir): os.makedirs(output_dir) n_scans = 23 # create 4D film film = create_random_image(ndim=4, n_scans=n_scans) # test loading vol from nibabel image object for t in xrange(n_scans): _vol, _n_scans = load_specific_vol(film, t) assert_equal(_n_scans, n_scans) assert_true(isinstance(_vol, type(film))) assert_equal(_vol.shape, film.shape[:-1]) numpy.testing.assert_array_equal(_vol.get_data(), film.get_data()[..., t]) # test loading vol from a single 4D filename for ext in IMAGE_EXTENSIONS: for film_filename_type in ['str', 'list']: if film_filename_type == 'str': # save film as single filename with extension ext film_filename = os.path.join(output_dir, "4D%s" % ext) nibabel.save(film, film_filename) else: # save film as multiple filenames (3D vols), with ext extension vols = nibabel.four_to_three(film) film_filename = [] for t, vol in zip(xrange(n_scans), vols): vol_filename = os.path.join(output_dir, "vol_%i%s" % (t, ext)) nibabel.save(vol, vol_filename) film_filename.append(vol_filename) # test loading proper for t in xrange(n_scans): # note that .img loads as Nifti1Pair, not Nifti1Image vol_type = nibabel.Nifti1Pair if ext == '.img' else \ nibabel.Nifti1Image # load specific 3D vol from 4D film by filename _vol, _n_scans = load_specific_vol(film_filename, t) assert_equal(_n_scans, n_scans) assert_true(isinstance(_vol, vol_type)) assert_equal(_vol.shape, film.shape[:-1]) numpy.testing.assert_array_equal(_vol.get_data(), film.get_data()[..., t])
def test_do_3Dto4D_merge(): # setup n_scans = 10 output_dir = os.path.join(OUTPUT_DIR, inspect.stack()[0][3]) if not os.path.exists(output_dir): os.makedirs(output_dir) # create 4D film film = create_random_image(ndim=4, n_scans=n_scans) threeD_vols = nibabel.four_to_three(film) _film = do_3Dto4D_merge(threeD_vols) assert_equal(_film.shape, film.shape) save_vols(threeD_vols, output_dir, ext='.nii.gz')
def split_warp_volumes_fn(in_file): from nipype import logging from nipype.utils.filemanip import split_filename import nibabel as nb import os.path as op iflogger = logging.getLogger('interface') iflogger.info(in_file) path, name, ext = split_filename(in_file) image = nb.load(in_file) x_img, y_img, z_img = nb.four_to_three(image) x = op.abspath(name + '_x' + ".nii.gz") y = op.abspath(name + '_y' + ".nii.gz") z = op.abspath(name + '_z' + ".nii.gz") nb.save(x_img, x) nb.save(y_img, y) nb.save(z_img, z) return x, y, z
def _run_interface(self, runtime): from dipy.reconst.csdeconv import ConstrainedSphericalDeconvModel from dipy.data import get_sphere # import marshal as pickle import pickle as pickle import gzip img = nb.load(self.inputs.in_file) imref = nb.four_to_three(img)[0] affine = img.get_affine() if isdefined(self.inputs.in_mask): msk = nb.load(self.inputs.in_mask).get_data() else: msk = np.ones(imref.get_shape()) data = img.get_data().astype(np.float32) hdr = imref.get_header().copy() gtab = self._get_gradient_table() resp_file = np.loadtxt(self.inputs.response) response = (np.array(resp_file[0:3]), resp_file[-1]) ratio = response[0][1] / response[0][0] if abs(ratio - 0.2) > 0.1: IFLOGGER.warn(('Estimated response is not prolate enough. ' 'Ratio=%0.3f.') % ratio) csd_model = ConstrainedSphericalDeconvModel( gtab, response, sh_order=self.inputs.sh_order) IFLOGGER.info('Fitting CSD model') csd_fit = csd_model.fit(data, msk) f = gzip.open(self._gen_filename('csdmodel', ext='.pklz'), 'wb') pickle.dump(csd_model, f, -1) f.close() if self.inputs.save_fods: sphere = get_sphere('symmetric724') fods = csd_fit.odf(sphere) nb.Nifti1Image(fods.astype(np.float32), img.get_affine(), None).to_filename(self._gen_filename('fods')) return runtime
def _run_interface(self, runtime): from dipy.reconst.csdeconv import ConstrainedSphericalDeconvModel from dipy.data import get_sphere # import marshal as pickle import cPickle as pickle import gzip img = nb.load(self.inputs.in_file) imref = nb.four_to_three(img)[0] affine = img.get_affine() if isdefined(self.inputs.in_mask): msk = nb.load(self.inputs.in_mask).get_data() else: msk = np.ones(imref.get_shape()) data = img.get_data().astype(np.float32) hdr = imref.get_header().copy() gtab = self._get_gradient_table() resp_file = np.loadtxt(self.inputs.response) response = (np.array(resp_file[0:3]), resp_file[-1]) ratio = response[0][1] / response[0][0] if abs(ratio - 0.2) > 0.1: IFLOGGER.warn(('Estimated response is not prolate enough. ' 'Ratio=%0.3f.') % ratio) csd_model = ConstrainedSphericalDeconvModel( gtab, response, sh_order=self.inputs.sh_order) IFLOGGER.info('Fitting CSD model') csd_fit = csd_model.fit(data, msk) f = gzip.open(self._gen_filename('csdmodel', ext='.pklz'), 'wb') pickle.dump(csd_model, f, -1) f.close() if self.inputs.save_fods: sphere = get_sphere('symmetric724') fods = csd_fit.odf(sphere) nb.Nifti1Image(fods.astype(np.float32), img.get_affine(), None).to_filename(self._gen_filename('fods')) return runtime
def smooth_image(img, fwhm, **kwargs): """Function wrapper LinearFilter class. Spatially smoothens img with kernel of size fwhm. Parameters ---------- img: ``ni.Nifti1Image`` image to be smoothen fwhm: 1D array like of size as big as there are spatial dimensions in the image FWHM of smoothing kernel **kwargs: dict-like key-word arguments passed to LinearFilter constructor. Returns ------- Smoothened image, same type and size as the input img. """ if isinstance(img, basestring): img = ni.load(img) elif isinstance(img, tuple): assert len(img) == 2 return smooth_image(ni.Nifti1Image(img[0], img[1]), fwhm, **kwargs) elif isinstance(img, list): return [smooth_image(x, fwhm, **kwargs) for x in img] else: assert is_niimg(img) if len(img.shape) == 4: return ni.concat_images( [smooth_image(vol, fwhm, **kwargs) for vol in ni.four_to_three(img)]) else: assert len(img.shape) == 3 smoothing_kernel = LinearFilter( img.get_affine(), img.shape, fwhm=fwhm, **kwargs) return ni.Nifti1Image(smoothing_kernel.smooth(img.get_data(), clean=True), img.get_affine())
def test_save_vols(): # setup n_scans = 10 output_dir = os.path.join(OUTPUT_DIR, inspect.stack()[0][3]) if not os.path.exists(output_dir): os.makedirs(output_dir) # create 4D film film = create_random_image(ndim=4, n_scans=n_scans) threeD_vols = nibabel.four_to_three(film) # save vols manually film_filename = os.path.join(output_dir, 'film.nii.gz') threeD_vols_filenames = [os.path.join(output_dir, 'fMETHODS-%06i' % i) for i in range(len(threeD_vols))] # check saving seperate 3D vols for stuff in [film, threeD_vols]: if isinstance(stuff, list): basenames = [os.path.basename(x) for x in threeD_vols_filenames] else: basenames = os.path.basename(film_filename) for concat in [False, True]: for bn in [None, basenames]: saved_vols_filenames = save_vols(stuff, output_dir, ext='.nii.gz', concat=concat, basenames=bn ) if not concat and isinstance(stuff, list): assert_true(isinstance( saved_vols_filenames, list)) assert_equal(len(saved_vols_filenames), n_scans) if not bn is None: assert_equal(os.path.basename(saved_vols_filenames[7]), 'fMETHODS-000007.nii.gz') else: assert_true(isinstance(saved_vols_filenames, basestring)) assert_true(saved_vols_filenames.endswith('.nii.gz'), msg=saved_vols_filenames) assert_true(is_4D(check_niimg_4d( saved_vols_filenames)))
def _run_interface(self, runtime): img = nb.load(self.inputs.in_file) mask_imgs = [nb.load(fname) for fname in self.inputs.label_files] if len(mask_imgs) == 1 and len(mask_imgs[0].shape) == 4: mask_imgs = nb.four_to_three(mask_imgs[0]) # This check assumes all input masks have same dimensions if img.shape[:3] != mask_imgs[0].shape[:3]: raise NotImplementedError( "Input image and mask should be of " "same dimensions before running SignalExtraction") # Load the mask. # If mask is a list, each mask is treated as its own ROI/parcel # If mask is a 3D, each integer is treated as its own ROI/parcel if len(mask_imgs) > 1: masks = [ mask_img.get_data() >= self.inputs.prob_thres for mask_img in mask_imgs ] else: labelsmap = mask_imgs[0].get_data() labels = np.unique(labelsmap) labels = labels[labels != 0] masks = [labelsmap == l for l in labels] if len(masks) != len(self.inputs.class_labels): raise ValueError("Number of masks must match number of labels") series = np.zeros((img.shape[3], len(masks))) metadata = {} data = img.get_data() for j, (mask, label) in enumerate(zip(masks, self.inputs.class_labels)): series[:, j] = data[mask, :].mean(axis=0) metadata[label] = {'Method': 'Mean'} output = np.vstack((self.inputs.class_labels, series.astype(str))) self._results['out_file'] = os.path.join(runtime.cwd, self.inputs.out_file) self._results['metadata'] = metadata np.savetxt(self._results['out_file'], output, fmt=b'%s', delimiter='\t') return runtime
def smooth_image(img, fwhm, **kwargs): """Function wrapper LinearFilter class. Spatially smoothens img with kernel of size fwhm. Parameters ---------- img: ``ni.Nifti1Image`` image to be smoothen fwhm: 1D array like of size as big as there are spatial dimensions in the image FWHM of smoothing kernel **kwargs: dict-like key-word arguments passed to LinearFilter constructor. Returns ------- Smoothened image, same type and size as the input img. """ if isinstance(img, basestring): img = ni.load(img) elif isinstance(img, tuple): assert len(img) == 2 return smooth_image(ni.Nifti1Image(img[0], img[1]), fwhm, **kwargs) elif isinstance(img, list): return [smooth_image(x, fwhm, **kwargs) for x in img] else: assert is_niimg(img) if len(img.shape) == 4: return ni.concat_images([ smooth_image(vol, fwhm, **kwargs) for vol in ni.four_to_three(img) ]) else: assert len(img.shape) == 3 smoothing_kernel = LinearFilter(img.get_affine(), img.shape, fwhm=fwhm, **kwargs) return ni.Nifti1Image( smoothing_kernel.smooth(img.get_data(), clean=True), img.get_affine())
def _split_epi_lists(in_files, pe_dir, max_trs=50): """ Split input EPIs and generate an output list of PEs. Inputs ------ in_files : list of ``BIDSFile``s The EPI images that will be pooled into field estimation. pe_dir : str The phase-encoding direction of the IntendedFor EPI scan. max_trs : int Index of frame after which all volumes will be discarded from the input EPI images. """ from os import path as op import nibabel as nb matched_pe = [] opposed_pe = [] for i, (epi_path, epi_pe) in enumerate(in_files): if epi_pe[0] == pe_dir[0]: img = nb.load(epi_path) if len(img.shape) == 3: splitnii = [img] else: splitnii = nb.four_to_three(img.slicer[:, :, :, :max_trs]) for j, nii in enumerate(splitnii): out_name = op.abspath('dir-%s_tstep-%03d_pe-%03d.nii.gz' % (epi_pe, i, j)) nii.to_filename(out_name) if epi_pe == pe_dir: matched_pe.append(out_name) else: opposed_pe.append(out_name) if matched_pe: return [opposed_pe, matched_pe] return [opposed_pe]
def load_specific_vol(vols, t, strict=False): """ Utility function for loading specific volume on demand. Parameters ---------- vols: string(s) or nibabel image object(s) input volumes or single 4D film t: int index of requested volume in the film """ assert t >= 0 if isinstance(vols, list): n_scans = len(vols) vol = load_vol(vols[t]) elif is_niimg(vols) or isinstance(vols, basestring): _vols = nibabel.load(vols) if isinstance(vols, basestring) else vols if len(_vols.shape) != 4: if strict: raise ValueError( "Expecting 4D image, got %iD" % len(_vols.shape)) else: return _vols, 1 n_scans = _vols.shape[-1] vol = nibabel.four_to_three(_vols)[t] else: # unhandled type raise TypeError( ("vols must be string, image object, or list of such; " "got %s" % type(vols))) # delete trivial dimension if len(vol.shape) == 4: vol = nibabel.Nifti1Image(vol.get_data()[..., ..., ..., 0], vol.get_affine()) assert is_niimg(vol) assert is_3D(vol) return vol, n_scans
def normalization_2_common_space(self): print('normalization') for (input_nii_file,output_nii_file) in zip(self.input_nii, self.normalized_nii): print('run %s' % input_nii_file) print('generate %s' % output_nii_file) if os.path.exists(output_nii_file): continue dir_name = os.path.dirname(output_nii_file) if not os.path.exists(dir_name): os.makedirs(dir_name) mni_nii_file = self.get_mni152_nii_file(input_nii_file) nib_img = nib.load(input_nii_file) if len(nib_img.shape) > 3: nib_3d_imgs = nib.four_to_three(nib_img) else: nib_3d_imgs = [nib_img] dyn_3d_nib_files = [] dyn_3d_nib_in_root = tempfile.mkdtemp() for nib_3d_img in nib_3d_imgs: nib_3d_img_file = os.path.join(dyn_3d_nib_in_root, uuid.uuid4().__str__() + '.nii.gz') nib_3d_img.to_filename(nib_3d_img_file) dyn_3d_nib_files.append(nib_3d_img_file) dyn_3d_nib_out_root = tempfile.mkdtemp() dyn_3d_nib_out_files = [] for dyn_3d_nib_file in dyn_3d_nib_files: dyn_3d_nib_out_file = os.path.join(dyn_3d_nib_out_root, uuid.uuid4().__str__() + '.nii.gz') devnull = open(os.devnull, 'w') subprocess.call(['flirt', '-in', dyn_3d_nib_file, '-out', dyn_3d_nib_out_file, '-ref', mni_nii_file, '-bins', '256', '-dof', '12'],stdout=devnull, stderr=subprocess.STDOUT) dyn_3d_nib_out_files.append(dyn_3d_nib_out_file) nib_3d_imgs = [] for dyn_3d_nib_out_file in dyn_3d_nib_out_files: nib_3d_imgs.append(nib.load(dyn_3d_nib_out_file)) if len(nib_3d_imgs) > 1: nib_4d_img = nib.concat_images(nib_3d_imgs) nib_4d_img.to_filename(output_nii_file) else: nib_3d_imgs[0].to_filename(output_nii_file) if os.path.isdir(dyn_3d_nib_in_root): shutil.rmtree(dyn_3d_nib_in_root) if os.path.isdir(dyn_3d_nib_out_root): shutil.rmtree(dyn_3d_nib_out_root) return
def _run_interface(self, runtime): in_file = self.inputs.in_file img = nb.load(in_file) extra_dims = tuple(dim for dim in img.shape[3:] if dim > 1) or (1, ) if len(extra_dims) != 1: raise ValueError( f"Invalid shape {'x'.join(str(s) for s in img.shape)}") img = img.__class__(img.dataobj.reshape(img.shape[:3] + extra_dims), img.affine, img.header) self._results["out_files"] = [] for i, img_3d in enumerate(nb.four_to_three(img)): out_file = fname_presuffix(in_file, suffix=f"_idx-{i:03}", newpath=runtime.cwd) img_3d.to_filename(out_file) self._results["out_files"].append(out_file) return runtime
def test_transform(): # setup output_dir = os.path.join(OUTPUT_DIR, inspect.stack()[0][3]) if not os.path.exists(output_dir): os.makedirs(output_dir) film = nibabel.Nifti1Image(np.random.rand(11, 13, 17, 19), np.eye(4)) threeD_vols = nibabel.four_to_three(film) # filenames film_filename = os.path.join(output_dir, 'film.nii.gz') threeD_vols_filenames = [os.path.join(output_dir, 'fMETHODS-%06i' % i) for i in xrange(len(threeD_vols))] for stuff in [film, threeD_vols]: for as_files in [False, True]: if as_files: if isinstance(stuff, list): basenames = [os.path.basename(x) for x in threeD_vols_filenames] else: basenames = os.path.basename(film_filename) stuff = save_vols(stuff, output_dir, basenames=basenames) fmristc = fMRISTC().fit(raw_data=stuff) output = fmristc.transform(output_dir=output_dir) # test output type, shape, etc. if isinstance(stuff, list): nose.tools.assert_true(isinstance( output, list)) nose.tools.assert_equal(len(output), film.shape[-1]) if as_files: nose.tools.assert_equal(os.path.basename(output[7]), 'afMETHODS-000007.nii.gz') else: if as_files: nose.tools.assert_equal(os.path.basename(output), 'afilm.nii.gz')
def estimate_motion(nifti_image): # BEGIN STDOUT SUPRESSION actualstdout = sys.stdout sys.stdout = open(os.devnull,'w') # We want to use the middle time point as the reference. But the algorithm does't allow that, so fake it. ref_vol = nifti_image.shape[3]/2 + 1 ims = nb.four_to_three(nifti_image) reg = Realign4d(nb.concat_images([ims[ref_vol]] + ims)) # in the next release, we'll need to add tr=1. reg.estimate(loops=3) # default: loops=5 aligned = reg.resample(0)[:,:,:,1:] sys.stdout = actualstdout # END STDOUT SUPRESSION abs_disp = [] rel_disp = [] transrot = [] prev_T = None # skip the first one, since it's the reference volume for T in reg._transforms[0][1:]: # get the full affine for this volume by pre-multiplying by the reference affine #mc_affine = np.dot(ni.get_affine(), T.as_affine()) transrot.append(T.translation.tolist()+T.rotation.tolist()) # Compute the mean displacement # See http://www.fmrib.ox.ac.uk/analysis/techrep/tr99mj1/tr99mj1/node5.html # radius of the spherical head assumption (in mm): R = 80. # The center of the volume. Assume 0,0,0 in world coordinates. # Note: it might be better to use the center of mass of the brain mask. xc = np.matrix((0,0,0)).T T_error = T.as_affine() - np.eye(4) A = np.matrix(T_error[0:3,0:3]) t = np.matrix(T_error[0:3,3]).T abs_disp.append(np.sqrt( R**2. / 5 * np.trace(A.T * A) + (t + A*xc).T * (t + A*xc) ).item()) if prev_T!=None: T_error = T.as_affine() - prev_T.as_affine() # - np.eye(4) A = np.matrix(T_error[0:3,0:3]) t = np.matrix(T_error[0:3,3]).T rel_disp.append(np.sqrt( R**2. / 5 * np.trace(A.T * A) + (t + A*xc).T * (t + A*xc) ).item()) else: rel_disp.append(0.0) prev_T = T return aligned,np.array(abs_disp),np.array(rel_disp),np.array(transrot)
def load_specific_vol(vols, t, strict=False): """ Utility function for loading specific volume on demand. Parameters ---------- vols: string(s) or nibabel image object(s) input volumes or single 4D film t: int index of requested volume in the film """ assert t >= 0 if isinstance(vols, list): n_scans = len(vols) vol = load_vol(vols[t]) elif is_niimg(vols) or isinstance(vols, basestring): _vols = nibabel.load(vols) if isinstance(vols, basestring) else vols if len(_vols.shape) != 4: if strict: raise ValueError("Expecting 4D image, got %iD" % len(_vols.shape)) else: return _vols, 1 n_scans = _vols.shape[-1] vol = nibabel.four_to_three(_vols)[t] else: # unhandled type raise TypeError(("vols must be string, image object, or list of such; " "got %s" % type(vols))) # delete trivial dimension if len(vol.shape) == 4: vol = nibabel.Nifti1Image(vol.get_data()[..., ..., ..., 0], vol.get_affine()) assert is_niimg(vol) assert is_3D(vol) return vol, n_scans
def _load_mixed_gambles(zmap_imgs): """Ravel zmaps (one per subject) along time axis, resulting, in a n_subjects * n_trials 3D niimgs and, and then make gain vector y of same length. """ X = [] y = [] mask = [] for zmap_img in zmap_imgs: # load subject data this_X = zmap_img.get_data() affine = zmap_img.get_affine() finite_mask = np.all(np.isfinite(this_X), axis=-1) this_mask = np.logical_and(np.all(this_X != 0, axis=-1), finite_mask) this_y = np.array([np.arange(1, 9)] * 6).ravel() # gain levels if len(this_y) != this_X.shape[-1]: raise RuntimeError("%s: Expecting %i volumes, got %i!" % ( zmap_img, len(this_y), this_X.shape[-1])) # standardize subject data this_X -= this_X.mean(axis=-1)[..., np.newaxis] std = this_X.std(axis=-1) std[std == 0] = 1 this_X /= std[..., np.newaxis] # commit subject data X.append(this_X) y.extend(this_y) mask.append(this_mask) y = np.array(y) X = np.concatenate(X, axis=-1) mask = np.sum(mask, axis=0) > .5 * len(zmap_imgs) mask = np.logical_and(mask, np.all(np.isfinite(X), axis=-1)) X = X[mask, :].T tmp = np.zeros(list(mask.shape) + [len(X)]) tmp[mask, :] = X.T mask_img = nibabel.Nifti1Image(mask.astype(np.int), affine) X = nibabel.four_to_three(nibabel.Nifti1Image(tmp, affine)) return X, y, mask_img
def load_craddock_2011(number_of_clusters: int, similarity_measure: str = 't', algorithm='2level') -> nibabel.Nifti1Image: """ :param number_of_clusters: See the list of cluster sizes above or in volume_cluster_number.csv :param similarity_measure: t, s, or random (temporal, spatial, random) :param algorithm: 2level, mean, none :return: """ if not ["t", "s", "random"].__contains__(similarity_measure): raise RuntimeError("%s is not a valid similarity measure for the craddock atlases. Please use 't', 's', 'random'" % similarity_measure) if not ["2level", "mean", None].__contains__(algorithm): raise RuntimeError( "%s is not a valid algorithm type for the craddock atlases. Please use '2level', 'mean', or None" % similarity_measure) if not CRADDOCK_CLUSTER_SIZES.__contains__(number_of_clusters): raise RuntimeError("%d is not a valid cluster size for the craddock atlases. Please use one of %s" % (number_of_clusters, str(CRADDOCK_CLUSTER_SIZES))) algorithm = algorithm + '_' if algorithm is not None else '' dataset_path = os.path.join(__get_data_folder_path(), 'craddock_2011', '%scorr05_%sall.nii.gz' % (similarity_measure, algorithm)) dataset_img = nibabel.load(dataset_path) return nibabel.four_to_three(dataset_img)[CRADDOCK_CLUSTER_SIZES.index(number_of_clusters)]
def _flatten_split_merge(in_files): if isinstance(in_files, 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.warning('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 = fname_presuffix(in_files[0], suffix='_split%04d', newpath=os.getcwd()) 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 = fname_presuffix(in_files[0], suffix='_merged', newpath=os.getcwd()) nb.concat_images(all_nii).to_filename(merged) return merged, flat_split
def _make_sd(func_filenames=None, anat_filename=None, ext=".nii.gz", n_sessions=1, make_sess_dirs=False, func_ndim=4, unique_func_names=False, output_dir="/tmp/titi"): if not func_filenames is None: n_sessions = len(func_filenames) func = [create_random_image(ndim=func_ndim) for _ in range(n_sessions)] anat = create_random_image(ndim=3) if anat_filename is None: anat_filename = '%s/anat%s' % (DATA_DIR, ext) _save_img(anat, anat_filename) if not func_filenames is None: for sess_func, filename in zip(func, func_filenames): if isinstance(filename, str): _save_img(sess_func, filename) else: vols = nibabel.four_to_three(sess_func) for x, y in zip(vols, filename): assert isinstance(y, str), type(y) _save_img(x, y) else: func_filenames = [] for sess in range(n_sessions): sess_dir = DATA_DIR if not make_sess_dirs else os.path.join( DATA_DIR, "session%i" % sess) if not os.path.exists(sess_dir): os.makedirs(sess_dir) func_filename = '%s/func%s%s' % (sess_dir, "_sess_%i_" % sess if ( n_sessions > 1 and unique_func_names) else "", ext) _save_img(func[sess], func_filename) func_filenames.append(func_filename) sd = SubjectData(anat=anat_filename, func=func_filenames, output_dir=output_dir) return sd
def preprocess_fmri_fullbrain(experiment_data): # prepare the full-brain fMRI activation plots # http://nilearn.github.io/plotting/index.html fmri_data = nibabel.load(experiment_data['nifti_path']) fmri_data_slices = nibabel.four_to_three(fmri_data) for i in range(MAXIMUM_EPI_PLOTS): output_file_cond = os.path.join( os.path.dirname(__file__), '..', '..', 'temp', 'fmri', experiment_data['participant'] + '_fMRIfull_' + str(i) + '.png') # TODO make the cut slice configurable directly from the UI if OVERWRITE_EPI_PLOTS or not os.path.exists(output_file_cond): plotting.plot_img(fmri_data_slices[i], output_file=output_file_cond, title='Scan ' + str(i), cut_coords=(config.FMRI_CUT_SLICE_X, config.FMRI_CUT_SLICE_Y, config.FMRI_CUT_SLICE_Z), annotate=True, draw_cross=True, black_bg=True, cmap=plt.cm.nipy_spectral)
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 normalization_intensity(self): for (input_nii_file, output_nii_file) in zip(self.smoothed_nii, self.intensity_norm_nii): print('run intensity normalization %s' % input_nii_file) print('generate %s' % output_nii_file) if os.path.exists(output_nii_file): continue dir_name = os.path.dirname(output_nii_file) if not os.path.exists(dir_name): os.makedirs(dir_name) nib_img = nib.load(input_nii_file) if len(nib_img.shape) > 3: nib_3d_imgs = nib.four_to_three(nib_img) else: nib_3d_imgs = [nib_img] dyn_3d_nib_files = [] dyn_3d_nib_in_root = tempfile.mkdtemp() for nib_3d_img in nib_3d_imgs: nib_3d_img_file = os.path.join(dyn_3d_nib_in_root, uuid.uuid4().__str__() + '.nii.gz') nib_3d_img.to_filename(nib_3d_img_file) dyn_3d_nib_files.append(nib_3d_img_file) dyn_3d_nib_out_root = tempfile.mkdtemp() dyn_3d_nib_out_files = [] for dyn_3d_nib_file in dyn_3d_nib_files: dyn_3d_nib_out_file = os.path.join(dyn_3d_nib_out_root, uuid.uuid4().__str__() + '.nii.gz') nib_3d_img = nib.load(dyn_3d_nib_file) np_3d_img = nib_3d_img.get_data() np_3d_img_norm = np_3d_img / np.mean(np_3d_img) nib_3d_img_norm = nib.Nifti1Image(np_3d_img_norm, nib_3d_img.affine) nib_3d_img_norm.to_filename(dyn_3d_nib_out_file) dyn_3d_nib_out_files.append(dyn_3d_nib_out_file) nib_3d_imgs = [] for dyn_3d_nib_out_file in dyn_3d_nib_out_files: nib_3d_imgs.append(nib.load(dyn_3d_nib_out_file)) if len(nib_3d_imgs) > 1: nib_4d_img = nib.concat_images(nib_3d_imgs) nib_4d_img.to_filename(output_nii_file) else: nib_3d_imgs[0].to_filename(output_nii_file) if os.path.isdir(dyn_3d_nib_in_root): shutil.rmtree(dyn_3d_nib_in_root) if os.path.isdir(dyn_3d_nib_out_root): shutil.rmtree(dyn_3d_nib_out_root) return
def remove_bad_volumes(dwi, bvec_file, bval_file, base_name, thresh): import numpy as np import nibabel as nb import os.path as op from nipype.utils.filemanip import split_filename dwi_4D = nb.load(dwi) dwi_files = nb.four_to_three(dwi_4D) bvecs = np.transpose(np.loadtxt(bvec_file)) bvals = np.transpose(np.loadtxt(bval_file)) bad_indices = np.where(np.abs(bvecs[:,0]) >= thresh)[0] n_removed = len(bad_indices) dwi_files = [i for j, i in enumerate(dwi_files) if j not in bad_indices] bvecs = [i for j, i in enumerate(bvecs) if j not in bad_indices] bvals = [i for j, i in enumerate(bvals) if j not in bad_indices] corr_dwi = nb.concat_images(dwi_files) corr_bvecs = np.transpose(bvecs) corr_bvals = np.transpose(bvals) assert(len(dwi_files) == len(bvecs) == len(bvals)) _, name, _ = split_filename(dwi) out_dwi = op.abspath(base_name + "%f_vib.nii.gz" % thresh) _, bvec_name, _ = split_filename(bvec_file) out_bvecs = op.abspath(base_name + "%f_vib.bvec" % thresh) _, bval_name, _ = split_filename(bval_file) out_bvals = op.abspath(base_name + "%f_vib.bval" % thresh) nb.save(corr_dwi, out_dwi) np.savetxt(out_bvecs, corr_bvecs) np.savetxt(out_bvals, corr_bvals) print("%d volumes were removed at threshold %f" % (n_removed, thresh)) return out_dwi, out_bvecs, out_bvals, n_removed
def remove_bad_volumes(dwi, bvec_file, bval_file, thresh=0.8): import numpy as np import nibabel as nb import os.path as op from nipype.utils.filemanip import split_filename dwi_4D = nb.load(dwi) dwi_files = nb.four_to_three(dwi_4D) bvecs = np.transpose(np.loadtxt(bvec_file)) bvals = np.transpose(np.loadtxt(bval_file)) bad_indices = np.where(np.abs(bvecs[:,0]) >= thresh)[0] n_removed = len(bad_indices) dwi_files = [i for j, i in enumerate(dwi_files) if j not in bad_indices] bvecs = [i for j, i in enumerate(bvecs) if j not in bad_indices] bvals = [i for j, i in enumerate(bvals) if j not in bad_indices] corr_dwi = nb.concat_images(dwi_files) corr_bvecs = np.transpose(bvecs) corr_bvals = np.transpose(bvals) assert(len(dwi_files) == len(bvecs) == len(bvals)) _, name, _ = split_filename(dwi) out_dwi = op.abspath(name + "_vib.nii.gz") _, bvec_name, _ = split_filename(bvec_file) out_bvecs = op.abspath(bvec_name + "_vib.bvec") _, bval_name, _ = split_filename(bval_file) out_bvals = op.abspath(bval_name + "_vib.bval") nb.save(corr_dwi, out_dwi) np.savetxt(out_bvecs, corr_bvecs) np.savetxt(out_bvals, corr_bvals) print("%d volumes were removed at threshold %f" % (n_removed, thresh)) return out_dwi, out_bvecs, out_bvals, n_removed
def smooth_gaussian(self): gaussian_filter = self.gaussian_filter for (input_nii_file, output_nii_file) in zip(self.normalized_nii,self.smoothed_nii): print('run gaussian smooth %s' % (input_nii_file)) print('generate %s' % output_nii_file) if os.path.exists(output_nii_file): continue dir_name = os.path.dirname(output_nii_file) if not os.path.exists(dir_name): os.makedirs(dir_name) nib_img = nib.load(input_nii_file) if len(nib_img.shape) > 3: nib_3d_imgs = nib.four_to_three(nib_img) else: nib_3d_imgs = [nib_img] dyn_3d_nib_files = [] dyn_3d_nib_in_root = tempfile.mkdtemp() for nib_3d_img in nib_3d_imgs: nib_3d_img_file = os.path.join(dyn_3d_nib_in_root, uuid.uuid4().__str__() + '.nii.gz') nib_3d_img.to_filename(nib_3d_img_file) dyn_3d_nib_files.append(nib_3d_img_file) dyn_3d_nib_out_root = tempfile.mkdtemp() dyn_3d_nib_out_files = [] for dyn_3d_nib_file in dyn_3d_nib_files: dyn_3d_nib_out_file = os.path.join(dyn_3d_nib_out_root, uuid.uuid4().__str__() + '.nii.gz') sitk_image_0 = sitk.ReadImage(dyn_3d_nib_file) sitk_image_1 = sitk.SmoothingRecursiveGaussian(sitk_image_0, gaussian_filter) sitk.WriteImage(sitk_image_1, dyn_3d_nib_out_file) dyn_3d_nib_out_files.append(dyn_3d_nib_out_file) nib_3d_imgs = [] for dyn_3d_nib_out_file in dyn_3d_nib_out_files: nib_3d_imgs.append(nib.load(dyn_3d_nib_out_file)) if len(nib_3d_imgs) > 1: nib_4d_img = nib.concat_images(nib_3d_imgs) nib_4d_img.to_filename(output_nii_file) else: nib_3d_imgs[0].to_filename(output_nii_file) if isdir(dyn_3d_nib_in_root): shutil.rmtree(dyn_3d_nib_in_root) if isdir(dyn_3d_nib_out_root): shutil.rmtree(dyn_3d_nib_out_root) return
def test_transform(): # setup output_dir = os.path.join(OUTPUT_DIR, inspect.stack()[0][3]) if not os.path.exists(output_dir): os.makedirs(output_dir) film = nibabel.Nifti1Image(np.random.rand(11, 13, 17, 19), np.eye(4)) threeD_vols = nibabel.four_to_three(film) # filenames film_filename = os.path.join(output_dir, 'film.nii.gz') threeD_vols_filenames = [ os.path.join(output_dir, 'fMETHODS-%06i.nii' % i) for i in range(len(threeD_vols)) ] for stuff in [film, threeD_vols]: for as_files in [False, True]: if as_files: if isinstance(stuff, list): basenames = [ os.path.basename(x) for x in threeD_vols_filenames ] else: basenames = os.path.basename(film_filename) stuff = save_vols(stuff, output_dir, basenames=basenames) fmristc = fMRISTC().fit(raw_data=stuff) output = fmristc.transform(output_dir=output_dir) # test output type, shape, etc. if isinstance(stuff, list): assert isinstance(output, list) assert len(output) == film.shape[-1] if as_files: assert os.path.basename( output[7]) == 'afMETHODS-000007.nii' else: if as_files: assert os.path.basename(output) == 'afilm.nii.gz'
def __init__(self, archivePath, **entities): """ Args: archivePath: Absolute path of the BIDS archive. entities: BIDS entities (subject, session, task, run, suffix, datatype) that define the particular subject/run of the data to stream """ self.bidsArchive = BidsArchive(archivePath) # TODO - when we have BidsRun # self.bidsRun = self.bidsArchive.getBidsRun(**entities) images = self.bidsArchive.getImages(**entities) if len(images) == 0: raise ValidationError('No matching images found') if len(images) > 1: raise ValidationError('More than one match, please give more specific subject/session/task/run') self.bidsImage = images[0] self.niftiImage = self.bidsImage.get_image() self.filename = self.niftiImage.get_filename() self.imgVolumes = nib.four_to_three(self.niftiImage) self.metadata = self.bidsArchive.getSidecarMetadata(self.filename, includeEntities=True) self.metadata.pop('extension') self.numVolumes = len(self.imgVolumes) self.nextVol = 0
def _make_sd(func_filenames=None, anat_filename=None, ext=".nii.gz", n_sessions=1, make_sess_dirs=False, unique_func_names=False, output_dir="/tmp/titi"): if not func_filenames is None: n_sessions = len(func_filenames) func = [create_random_image(ndim=4) for _ in xrange(n_sessions)] anat = create_random_image(ndim=3) if anat_filename is None: anat_filename = '%s/anat%s' % (DATA_DIR, ext) _save_img(anat, anat_filename) if not func_filenames is None: for sess_func, filename in zip(func, func_filenames): if isinstance(filename, basestring): _save_img(sess_func, filename) else: vols = nibabel.four_to_three(sess_func) for x, y in zip(vols, filename): assert isinstance(y, basestring), type(y) _save_img(x, y) else: func_filenames = [] for sess in xrange(n_sessions): sess_dir = DATA_DIR if not make_sess_dirs else os.path.join( DATA_DIR, "session%i" % sess) if not os.path.exists(sess_dir): os.makedirs(sess_dir) func_filename = '%s/func%s%s' % ( sess_dir, "_sess_%i_" % sess if ( n_sessions > 1 and unique_func_names) else "", ext) _save_img(func[sess], func_filename) func_filenames.append(func_filename) sd = SubjectData(anat=anat_filename, func=func_filenames, output_dir=output_dir) return sd
def b0_average(in_file, out_file=None): """ Average the b0 volumes. Args: in_file (str): The b0 volumes already registered. out_file (optional[str]): Name of the file. Returns: The mean of the b0 volumes. Warnings: The b0 volumes must be registered. """ import os.path as op import nibabel as nb import numpy as np if out_file is None: fname, ext = op.splitext(op.basename(in_file)) if ext == ".gz": fname, ext2 = op.splitext(fname) ext = ext2 + ext out_file = op.abspath("%s_avg_b0%s" % (fname, ext)) imgs = np.array(nb.four_to_three(nb.load(in_file))) b0s = [im.get_data().astype(np.float32) for im in imgs] b0 = np.average(np.array(b0s), axis=0) hdr = imgs[0].get_header().copy() hdr.set_data_shape(b0.shape) hdr.set_xyzt_units("mm") hdr.set_data_dtype(np.float32) nb.Nifti1Image(b0, imgs[0].get_affine(), hdr).to_filename(out_file) return out_file
def _run_interface(self, runtime): nii_list = [] for f in self.inputs.in_files: filenii = nb.squeeze_image(nb.load(f)) ndim = filenii.dataobj.ndim if ndim == 3: nii_list.append(filenii) continue elif self.inputs.allow_4D and ndim == 4: nii_list += nb.four_to_three(filenii) continue else: raise ValueError( "Input image has an incorrect number of dimensions" f" ({ndim}).") img_4d = nb.concat_images(nii_list) out_file = fname_presuffix(self.inputs.in_files[0], suffix="_merged", newpath=runtime.cwd) img_4d.to_filename(out_file) self._results["out_file"] = out_file return runtime
def time_avg(in_file, index=[0], out_file=None): """ Average the input time-series, selecting the indices given in index .. warning:: time steps should be already registered (corrected for head motion artifacts). """ import numpy as np import nibabel as nb import os.path as op from nipype.utils import NUMPY_MMAP if out_file is None: fname, ext = op.splitext(op.basename(in_file)) if ext == ".gz": fname, ext2 = op.splitext(fname) ext = ext2 + ext out_file = op.abspath("%s_baseline%s" % (fname, ext)) index = np.atleast_1d(index).tolist() imgs = np.array(nb.four_to_three(nb.load(in_file, mmap=NUMPY_MMAP)))[index] if len(index) == 1: data = imgs[0].get_data().astype(np.float32) else: data = np.average(np.array( [im.get_data().astype(np.float32) for im in imgs]), axis=0) hdr = imgs[0].header.copy() hdr.set_data_shape(data.shape) hdr.set_xyzt_units('mm') hdr.set_data_dtype(np.float32) nb.Nifti1Image(data, imgs[0].affine, hdr).to_filename(out_file) return out_file
def b0_average(in_dwi, in_bval, max_b=10.0, out_file=None): """ A function that averages the *b0* volumes from a DWI dataset. As current dMRI data are being acquired with all b-values > 0.0, the *lowb* volumes are selected by specifying the parameter max_b. .. warning:: *b0* should be already registered (head motion artifact should be corrected). """ import numpy as np import nibabel as nb import os.path as op from nipype.utils import NUMPY_MMAP if out_file is None: fname, ext = op.splitext(op.basename(in_dwi)) if ext == ".gz": fname, ext2 = op.splitext(fname) ext = ext2 + ext out_file = op.abspath("%s_avg_b0%s" % (fname, ext)) imgs = np.array(nb.four_to_three(nb.load(in_dwi, mmap=NUMPY_MMAP))) bval = np.loadtxt(in_bval) index = np.argwhere(bval <= max_b).flatten().tolist() b0s = [im.get_data().astype(np.float32) for im in imgs[index]] b0 = np.average(np.array(b0s), axis=0) hdr = imgs[0].header.copy() hdr.set_data_shape(b0.shape) hdr.set_xyzt_units('mm') hdr.set_data_dtype(np.float32) nb.Nifti1Image(b0, imgs[0].affine, hdr).to_filename(out_file) return out_file
def test_load_4D_img(): # setup output_dir = os.path.join(OUTPUT_DIR, inspect.stack()[0][3]) if not os.path.exists(output_dir): os.makedirs(output_dir) # try loading from 4D niimg film = create_random_image(n_scans=10) loaded_4D_img = load_4D_img(film) assert_true(is_niimg(loaded_4D_img)) assert_equal(loaded_4D_img.shape, film.shape) # try loading from 4D image file film = create_random_image(n_scans=10) saved_img_filename = os.path.join(output_dir, "4D.nii.gz") nibabel.save(film, saved_img_filename) loaded_4D_img = load_4D_img(saved_img_filename) assert_true(is_niimg(loaded_4D_img)) assert_equal(loaded_4D_img.shape, film.shape) # try loading from list of 3D niimgs film = create_random_image(n_scans=10) loaded_4D_img = load_4D_img(nibabel.four_to_three(film)) assert_true(is_niimg(loaded_4D_img)) assert_equal(loaded_4D_img.shape, film.shape) # try loading from list of 3D image files film = create_random_image(n_scans=10) saved_vols_filenames = save_vols( film, output_dir, ext='.nii.gz', ) loaded_4D_img = load_4D_img(saved_vols_filenames) assert_true(is_niimg(loaded_4D_img)) assert_equal(loaded_4D_img.shape, film.shape)
def _run_interface(self, runtime): iflogger.info( 'Segmentation image: {img}'.format(img=self.inputs.segmentation_file)) rois = get_roi_list(self.inputs.segmentation_file) number_of_nodes = len(rois) iflogger.info('Found {roi} unique region values'.format(roi=len(rois))) if len(self.inputs.in_files) > 1: iflogger.info('Multiple input images detected') iflogger.info(len(self.inputs.in_files)) in_files = self.inputs.in_files try: # VERY tempermental solution to sorting the functional images. # RELIES ON xyz-01_out.nii from recent resampling. in_files = sorted(in_files, key=lambda x: int(x.split("_")[-2].split("-")[-2])) except IndexError: # Tempermental solution to sorting the functional images. # RELIES ON xyz_out.nii from recent resampling. in_files = sorted(in_files, key=lambda x: int(x.split("_")[-2])) elif isdefined(self.inputs.in_file4d): iflogger.info('Single four-dimensional image selected') in_file4d = nb.load(self.inputs.in_file4d) in_files = nb.four_to_three(in_file4d) else: iflogger.info('Single functional image provided') in_files = self.inputs.in_files rois = get_roi_list(self.inputs.segmentation_file) fMRI_timecourse, _, _, _, _ = get_timecourse_by_region( in_files, self.inputs.segmentation_file, rois) timecourse_at_each_node = fMRI_timecourse.T time_course_image = nb.load(self.inputs.time_course_file) iflogger.info(np.shape(timecourse_at_each_node)) number_of_components = 30 number_of_images = 198 time_course_data = time_course_image.get_data() onerow = np.ones(number_of_images) time_course_per_IC = np.vstack((onerow.T, time_course_data.T)).T iflogger.info(np.shape(time_course_per_IC)) y = timecourse_at_each_node X = time_course_per_IC n = number_of_images XTX_inv = np.linalg.inv(np.dot(X.T, X)) N = number_of_components + 1 contrast = np.concatenate( (np.zeros((1, number_of_components)), np.eye(number_of_components))).T a = np.empty((number_of_nodes, N)) residues = np.empty((number_of_nodes, 1)) rank = np.empty((number_of_nodes, 1)) singularvalues = np.empty((number_of_nodes, N)) resids = np.empty((number_of_nodes, number_of_images)) error_variance = np.empty((number_of_nodes, 1)) t_values = np.empty((number_of_nodes, number_of_components)) beta_value = np.empty((number_of_components, 1)) for node_idx, node in enumerate(rois): a[node_idx], residues[node_idx], rank[node_idx], singularvalues[ node_idx] = np.linalg.lstsq(X, y[:, node_idx]) resids[node_idx, :] = y[:, node_idx] - \ np.dot(X, a[node_idx]) # e = y - Xa; error_variance[node_idx] = np.var(resids[node_idx]) for IC in range(0, number_of_components): t_values[node_idx, IC] = np.dot(contrast[IC], a[node_idx]) / \ np.sqrt( error_variance[node_idx] * np.dot(np.dot(contrast[IC], XTX_inv), contrast[IC, :].T)) beta_value[IC] = np.dot(contrast[IC], a[node_idx]) t_value_dict = {} t_value_dict['t_value_per_node'] = t_values t_value_dict['timecourse_at_each_node'] = y t_value_dict['timecourse_per_IC'] = X t_value_dict['number_of_images'] = n t_value_dict['a'] = a t_value_dict['contrast'] = contrast t_value_dict['residuals'] = resids t_value_dict['error_variance'] = error_variance out_file = op.abspath(self.inputs.out_t_value_threshold_file) iflogger.info( 'Saving T-values per node, per IC, as {file}'.format(file=out_file)) sio.savemat(out_file, t_value_dict) return runtime
def nonlinfit_fn(dwi, bvecs, bvals, base_name): import nibabel as nb import numpy as np import os.path as op import dipy.reconst.dti as dti from dipy.core.gradients import GradientTable dwi_img = nb.load(dwi) dwi_data = dwi_img.get_data() dwi_affine = dwi_img.get_affine() from dipy.segment.mask import median_otsu b0_mask, mask = median_otsu(dwi_data, 2, 4) # Mask the data so that tensors are not fit for # unnecessary voxels mask_img = nb.Nifti1Image(mask.astype(np.float32), dwi_affine) b0_imgs = nb.Nifti1Image(b0_mask.astype(np.float32), dwi_affine) b0_img = nb.four_to_three(b0_imgs)[0] out_mask_name = op.abspath(base_name + '_binary_mask.nii.gz') out_b0_name = op.abspath(base_name + '_b0_mask.nii.gz') nb.save(mask_img, out_mask_name) nb.save(b0_img, out_b0_name) # Load the gradient strengths and directions bvals = np.loadtxt(bvals) gradients = np.loadtxt(bvecs) # Dipy wants Nx3 arrays if gradients.shape[0] == 3: gradients = gradients.T assert(gradients.shape[1] == 3) # Place in Dipy's preferred format gtab = GradientTable(gradients) gtab.bvals = bvals # Fit the tensors to the data tenmodel = dti.TensorModel(gtab, fit_method="NLLS") tenfit = tenmodel.fit(dwi_data, mask) # Calculate the fit, fa, and md of each voxel's tensor tensor_data = tenfit.lower_triangular() print('Computing anisotropy measures (FA, MD, RGB)') from dipy.reconst.dti import fractional_anisotropy, color_fa evals = tenfit.evals.astype(np.float32) FA = fractional_anisotropy(np.abs(evals)) FA = np.clip(FA, 0, 1) MD = dti.mean_diffusivity(np.abs(evals)) norm = dti.norm(tenfit.quadratic_form) RGB = color_fa(FA, tenfit.evecs) evecs = tenfit.evecs.astype(np.float32) mode = tenfit.mode.astype(np.float32) mode = np.nan_to_num(mode) # Write tensor as a 4D Nifti image with the original affine tensor_fit_img = nb.Nifti1Image(tensor_data.astype(np.float32), dwi_affine) mode_img = nb.Nifti1Image(mode.astype(np.float32), dwi_affine) norm_img = nb.Nifti1Image(norm.astype(np.float32), dwi_affine) FA_img = nb.Nifti1Image(FA.astype(np.float32), dwi_affine) evecs_img = nb.Nifti1Image(evecs, dwi_affine) evals_img = nb.Nifti1Image(evals, dwi_affine) rgb_img = nb.Nifti1Image(np.array(255 * RGB, 'uint8'), dwi_affine) MD_img = nb.Nifti1Image(MD.astype(np.float32), dwi_affine) out_tensor_file = op.abspath(base_name + "_tensor.nii.gz") out_mode_file = op.abspath(base_name + "_mode.nii.gz") out_fa_file = op.abspath(base_name + "_fa.nii.gz") out_norm_file = op.abspath(base_name + "_norm.nii.gz") out_evals_file = op.abspath(base_name + "_evals.nii.gz") out_evecs_file = op.abspath(base_name + "_evecs.nii.gz") out_rgb_fa_file = op.abspath(base_name + "_rgb_fa.nii.gz") out_md_file = op.abspath(base_name + "_md.nii.gz") nb.save(rgb_img, out_rgb_fa_file) nb.save(norm_img, out_norm_file) nb.save(mode_img, out_mode_file) nb.save(tensor_fit_img, out_tensor_file) nb.save(evecs_img, out_evecs_file) nb.save(evals_img, out_evals_file) nb.save(FA_img, out_fa_file) nb.save(MD_img, out_md_file) print('Tensor fit image saved as {i}'.format(i=out_tensor_file)) print('FA image saved as {i}'.format(i=out_fa_file)) print('MD image saved as {i}'.format(i=out_md_file)) return out_tensor_file, out_fa_file, out_md_file, \ out_evecs_file, out_evals_file, out_rgb_fa_file, out_norm_file, \ out_mode_file, out_mask_name, out_b0_name
def _run_interface(self, runtime): from dipy.core.gradients import GradientTable from dipy.reconst.dti import fractional_anisotropy, mean_diffusivity from dipy.reconst.csdeconv import recursive_response, auto_response img = nb.load(self.inputs.in_file) imref = nb.four_to_three(img)[0] affine = img.affine if isdefined(self.inputs.in_mask): msk = nb.load(self.inputs.in_mask).get_data() msk[msk > 0] = 1 msk[msk < 0] = 0 else: msk = np.ones(imref.shape) data = img.get_data().astype(np.float32) gtab = self._get_gradient_table() evals = np.nan_to_num(nb.load(self.inputs.in_evals).get_data()) FA = np.nan_to_num(fractional_anisotropy(evals)) * msk indices = np.where(FA > self.inputs.fa_thresh) S0s = data[indices][:, np.nonzero(gtab.b0s_mask)[0]] S0 = np.mean(S0s) if self.inputs.auto: response, ratio = auto_response(gtab, data, roi_radius=self.inputs.roi_radius, fa_thr=self.inputs.fa_thresh) response = response[0].tolist() + [S0] elif self.inputs.recursive: MD = np.nan_to_num(mean_diffusivity(evals)) * msk indices = np.logical_or(FA >= 0.4, (np.logical_and(FA >= 0.15, MD >= 0.0011))) data = nb.load(self.inputs.in_file).get_data() response = recursive_response(gtab, data, mask=indices, sh_order=8, peak_thr=0.01, init_fa=0.08, init_trace=0.0021, iter=8, convergence=0.001, parallel=True) ratio = abs(response[1] / response[0]) else: lambdas = evals[indices] l01 = np.sort(np.mean(lambdas, axis=0)) response = np.array([l01[-1], l01[-2], l01[-2], S0]) ratio = abs(response[1] / response[0]) if ratio > 0.25: IFLOGGER.warn( 'Estimated response is not prolate enough. ' 'Ratio=%0.3f.', ratio) elif ratio < 1.e-5 or np.any(np.isnan(response)): response = np.array([1.8e-3, 3.6e-4, 3.6e-4, S0]) IFLOGGER.warn( 'Estimated response is not valid, using a default one') else: IFLOGGER.info('Estimated response: %s', str(response[:3])) np.savetxt(op.abspath(self.inputs.response), response) wm_mask = np.zeros_like(FA) wm_mask[indices] = 1 nb.Nifti1Image(wm_mask.astype(np.uint8), affine, None).to_filename(op.abspath(self.inputs.out_mask)) 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] if self.inputs.to_ras: in_files = [reorient(inf, newpath=runtime.cwd) for inf in in_files] run_hmc = self.inputs.hmc and len(in_files) > 1 nii_list = [] # Remove one-sized extra dimensions for i, f in enumerate(in_files): filenii = nb.load(f) filenii = nb.squeeze_image(filenii) if len(filenii.shape) == 5: raise RuntimeError("Input image (%s) is 5D." % f) if filenii.dataobj.ndim == 4: nii_list += nb.four_to_three(filenii) else: nii_list.append(filenii) if len(nii_list) > 1: filenii = nb.concat_images(nii_list) else: filenii = nii_list[0] merged_fname = fname_presuffix(self.inputs.in_files[0], suffix="_merged", newpath=runtime.cwd) filenii.to_filename(merged_fname) self._results["out_file"] = merged_fname self._results["out_avg"] = merged_fname if filenii.dataobj.ndim < 4: # TODO: generate identity out_mats and zero-filled out_movpar return runtime if run_hmc: mcflirt = fsl.MCFLIRT( cost="normcorr", save_mats=True, save_plots=True, ref_vol=0, in_file=merged_fname, ) mcres = mcflirt.run() filenii = nb.load(mcres.outputs.out_file) self._results["out_file"] = mcres.outputs.out_file self._results["out_mats"] = mcres.outputs.mat_file self._results["out_movpar"] = mcres.outputs.par_file hmcdata = filenii.get_fdata(dtype="float32") if self.inputs.grand_mean_scaling: if not isdefined(self.inputs.in_mask): mean = np.median(hmcdata, axis=-1) thres = np.percentile(mean, 25) mask = mean > thres else: mask = nb.load( self.inputs.in_mask).get_fdata(dtype="float32") > 0.5 nimgs = hmcdata.shape[-1] means = np.median(hmcdata[mask[..., np.newaxis]].reshape( (-1, nimgs)).T, axis=-1) max_mean = means.max() for i in range(nimgs): hmcdata[..., i] *= max_mean / means[i] hmcdata = hmcdata.mean(axis=3) if self.inputs.zero_based_avg: hmcdata -= hmcdata.min() self._results["out_avg"] = fname_presuffix(self.inputs.in_files[0], suffix="_avg", newpath=runtime.cwd) nb.Nifti1Image(hmcdata, filenii.affine, filenii.header).to_filename(self._results["out_avg"]) return runtime
def _run_interface(self, runtime): from dipy.reconst.peaks import peaks_from_model from dipy.tracking.eudx import EuDX from dipy.data import get_sphere # import marshal as pickle import pickle as pickle import gzip if (not (isdefined(self.inputs.in_model) or isdefined(self.inputs.in_peaks))): raise RuntimeError(('At least one of in_model or in_peaks should ' 'be supplied')) img = nb.load(self.inputs.in_file) imref = nb.four_to_three(img)[0] affine = img.affine data = img.get_data().astype(np.float32) hdr = imref.header.copy() hdr.set_data_dtype(np.float32) hdr['data_type'] = 16 sphere = get_sphere('symmetric724') self._save_peaks = False if isdefined(self.inputs.in_peaks): IFLOGGER.info('Peaks file found, skipping ODF peaks search...') f = gzip.open(self.inputs.in_peaks, 'rb') peaks = pickle.load(f) f.close() else: self._save_peaks = True IFLOGGER.info('Loading model and computing ODF peaks') f = gzip.open(self.inputs.in_model, 'rb') odf_model = pickle.load(f) f.close() peaks = peaks_from_model( model=odf_model, data=data, sphere=sphere, relative_peak_threshold=self.inputs.peak_threshold, min_separation_angle=self.inputs.min_angle, parallel=self.inputs.multiprocess) f = gzip.open(self._gen_filename('peaks', ext='.pklz'), 'wb') pickle.dump(peaks, f, -1) f.close() hdr.set_data_shape(peaks.gfa.shape) nb.Nifti1Image(peaks.gfa.astype(np.float32), affine, hdr).to_filename(self._gen_filename('gfa')) IFLOGGER.info('Performing tractography') if isdefined(self.inputs.tracking_mask): msk = nb.load(self.inputs.tracking_mask).get_data() msk[msk > 0] = 1 msk[msk < 0] = 0 else: msk = np.ones(imref.shape) gfa = peaks.gfa * msk seeds = self.inputs.num_seeds if isdefined(self.inputs.seed_coord): seeds = np.loadtxt(self.inputs.seed_coord) elif isdefined(self.inputs.seed_mask): seedmsk = nb.load(self.inputs.seed_mask).get_data() assert (seedmsk.shape == data.shape[:3]) seedmsk[seedmsk > 0] = 1 seedmsk[seedmsk < 1] = 0 seedps = np.array(np.where(seedmsk == 1), dtype=np.float32).T vseeds = seedps.shape[0] nsperv = (seeds // vseeds) + 1 IFLOGGER.info( 'Seed mask is provided (%d voxels inside ' 'mask), computing seeds (%d seeds/voxel).', vseeds, nsperv) if nsperv > 1: IFLOGGER.info('Needed %d seeds per selected voxel (total %d).', nsperv, vseeds) seedps = np.vstack(np.array([seedps] * nsperv)) voxcoord = seedps + np.random.uniform(-1, 1, size=seedps.shape) nseeds = voxcoord.shape[0] seeds = affine.dot( np.vstack((voxcoord.T, np.ones((1, nseeds)))))[:3, :].T if self.inputs.save_seeds: np.savetxt(self._gen_filename('seeds', ext='.txt'), seeds) if isdefined(self.inputs.tracking_mask): tmask = msk a_low = 0.1 else: tmask = gfa a_low = self.inputs.gfa_thresh eu = EuDX(tmask, peaks.peak_indices[..., 0], seeds=seeds, affine=affine, odf_vertices=sphere.vertices, a_low=a_low) ss_mm = [np.array(s) for s in eu] trkfilev = nb.trackvis.TrackvisFile([(s, None, None) for s in ss_mm], points_space='rasmm', affine=np.eye(4)) trkfilev.to_file(self._gen_filename('tracked', ext='.trk')) return runtime
def _run_interface(self, runtime): # Determine the parameters experiment = self.inputs.experiment subject, session, run = self.inputs.run self._results["run_tuple"] = self.inputs.run self._results["subject"] = subject self._results["session"] = session self._results["run"] = run # Spec out paths to the input files keys = dict(subject=subject, experiment=experiment, session=session, run=run) sb_fname = op.join(self.inputs.data_dir, subject, "func", self.inputs.sb_template.format(**keys)) ts_fname = op.join(self.inputs.data_dir, subject, "func", self.inputs.ts_template.format(**keys)) # Load the input images in canonical orientation sb_img = nib.as_closest_canonical(nib.load(sb_fname)) ts_img = nib.as_closest_canonical(nib.load(ts_fname)) # Convert image datatypes to float sb_img.set_data_dtype(np.float32) ts_img.set_data_dtype(np.float32) # Optionally crop the first n frames of the timeseries if self.inputs.crop_frames > 0: ts_data = ts_img.get_data() ts_data = ts_data[..., self.inputs.crop_frames:] ts_img = nib.Nifti1Image(ts_data, ts_img.affine, ts_img.header) # Write out the new images self.write_image("sb_file", "sb.nii.gz", sb_img) self.write_image("ts_file", "ts.nii.gz", ts_img) # Write out each frame of the timeseries os.mkdir("frames") ts_frames = [] ts_frame_imgs = nib.four_to_three(ts_img) for i, frame_img in enumerate(ts_frame_imgs): frame_fname = op.abspath("frames/frame{:04d}.nii.gz".format(i)) ts_frames.append(frame_fname) frame_img.to_filename(frame_fname) self._results["ts_frames"] = ts_frames # Make a GIF movie of the raw timeseries out_plot = self.define_output("ts_plot", "raw.gif") self.write_time_series_gif(runtime, ts_img, out_plot) # Load files from the template directory template_path = op.join(self.inputs.proc_dir, subject, "template") results = dict( reg_file=op.join(template_path, "anat2func.mat"), seg_file=op.join(template_path, "seg.nii.gz"), anat_file=op.join(template_path, "anat.nii.gz"), mask_file=op.join(template_path, "mask.nii.gz"), ) self._results.update(results) return runtime
def _save_2_pet_suv_bqml(self, series_dicom_root, sub_root, sub_name='sub-001', func_name='pet', task_name='rest'): # find udcm2bids tags and calc convert factor func_root = os.path.join(sub_root, func_name) bqml_nii_file = os.path.join( func_root, sub_name + '_task-' + task_name + '_PET-BQML.nii.gz') suvbw_nii_file = bqml_nii_file.replace('_PET-BQML', '_PET-SUVbw') suvbw_json_file = suvbw_nii_file.replace('.nii.gz', '.json') if os.path.exists(suvbw_nii_file): return suv_factor = [] acqdatetime = [] dicom_files = glob(os.path.join(series_dicom_root, '*.dcm')) for i, file in enumerate(dicom_files): ds = pydicom.read_file(file, stop_before_pixels=False) dt = str(ds.AcquisitionDateTime)[:14] if dt not in acqdatetime: acqdatetime.append(dt) suv_factor.append(self._calc_uih_pet_suvbw_factor(ds)) # convert to bids if not os.path.isdir(func_root): os.mkdir(func_root) # check whether exist or not if not os.path.exists(bqml_nii_file): devnull = open(os.devnull, 'w') subprocess.call([ 'dcm2niix', '-b', 'y', '-z', 'y', '-f', sub_name + '_task-' + task_name + '_PET-BQML', '-o', func_root, series_dicom_root ], stdout=devnull, stderr=subprocess.STDOUT) # convert bqml to suv_bw with suv_factor nib_img_bqml = nib.load(bqml_nii_file) if len(suv_factor) > 1: nib_3d_imgs_bqml = nib.four_to_three(nib_img_bqml) np_3d_imgs_bqml = [ nib_3d_img_bqml.get_data() for nib_3d_img_bqml in nib_3d_imgs_bqml ] affines = [ nib_3d_img_bqml.affine for nib_3d_img_bqml in nib_3d_imgs_bqml ] np_3d_imgs_suvbw = [ np_3d_img * c_factor for np_3d_img, c_factor in zip(np_3d_imgs_bqml, suv_factor) ] nib_3d_imgs_suvbw = [ nib.Nifti1Image(new_np_3d_img, affine) for new_np_3d_img, affine in zip(np_3d_imgs_suvbw, affines) ] nib_img_suvbw = nib.concat_images(nib_3d_imgs_suvbw) nib_img_suvbw.to_filename(suvbw_nii_file) else: nib_3d_img_bqml = nib_img_bqml np_3d_img_bqml = nib_3d_img_bqml.get_data() affine = nib_3d_img_bqml.affine np_3d_img_suvbw = np_3d_img_bqml * suv_factor[0] nib_3d_img_suvbw = nib.Nifti1Image(np_3d_img_suvbw, affine) nib_3d_img_suvbw.to_filename(suvbw_nii_file) with open(suvbw_json_file, 'wt', encoding='utf-8') as f_json: json.dump( { 'suvbw_factor': suv_factor, 'acquisition_time': acqdatetime }, f_json, indent=4) return
def _run_interface(self, runtime): # Load the 4D raw fieldmap image and select first frame raw_img_frames = nib.load(self.inputs.raw_file) raw_img = nib.four_to_three(raw_img_frames)[0] affine, header = raw_img.affine, raw_img.header # Write out the raw image to serve as a registration target self.write_image("raw_file", "raw.nii.gz", raw_img) # Load the 4D jacobian image jac_img_frames = nib.concat_images(self.inputs.jacobian_files) jac_data = jac_img_frames.get_data() # Load the 4D corrected fieldmap image corr_img_frames = nib.load(self.inputs.corrected_file) corr_data = corr_img_frames.get_data() # Jacobian modulate the corrected image corr_mod_data = corr_data * jac_data corr_img_frames = nib.Nifti1Image(corr_mod_data, affine, header) # Average the corrected image over the final dimension and write corr_mod_data = corr_mod_data.mean(axis=-1) self.write_image("corrected_file", "func.nii.gz", corr_mod_data, affine, header) # Save the jacobian images using the raw geometry self.write_image("jacobian_file", "jacobian.nii.gz", jac_data, affine, header) # Select the first warpfield image # We combine the two fieldmap images so that the first one has # a phase encoding that matches the time series data. # Also note that when the fieldmap images have multiple frames, # the warps corresponding to those frames are identical. warp_file = self.inputs.warp_files[0] # Load in the the warp file and save out with the correct affine # (topup doesn't save the header geometry correctly for some reason) warp_data = nib.load(warp_file).get_data() self.write_image("warp_file", "warp.nii.gz", warp_data, affine, header) # Select the warp along the phase encode direction # Note: we elsewhere currently require phase encoding to be AP or PA # so because the input node transforms the fieldmap to canonical # orientation this will work. But in the future we might want to ne # more flexible with what we accept and will need to change this. warp_data_y = warp_data[..., 1] # Write out a mask to exclude voxels with large distortions/dropout mask_data = (np.abs(warp_data_y) < 4).astype(np.int) self.write_image("mask_file", "warp_mask.nii.gz", mask_data, affine, header) # Generate a QC image of the warpfield m = Mosaic(raw_img, warp_data_y) m.plot_overlay("coolwarm", vmin=-6, vmax=6, alpha=.75) self.write_visualization("warp_plot", "warp.png", m) # Generate a QC gif of the unwarping performance self.generate_unwarp_gif(runtime, raw_img_frames, corr_img_frames) return runtime
def save_vols(vols, output_dir, basenames=None, affine=None, concat=False, prefix='', ext=None): """ Saves a single 4D image or a couple of 3D vols unto disk. vols: single 4D nibabel image object, or list of 3D nibabel image objects volumes, of ndarray volumes to be saved output_dir: string existing filename, destination directory basenames: string or list of string, optional (default None) basename(s) for output image(s) affine: 2D array of shape (4, 4) affine matrix for the output images concat: bool, optional (default False) concatenate all vols into a single film prefix: string, optional (default '') prefix to be prepended to output file basenames ext: string, optional (default ".nii.gz") file extension for output images Returns ------- string of list of strings, dependending on whether vols is list or not, and on whether concat is set or not the output image filename(s) """ def _nifti_or_ndarray_to_nifti(x): if is_niimg(x): if not affine is None: raise ValueError( ("vol is of type %s; not expecting `affine` parameter." ) % type(x)) else: return x if affine is None: raise ValueError( "vol is of type ndarray; you need to specifiy `affine`") else: return nibabel.Nifti1Image(x, affine) if not basenames is None: basenames = get_basenames(basenames, ext=ext) # sanitize output_dir if not os.path.exists(output_dir): os.makedirs(output_dir) # vols are ndarray ? if isinstance(vols, np.ndarray): vols = _nifti_or_ndarray_to_nifti(vols) # concat vols to single 4D film ? if concat: if isinstance(vols, list): vols = nibabel.concat_images([_nifti_or_ndarray_to_nifti(vol) for vol in vols], check_affines=False ) if not basenames is None: if not isinstance(basenames, basestring): basenames = basenames[0] else: if not basenames is None: if not isinstance(basenames, basestring): raise RuntimeError( ("concat=True specified but basenames is of type %s " "instead of string") % type(basenames)) if not isinstance(vols, list): if basenames is None: basenames = get_basenames("vols", ext=ext) if not isinstance(basenames, basestring): vols = nibabel.four_to_three(vols) filenames = [] for vol, basename in zip(vols, basenames): assert isinstance(basename, basestring) filename = os.path.join(output_dir, "%s%s" % ( prefix, basename)) nibabel.save(vol, filename) filenames.append(filename) else: filenames = os.path.join(output_dir, "%s%s" % ( prefix, basenames)) nibabel.save(vols, filenames) return filenames else: n_vols = len(vols) filenames = [] if basenames is None: if prefix: prefix = prefix + "_" else: if isinstance(basenames, basestring): basenames = ["vol%i_%s" % (t, basenames) for t in xrange(len(vols))] else: assert len(set(basenames)) == len(vols), basenames for t, vol in zip(xrange(n_vols), vols): if isinstance(vol, np.ndarray): if affine is None: raise ValueError( ("vols is of type ndarray; you need to specifiy" " `affine`")) else: vol = nibabel.Nifti1Image(vol, affine) # save realigned vol unto disk if basenames is None: if ext is None: ext = ".nii.gz" output_filename = os.path.join(output_dir, get_basename("%svol_%i" % ( prefix, t), ext=ext)) else: basename = basenames if isinstance( basenames, basestring) else basenames[t] output_filename = os.path.join(output_dir, get_basenames("%s%s" % ( prefix, basename), ext=ext)) vol = load_vol(vol) if not is_niimg(vol) else vol nibabel.save(vol, output_filename) # update rvols and filenames filenames.append(output_filename) return filenames
def _run_interface(self, runtime): from dipy.reconst.peaks import peaks_from_model from dipy.tracking.eudx import EuDX from dipy.data import get_sphere # import marshal as pickle import pickle as pickle import gzip if (not (isdefined(self.inputs.in_model) or isdefined(self.inputs.in_peaks))): raise RuntimeError(('At least one of in_model or in_peaks should ' 'be supplied')) img = nb.load(self.inputs.in_file) imref = nb.four_to_three(img)[0] affine = img.affine data = img.get_data().astype(np.float32) hdr = imref.header.copy() hdr.set_data_dtype(np.float32) hdr['data_type'] = 16 sphere = get_sphere('symmetric724') self._save_peaks = False if isdefined(self.inputs.in_peaks): IFLOGGER.info('Peaks file found, skipping ODF peaks search...') f = gzip.open(self.inputs.in_peaks, 'rb') peaks = pickle.load(f) f.close() else: self._save_peaks = True IFLOGGER.info('Loading model and computing ODF peaks') f = gzip.open(self.inputs.in_model, 'rb') odf_model = pickle.load(f) f.close() peaks = peaks_from_model( model=odf_model, data=data, sphere=sphere, relative_peak_threshold=self.inputs.peak_threshold, min_separation_angle=self.inputs.min_angle, parallel=self.inputs.multiprocess) f = gzip.open(self._gen_filename('peaks', ext='.pklz'), 'wb') pickle.dump(peaks, f, -1) f.close() hdr.set_data_shape(peaks.gfa.shape) nb.Nifti1Image(peaks.gfa.astype(np.float32), affine, hdr).to_filename( self._gen_filename('gfa')) IFLOGGER.info('Performing tractography') if isdefined(self.inputs.tracking_mask): msk = nb.load(self.inputs.tracking_mask).get_data() msk[msk > 0] = 1 msk[msk < 0] = 0 else: msk = np.ones(imref.shape) gfa = peaks.gfa * msk seeds = self.inputs.num_seeds if isdefined(self.inputs.seed_coord): seeds = np.loadtxt(self.inputs.seed_coord) elif isdefined(self.inputs.seed_mask): seedmsk = nb.load(self.inputs.seed_mask).get_data() assert (seedmsk.shape == data.shape[:3]) seedmsk[seedmsk > 0] = 1 seedmsk[seedmsk < 1] = 0 seedps = np.array(np.where(seedmsk == 1), dtype=np.float32).T vseeds = seedps.shape[0] nsperv = (seeds // vseeds) + 1 IFLOGGER.info('Seed mask is provided (%d voxels inside ' 'mask), computing seeds (%d seeds/voxel).', vseeds, nsperv) if nsperv > 1: IFLOGGER.info('Needed %d seeds per selected voxel (total %d).', nsperv, vseeds) seedps = np.vstack(np.array([seedps] * nsperv)) voxcoord = seedps + np.random.uniform(-1, 1, size=seedps.shape) nseeds = voxcoord.shape[0] seeds = affine.dot( np.vstack((voxcoord.T, np.ones((1, nseeds)))))[:3, :].T if self.inputs.save_seeds: np.savetxt(self._gen_filename('seeds', ext='.txt'), seeds) if isdefined(self.inputs.tracking_mask): tmask = msk a_low = 0.1 else: tmask = gfa a_low = self.inputs.gfa_thresh eu = EuDX( tmask, peaks.peak_indices[..., 0], seeds=seeds, affine=affine, odf_vertices=sphere.vertices, a_low=a_low) ss_mm = [np.array(s) for s in eu] trkfilev = nb.trackvis.TrackvisFile( [(s, None, None) for s in ss_mm], points_space='rasmm', affine=np.eye(4)) trkfilev.to_file(self._gen_filename('tracked', ext='.trk')) return runtime
print('') print("Shape of permutation data:") for s in range(nsubj): print(dat[s].shape) print('') end = timer() print("Data loaded: {seconds:.4f} seconds".format(seconds=end-start)) middle = timer() if args.mask: try: mask_img = nib.four_to_three(nib.load(args.mask))[0] except ValueError: mask_img = nib.load(args.mask) mask_data = mask_img.get_data() # If it is a probability map of tissue types, this says treat all voxels # that have a probability 0.2 or higher of being grey matter. # 0.2 is based on John Ashburner's VBM tutorial (VBMclass15.pdf) and Kurth, # Gaser, and Luders (2015, Nature Protocols) print("Masking reference data ...") try: mask = (mask_data > 0.2) * automask except: print("Dimension mismatch between mask and data! Resampling the mask and trying again ...") rmask = nib.processing.resample_from_to(mask_img, reference_img) mask_data = rmask.get_data()
def _run_interface(self, runtime): if len(self.inputs.in_files) > 1: iflogger.info('Multiple input images detected') iflogger.info(len(self.inputs.in_files)) in_files = self.inputs.in_files elif isdefined(self.inputs.in_file4d): iflogger.info('Single four-dimensional image selected') in_file4d = nb.load(self.inputs.in_file4d) in_files = nb.four_to_three(in_file4d) else: iflogger.info('Single functional image provided') in_files = self.inputs.in_files if len(in_files) == 1: iflogger.error( "Only one functional image was input. Pearson's correlation coefficient can not be calculated") raise ValueError else: rois = get_roi_list(self.inputs.segmentation_file) fMRI_timecourse = get_timecourse_by_region( in_files, self.inputs.segmentation_file, rois) timecourse_at_each_node = fMRI_timecourse.T iflogger.info(np.shape(timecourse_at_each_node)) iflogger.info( 'Structural Network: {s}'.format(s=self.inputs.structural_network)) structural_network = nx.read_gpickle(self.inputs.structural_network) rois = structural_network.nodes() #rois = get_roi_list(self.inputs.segmentation_file) number_of_nodes = len(rois) iflogger.info('Found {roi} unique region values'.format(roi=len(rois))) newntwk = structural_network.copy() newntwk = remove_all_edges(newntwk) simple_correlation_matrix = np.zeros( (number_of_nodes, number_of_nodes)) iflogger.info('Drawing edges...') for idx_i, roi_i in enumerate(rois): #iflogger.info('ROI:{i}, T-value: {t}'.format(i=roi_i, t=t_i)) for idx_j, roi_j in enumerate(rois): #iflogger.info('...ROI:{j}, T-value: {t}'.format(j=roi_j, t=t_j)) if idx_j > idx_i: simple_correlation_matrix[idx_i, idx_j] = pearsonr( fMRI_timecourse[idx_i], fMRI_timecourse[idx_j])[0] elif roi_i == roi_j: simple_correlation_matrix[idx_i, idx_j] = 0.5 simple_correlation_matrix = simple_correlation_matrix + \ simple_correlation_matrix.T stats = {'correlation': simple_correlation_matrix} newntwk = add_edge_data(simple_correlation_matrix, newntwk) path, name, ext = split_filename(self.inputs.out_network_file) if not ext == '.pck': ext = '.pck' out_network_file = op.abspath(name + ext) iflogger.info( 'Saving simple correlation network as {out}'.format(out=out_network_file)) nx.write_gpickle(newntwk, out_network_file) path, name, ext = split_filename(self.inputs.out_stats_file) if not ext == '.mat': ext = '.mat' out_stats_file = op.abspath(name + ext) iflogger.info( 'Saving image statistics as {stats}'.format(stats=out_stats_file)) sio.savemat(out_stats_file, stats) return runtime
def _run_interface(self, runtime): if isdefined(self.inputs.lookup_table): LUT_dict = get_names(self.inputs.lookup_table) if len(self.inputs.in_files) > 1: iflogger.info('Multiple input images detected') iflogger.info(len(self.inputs.in_files)) in_files = self.inputs.in_files elif isdefined(self.inputs.in_file4d): iflogger.info('Single four-dimensional image selected') in_files = nb.four_to_three(self.inputs.in_file4d) else: iflogger.info('Single functional image provided') in_files = self.inputs.in_files per_file_stats = {} seg_file = nb.load(self.inputs.segmentation_file) segmentationdata = seg_file.get_data() if isdefined(self.inputs.resolution_network_file): try: gp = nx.read_gpickle(self.inputs.resolution_network_file) except: gp = nx.read_graphml(self.inputs.resolution_network_file) nodedict = gp.node[gp.nodes()[0]] if not nodedict.has_key('dn_position'): iflogger.info("Creating node positions from segmentation") G = nx.Graph() for u, d in gp.nodes_iter(data=True): iflogger.info('Node ID {id}'.format(id=int(u))) G.add_node(int(u), d) xyz = tuple( np.mean(np.where(np.flipud(segmentationdata) == int(d["dn_correspondence_id"])), axis=1)) G.node[int(u)]['dn_position'] = xyz ntwkname = op.abspath('nodepositions.pck') nx.write_gpickle(G, ntwkname) else: ntwkname = self.inputs.resolution_network_file rois = get_roi_list(self.inputs.segmentation_file) roi_mean_tc, roi_max_tc, roi_min_tc, roi_std_tc, voxels = get_timecourse_by_region( in_files, self.inputs.segmentation_file, rois) stats = {} stats['func_max'] = roi_max_tc stats['func_mean'] = roi_mean_tc stats['func_min'] = roi_min_tc stats['func_stdev'] = roi_std_tc stats['number_of_voxels'] = voxels stats['rois'] = rois if isdefined(self.inputs.lookup_table): stats['roi_names'] = [] for x in rois: try: stats['roi_names'].append(LUT_dict[x]) except KeyError: stats['roi_names'].append("Unknown_ROI_" + str(x)) global all_ntwks all_ntwks = list() for in_file_idx, in_file in enumerate(in_files): ntwks = list() per_file_stats = {} per_file_stats['func_max'] = roi_max_tc[:, in_file_idx] per_file_stats['func_mean'] = roi_mean_tc[:, in_file_idx] per_file_stats['func_min'] = roi_min_tc[:, in_file_idx] per_file_stats['func_stdev'] = roi_std_tc[:, in_file_idx] per_file_stats['rois'] = rois if isdefined(self.inputs.lookup_table): per_file_stats['roi_names'] = [LUT_dict[x] for x in rois] #per_file_stats['number_of_voxels'] = voxels[in_file_idx] for key in per_file_stats.keys(): iflogger.info(key) iflogger.info(np.shape(per_file_stats[key])) try: nwtk = nx.read_gpickle(ntwkname) newntwk = add_node_data(per_file_stats[key], nwtk) except: iflogger.error(key) iflogger.error(np.shape(per_file_stats[key])) iflogger.error( "Double-check the subjects' freesurfer directory.") raise Exception( "There may not be enough regions in the segmentation file!") name = '{k}_{i}'.format(k=key, i=str(in_file_idx)) out_file = op.abspath(name + '.pck') nx.write_gpickle(newntwk, out_file) ntwks.append(out_file) all_ntwks.extend(ntwks) else: rois = get_roi_list(self.inputs.segmentation_file) roi_mean_tc, roi_max_tc, roi_min_tc, roi_std_tc, voxels = get_timecourse_by_region( in_files, self.inputs.segmentation_file, rois) stats = {} stats['func_max'] = roi_max_tc stats['func_mean'] = roi_mean_tc stats['func_min'] = roi_min_tc stats['func_stdev'] = roi_std_tc stats['number_of_voxels'] = voxels stats['rois'] = rois if isdefined(self.inputs.lookup_table): stats['roi_names'] = [] for x in rois: try: stats['roi_names'].append(LUT_dict[x]) except KeyError: stats['roi_names'].append("Unknown_ROI_" + str(x)) if isdefined(self.inputs.subject_id): stats['subject_id'] = self.inputs.subject_id out_stats_file = op.abspath(self.inputs.out_stats_file) iflogger.info( 'Saving image statistics as {stats}'.format(stats=out_stats_file)) sio.savemat(out_stats_file, stats) return runtime
def save_vols(vols, output_dir, basenames=None, affine=None, concat=False, prefix='', ext=None): """ Saves a single 4D image or a couple of 3D vols unto disk. vols: single 4D nibabel image object, or list of 3D nibabel image objects volumes, of ndarray volumes to be saved output_dir: string existing filename, destination directory basenames: string or list of string, optional (default None) basename(s) for output image(s) affine: 2D array of shape (4, 4) affine matrix for the output images concat: bool, optional (default False) concatenate all vols into a single film prefix: string, optional (default '') prefix to be prepended to output file basenames ext: string, optional (default ".nii.gz") file extension for output images Returns ------- string of list of strings, dependending on whether vols is list or not, and on whether concat is set or not the output image filename(s) """ if ext is None: ext = ".nii.gz" def _nifti_or_ndarray_to_nifti(x): if is_niimg(x): if affine is not None: raise ValueError( ("vol is of type %s; not expecting `affine` parameter.") % type(x)) else: return x if affine is None: raise ValueError( "vol is of type ndarray; you need to specifiy `affine`") else: return nibabel.Nifti1Image(x, affine) if basenames is not None: basenames = get_basenames(basenames, ext=ext) # sanitize output_dir if not os.path.exists(output_dir): os.makedirs(output_dir) # vols are ndarray ? if isinstance(vols, np.ndarray): vols = _nifti_or_ndarray_to_nifti(vols) # concat vols to single 4D film ? if concat: if isinstance(vols, list): vols = nibabel.concat_images( [_nifti_or_ndarray_to_nifti(vol) for vol in vols], check_affines=False) if basenames is not None: if not isinstance(basenames, _basestring): basenames = basenames[0] else: if basenames is not None: if not isinstance(basenames, _basestring): raise RuntimeError( ("concat=True specified but basenames is of type %s " "instead of string") % type(basenames)) if not isinstance(vols, list): if basenames is None: basenames = get_basenames("vols", ext=ext) if not isinstance(basenames, _basestring): vols = nibabel.four_to_three(vols) filenames = [] for vol, basename in zip(vols, basenames): if not isinstance(basename, _basestring): raise RuntimeError filename = os.path.join(output_dir, "%s%s" % (prefix, basename)) nibabel.save(vol, filename) filenames.append(filename) else: filenames = os.path.join(output_dir, "%s%s" % (prefix, basenames)) nibabel.save(vols, filenames) return filenames else: n_vols = len(vols) filenames = [] if basenames is None: if prefix: prefix = prefix + "_" else: if isinstance(basenames, _basestring): basenames = [ "vol%i_%s" % (t, basenames) for t in range(len(vols)) ] else: if len(set(basenames)) != len(vols): raise RuntimeError for t, vol in zip(range(n_vols), vols): if isinstance(vol, np.ndarray): if affine is None: raise ValueError( ("vols is of type ndarray; you need to specifiy" " `affine`")) else: vol = nibabel.Nifti1Image(vol, affine) # save realigned vol unto disk if basenames is None: output_filename = os.path.join( output_dir, get_basename("%svol_%i" % (prefix, t), ext=ext)) else: basename = basenames if isinstance( basenames, _basestring) else basenames[t] output_filename = os.path.join( output_dir, get_basenames("%s%s" % (prefix, basename), ext=ext)) vol = check_niimg(vol) nibabel.save(vol, output_filename) # update rvols and filenames filenames.append(output_filename) return filenames
def _run_interface(self, runtime): data_dir = op.abspath('./denoise/components') if not os.path.exists(data_dir): os.makedirs(data_dir) in_files = self.inputs.in_files if len(self.inputs.in_files) > 1: print 'Multiple ({n}) input images detected! Copying to {d}...'.format(n=len(self.inputs.in_files), d=data_dir) for in_file in self.inputs.in_files: path, name, ext = split_filename(in_file) shutil.copyfile(in_file, op.join(data_dir, name) + ext) if ext == '.img': shutil.copyfile(op.join(path, name) + '.hdr', op.join(data_dir, name) + '.hdr') elif ext == '.hdr': shutil.copyfile(op.join(path, name) + '.img', op.join(data_dir, name) + '.img') print 'Copied!' in_files = self.inputs.in_files elif isdefined(self.inputs.in_file4d): print 'Single four-dimensional image selected. Splitting and copying to {d}'.format(d=data_dir) in_files = nb.four_to_three(self.inputs.in_file4d) for in_file in in_files: path, name, ext = split_filename(in_file) shutil.copyfile(in_file, op.join(data_dir, name) + ext) print 'Copied!' else: print 'Single functional image provided. Ending...' in_files = self.inputs.in_files nComponents = len(in_files) path, name, ext = split_filename(self.inputs.time_course_image) shutil.copyfile(self.inputs.time_course_image, op.join(data_dir, name) + ext) if ext == '.img': shutil.copyfile(op.join(path, name) + '.hdr', op.join(data_dir, name) + '.hdr') elif ext == '.hdr': shutil.copyfile(op.join(path, name) + '.img', op.join(data_dir, name) + '.img') data_dir = op.abspath('./denoise') path, name, ext = split_filename(self.inputs.ica_mask_image) shutil.copyfile(self.inputs.ica_mask_image, op.join(data_dir, name) + ext) if ext == '.img': shutil.copyfile(op.join(path, name) + '.hdr', op.join(data_dir, name) + '.hdr') elif ext == '.hdr': shutil.copyfile(op.join(path, name) + '.img', op.join(data_dir, name) + '.img') mask_file = op.join(data_dir, name) repetition_time = self.inputs.repetition_time neuronal_image = op.abspath(self.inputs.out_neuronal_image) non_neuronal_image = op.abspath(self.inputs.out_non_neuronal_image) coma_rest_lib_path = op.abspath(self.inputs.coma_rest_lib_path) d = dict( data_dir=data_dir, mask_name=mask_file, nComponents=nComponents, Tr=repetition_time, nameNeuronal=neuronal_image, nameNonNeuronal=non_neuronal_image, coma_rest_lib_path=coma_rest_lib_path) script = Template(""" restlib_path = '$coma_rest_lib_path'; setup_restlib_paths(restlib_path) dataDir = '$data_dir'; maskName = '$mask_name'; nCompo = $nComponents; Tr = $Tr; nameNeuronalData = '$nameNeuronal'; nameNonNeuronalData = '$nameNonNeuronal'; denoiseImage(dataDir,maskName,nCompo,Tr,nameNeuronalData,nameNonNeuronalData, restlib_path); """).substitute(d) result = MatlabCommand(script=script, mfile=True, prescript=[''], postscript=['']) r = result.run() print 'Neuronal component image saved as {n}'.format(n=neuronal_image) print 'Non-neuronal component image saved as {n}'.format(n=non_neuronal_image) return runtime
def _run_interface(self, runtime): from dipy.core.gradients import GradientTable from dipy.reconst.dti import fractional_anisotropy, mean_diffusivity from dipy.reconst.csdeconv import recursive_response, auto_response img = nb.load(self.inputs.in_file) imref = nb.four_to_three(img)[0] affine = img.affine if isdefined(self.inputs.in_mask): msk = nb.load(self.inputs.in_mask).get_data() msk[msk > 0] = 1 msk[msk < 0] = 0 else: msk = np.ones(imref.shape) data = img.get_data().astype(np.float32) gtab = self._get_gradient_table() evals = np.nan_to_num(nb.load(self.inputs.in_evals).get_data()) FA = np.nan_to_num(fractional_anisotropy(evals)) * msk indices = np.where(FA > self.inputs.fa_thresh) S0s = data[indices][:, np.nonzero(gtab.b0s_mask)[0]] S0 = np.mean(S0s) if self.inputs.auto: response, ratio = auto_response(gtab, data, roi_radius=self.inputs.roi_radius, fa_thr=self.inputs.fa_thresh) response = response[0].tolist() + [S0] elif self.inputs.recursive: MD = np.nan_to_num(mean_diffusivity(evals)) * msk indices = np.logical_or( FA >= 0.4, (np.logical_and(FA >= 0.15, MD >= 0.0011))) data = nb.load(self.inputs.in_file).get_data() response = recursive_response(gtab, data, mask=indices, sh_order=8, peak_thr=0.01, init_fa=0.08, init_trace=0.0021, iter=8, convergence=0.001, parallel=True) ratio = abs(response[1] / response[0]) else: lambdas = evals[indices] l01 = np.sort(np.mean(lambdas, axis=0)) response = np.array([l01[-1], l01[-2], l01[-2], S0]) ratio = abs(response[1] / response[0]) if ratio > 0.25: IFLOGGER.warn('Estimated response is not prolate enough. ' 'Ratio=%0.3f.', ratio) elif ratio < 1.e-5 or np.any(np.isnan(response)): response = np.array([1.8e-3, 3.6e-4, 3.6e-4, S0]) IFLOGGER.warn('Estimated response is not valid, using a default one') else: IFLOGGER.info('Estimated response: %s', str(response[:3])) np.savetxt(op.abspath(self.inputs.response), response) wm_mask = np.zeros_like(FA) wm_mask[indices] = 1 nb.Nifti1Image( wm_mask.astype(np.uint8), affine, None).to_filename(op.abspath(self.inputs.out_mask)) return runtime