def reorient_tensor_image(tensor_image, warp_file, mask_img, prefix, output_fname): cmds = [] to_remove = [] reoriented_tensor_fname = prefix + "reoriented_tensor.nii" reorient_cmd = "ReorientTensorImage 3 %s %s %s" % (tensor_image, reoriented_tensor_fname, warp_file) LOGGER.info(reorient_cmd) os.system(reorient_cmd) cmds.append(reorient_cmd) to_remove.append(reoriented_tensor_fname) # Load the reoriented tensor and get the principal directions out reoriented_dt_img = nb.load(reoriented_tensor_fname) reoriented_tensor_data = reoriented_dt_img.get_data().squeeze() mask_data = mask_img.get_data() > 0 output_data = np.zeros(mask_img.shape + (3,)) reoriented_tensors = reoriented_tensor_data[mask_data] reoriented_vectors = np.zeros((reoriented_tensors.shape[0], 3)) def tensor_from_vec(vec): """[dxx, dxy, dyy, dxz, dyz, dzz].""" return np.array([ [vec[0], vec[1], vec[3]], [vec[1], vec[2], vec[4]], [vec[3], vec[4], vec[5]] ]) for nrow, row in enumerate(reoriented_tensors): row_tensor = tensor_from_vec(row) evals, evecs = decompose_tensor(row_tensor) reoriented_vectors[nrow] = evecs[:, 0] output_data[mask_data] = normalized_vector(reoriented_vectors) vector_data = get_vector_nii(output_data, mask_img.affine, mask_img.header) vector_data.to_filename(output_fname) os.remove(reoriented_tensor_fname) os.remove(tensor_image) return output_fname, reorient_cmd
allBvecsNames = [x.strip('\n') for x in allBvecsNames] allBvalsNames = [x.strip('\n') for x in allBvalsNames] if os.path.exists(directory) == False: os.mkdir(directory) # Processing for iMask in range(len(allMaskNames)): print "Processing subject", iMask print "Loading" gradient_directions = np.loadtxt(allBvecsNames[iMask]) # on the unit sphere if gradient_directions.shape[1] == 3: gradient_directions_normalized = normalized_vector(gradient_directions) else: gradient_directions_normalized = normalized_vector(gradient_directions.T) gradient_directions_normalized[np.isnan(gradient_directions_normalized)] = 1.0/np.sqrt(3) bvalues = np.loadtxt(allBvalsNames[iMask]) # given in s/mm^2 bvalues_SI = bvalues * 1e6 acq_scheme = acquisition_scheme_from_bvalues(bvalues_SI, gradient_directions_normalized, delta, Delta) # gtab_dipy = gradient_table(bvalues, gradient_directions, big_delta=Delta, small_delta=delta, atol=3e-2) # acq_scheme = gtab_dipy2mipy(gtab_dipy) acq_scheme.print_acquisition_info dwi_nii = nib.load(allDwiNames[iMask]) dwi = dwi_nii.get_data() mask = nib.load(allMaskNames[iMask]).get_data()
def run(context): #################################################### # Get the path to input files and other parameter # #################################################### context.set_progress(message='Set path.') os.environ[ 'PATH'] = os.environ['PATH'] + ':/root/mrtrix3-3.0_RC3_latest/bin' os.environ['PATH'] = os.environ['PATH'] + ':/root/antsbin/bin' context.set_progress(message='Retrieving data.') analysis_data = context.fetch_analysis_data() settings = analysis_data['settings'] postprocessing = settings['postprocessing'] hcpl_dwi_file_handle = context.get_files('input', modality='HARDI')[0] hcpl_dwi_file_path = hcpl_dwi_file_handle.download('/root/') hcpl_bvalues_file_handle = context.get_files( 'input', reg_expression='.*prep.bvalues.hcpl.txt')[0] hcpl_bvalues_file_path = hcpl_bvalues_file_handle.download('/root/') hcpl_bvecs_file_handle = context.get_files( 'input', reg_expression='.*prep.gradients.hcpl.txt')[0] hcpl_bvecs_file_path = hcpl_bvecs_file_handle.download('/root/') inject_file_handle = context.get_files( 'input', reg_expression='.*prep.inject.nii.gz')[0] inject_file_path = inject_file_handle.download('/root/') seed_mask_img = nib.load(inject_file_path) affine = seed_mask_img.affine VUMC_ROIs_file_handle = context.get_files( 'input', reg_expression='.*VUMC_ROIs.nii.gz')[0] VUMC_ROIs_file_path = VUMC_ROIs_file_handle.download('/root/') ############################# # Fitting NODDI using AMICO # ############################# context.set_progress(message='Setting up AMICO.') amico.core.setup() ae = amico.Evaluation('/root/', '.') [_, bvecs] = read_bvals_bvecs(None, hcpl_bvecs_file_path) bvecs_norm = normalized_vector(bvecs) bvecs_norm[0] = [0, 0, 0] np.savetxt('/root/grad_norm.txt', np.matrix.transpose(bvecs_norm), fmt='%.3f') amico.util.fsl2scheme(hcpl_bvalues_file_path, '/root/grad_norm.txt', '/root/grad.scheme') os.system('dwi2mask -fslgrad ' + hcpl_bvecs_file_path + ' ' + hcpl_bvalues_file_path + ' ' + hcpl_dwi_file_path + ' /root/mask.nii.gz') ae.load_data(dwi_filename='prep.dwi.hcpl.nii.gz', scheme_filename='grad.scheme', mask_filename='mask.nii.gz', b0_thr=30) ae.set_model('NODDI') ae.generate_kernels() ae.load_kernels() context.set_progress(message='Fitting NODDI maps.') ae.fit() ae.save_results() ###################################################### # Computing inclusion/exclusion maps from NODDI maps # ###################################################### context.set_progress(message='Defining masks.') os.system( 'mrcalc /root/AMICO/NODDI/FIT_OD.nii.gz 0.1 -gt ' + '/root/AMICO/NODDI/FIT_OD.nii.gz 0.7 -lt -mul /root/wm_mask.nii.gz') os.system( 'mrcalc /root/AMICO/NODDI/FIT_ICVF.nii.gz 0.95 -lt /root/gm_mask.nii.gz' ) os.system( 'mrcalc /root/AMICO/NODDI/FIT_ISOVF.nii.gz 0 -gt /root/csf_mask.nii.gz' ) ################################################## # Doing reconstruction&tracking using TRAMPOLINO # ################################################## context.set_progress(message='Starting TRAMPOLINO recon&track.') os.chdir('/root') os.system( 'trampolino -r results -n mrtrix_workflow recon -i ' + hcpl_dwi_file_path + ' ' + '-v ' + hcpl_bvecs_file_path + ' -b ' + hcpl_bvalues_file_path + ' ' + '--opt bthres:0,mask:wm_mask.nii.gz mrtrix_msmt_csd track ' + '-s ' + inject_file_path + ' --opt nos:10000,include:gm_mask.nii.gz,exclude:csf_mask.nii.gz ' + '--min_length 10,50 --ensemble min_length mrtrix_tckgen ' + 'convert -r wm_mask.nii.gz tck2trk') track = load_tractogram('results/track.trk', 'wm_mask.nii.gz') streamlines = track.streamlines ########################################################################### # Compute 3D volumes for the IronTract Challenge. For 'EPFL', we only # # keep streamlines with length > 1mm. We compute the visitation count # # image and apply a small gaussian smoothing. The gaussian smoothing # # is especially usefull to increase voxel coverage of deterministic # # algorithms. The log of the smoothed visitation count map is then # # iteratively thresholded producing 200 volumes/operation points. # # For VUMC, additional streamline filtering is done using anatomical # # priors (keeping only streamlines that intersect with at least one ROI). # ########################################################################### if postprocessing in ['EPFL', 'ALL']: context.set_progress(message='Processing density map (EPFL).') volume_folder = '/root/vol_epfl' output_epfl_zip_file_path = '/root/SpaghettiBeans_EPFL.zip' os.mkdir(volume_folder) lengths = length(streamlines) streamlines = streamlines[lengths > 1] density = utils.density_map(streamlines, affine, seed_mask_img.shape) density = scipy.ndimage.gaussian_filter(density.astype('float32'), 0.5) log_density = np.log10(density + 1) max_density = np.max(log_density) for i, t in enumerate(np.arange(0, max_density, max_density / 200)): nbr = str(i) nbr = nbr.zfill(3) mask = log_density >= t vol_filename = os.path.join( volume_folder, 'vol' + nbr + '_t' + str(t) + '.nii.gz') nib.Nifti1Image(mask.astype('int32'), affine, seed_mask_img.header).to_filename(vol_filename) shutil.make_archive(output_epfl_zip_file_path[:-4], 'zip', volume_folder) if postprocessing in ['VUMC', 'ALL']: context.set_progress(message='Processing density map (VUMC).') ROIs_img = nib.load(VUMC_ROIs_file_path) volume_folder = '/root/vol_vumc' output_vumc_zip_file_path = '/root/SpaghettiBeans_VUMC.zip' os.mkdir(volume_folder) lengths = length(streamlines) streamlines = streamlines[lengths > 1] rois = ROIs_img.get_fdata().astype(int) _, grouping = utils.connectivity_matrix(streamlines, affine, rois, inclusive=True, return_mapping=True, mapping_as_streamlines=False) streamlines = streamlines[grouping[(0, 1)]] density = utils.density_map(streamlines, affine, seed_mask_img.shape) density = scipy.ndimage.gaussian_filter(density.astype('float32'), 0.5) log_density = np.log10(density + 1) max_density = np.max(log_density) for i, t in enumerate(np.arange(0, max_density, max_density / 200)): nbr = str(i) nbr = nbr.zfill(3) mask = log_density >= t vol_filename = os.path.join( volume_folder, 'vol' + nbr + '_t' + str(t) + '.nii.gz') nib.Nifti1Image(mask.astype('int32'), affine, seed_mask_img.header).to_filename(vol_filename) shutil.make_archive(output_vumc_zip_file_path[:-4], 'zip', volume_folder) ################### # Upload the data # ################### context.set_progress(message='Uploading results...') if postprocessing in ['EPFL', 'ALL']: context.upload_file(output_epfl_zip_file_path, 'SpaghettiBeans_EPFL.zip') if postprocessing in ['VUMC', 'ALL']: context.upload_file(output_vumc_zip_file_path, 'SpaghettiBeans_VUMC.zip')