def test_create_density_map(): """ Test for create_density_map functionality """ from pynets.dmri import track base_dir = str(Path(__file__).parent / "examples") dir_path = base_dir + '/001/dmri' dwi_file = dir_path + '/HARDI150.nii.gz' dwi_img = nib.load(dwi_file) # Load output from test_filter_streamlines: dictionary of streamline info streamlines_trk = dir_path + '/tractography/streamlines_Default_csa_10_5mm_curv[2_4_6]_step[0.1_0.2_0.5].trk' streamlines = nib.streamlines.load(streamlines_trk).streamlines conn_model = 'csa' target_samples = 10 node_size = 5 curv_thr_list = [2, 4, 6] step_list = [0.1, 0.2, 0.5] network = 'Default' roi = None directget = 'prob' max_length = 200 [streams, dir_path, dm_path] = track.create_density_map(dwi_img, dir_path, streamlines, conn_model, target_samples, node_size, curv_thr_list, step_list, network, roi, directget, max_length) assert streams is not None assert dir_path is not None assert dm_path is not None
def test_create_density_map(): """ Test for create_density_map functionality """ from pynets.dmri import track from dipy.tracking._utils import _mapping_to_voxel base_dir = os.path.abspath( pkg_resources.resource_filename("pynets", "../data/examples")) dir_path = f"{base_dir}/BIDS/sub-25659/ses-1/dwi" dwi_file = f"{base_dir}/BIDS/sub-25659/ses-1/dwi/final_preprocessed_" \ f"dwi.nii.gz" dwi_img = nib.load(dwi_file) # Load output from test_filter_streamlines: dictionary of streamline info streamlines_trk = f"{base_dir}/miscellaneous/streamlines_model-csd_" \ f"nodetype-parc_tracktype-local_traversal-prob_" \ f"minlength-0.trk" streamlines = nib.streamlines.load(streamlines_trk).streamlines # Remove streamlines with negative voxel indices lin_T, offset = _mapping_to_voxel(np.eye(4)) streams_final_filt_final = [] for sl in streamlines: inds = np.dot(sl, lin_T) inds += offset if not inds.min().round(decimals=6) < 0: streams_final_filt_final.append(sl) conn_model = 'csd' node_radius = None curv_thr_list = [40, 30] step_list = [0.1, 0.2, 0.3, 0.4, 0.5] subnet = None roi = None traversal = 'prob' max_length = 0 [dir_path, dm_path ] = track.create_density_map(dwi_img, dir_path, streams_final_filt_final, conn_model, node_radius, curv_thr_list, step_list, subnet, roi, traversal, max_length, '/tmp') assert dir_path is not None assert dm_path is not None
def test_create_density_map(): """ Test for create_density_map functionality """ from pynets.dmri import track from dipy.tracking._utils import _mapping_to_voxel base_dir = str(Path(__file__).parent / "examples") dir_path = f"{base_dir}/BIDS/sub-0025427/ses-1/dwi" dwi_file = f"{base_dir}/BIDS/sub-0025427/ses-1/dwi/final_preprocessed_dwi.nii.gz" dwi_img = nib.load(dwi_file) # Load output from test_filter_streamlines: dictionary of streamline info streamlines_trk = f"{base_dir}/miscellaneous/streamlines_est-csd_nodetype-parc_samples-10000streams_tt-local_dg-prob_ml-0.trk" streamlines = nib.streamlines.load(streamlines_trk).streamlines # Remove streamlines with negative voxel indices lin_T, offset = _mapping_to_voxel(np.eye(4)) streams_final_filt_final = [] for sl in streamlines: inds = np.dot(sl, lin_T) inds += offset if not inds.min().round(decimals=6) < 0: streams_final_filt_final.append(sl) conn_model = 'csd' target_samples = 10000 node_size = None curv_thr_list = [40, 30] step_list = [0.1, 0.2, 0.3, 0.4, 0.5] network = None roi = None directget = 'prob' max_length = 0 [streams, dir_path, dm_path ] = track.create_density_map(dwi_img, dir_path, streams_final_filt_final, conn_model, target_samples, node_size, curv_thr_list, step_list, network, roi, directget, max_length) assert streams is not None assert dir_path is not None assert dm_path is not None
def run_track(B0_mask, gm_in_dwi, vent_csf_in_dwi, wm_in_dwi, tiss_class, labels_im_file_wm_gm_int, labels_im_file, target_samples, curv_thr_list, step_list, track_type, max_length, maxcrossing, directget, conn_model, gtab_file, dwi_file, network, node_size, dens_thresh, ID, roi, min_span_tree, disp_filt, parc, prune, atlas, uatlas, labels, coords, norm, binary, atlas_mni, min_length, fa_path, waymask, roi_neighborhood_tol=8, sphere='repulsion724'): """ Run all ensemble tractography and filtering routines. Parameters ---------- B0_mask : str File path to B0 brain mask. gm_in_dwi : str File path to grey-matter tissue segmentation Nifti1Image. vent_csf_in_dwi : str File path to ventricular CSF tissue segmentation Nifti1Image. wm_in_dwi : str File path to white-matter tissue segmentation Nifti1Image. tiss_class : str Tissue classification method. labels_im_file_wm_gm_int : str File path to atlas parcellation Nifti1Image in T1w-warped native diffusion space, restricted to wm-gm interface. labels_im_file : str File path to atlas parcellation Nifti1Image in T1w-warped native diffusion space. target_samples : int Total number of streamline samples specified to generate streams. curv_thr_list : list List of integer curvature thresholds used to perform ensemble tracking. step_list : list List of float step-sizes used to perform ensemble tracking. track_type : str Tracking algorithm used (e.g. 'local' or 'particle'). max_length : int Maximum fiber length threshold in mm to restrict tracking. maxcrossing : int Maximum number if diffusion directions that can be assumed per voxel while tracking. directget : str The statistical approach to tracking. Options are: det (deterministic), closest (clos), boot (bootstrapped), and prob (probabilistic). conn_model : str Connectivity reconstruction method (e.g. 'csa', 'tensor', 'csd'). gtab_file : str File path to pickled DiPy gradient table object. dwi_file : str File path to diffusion weighted image. network : str Resting-state network based on Yeo-7 and Yeo-17 naming (e.g. 'Default') used to filter nodes in the study of brain subgraphs. node_size : int Spherical centroid node size in the case that coordinate-based centroids are used as ROI's for tracking. dens_thresh : bool Indicates whether a target graph density is to be used as the basis for thresholding. ID : str A subject id or other unique identifier. roi : str File path to binarized/boolean region-of-interest Nifti1Image file. min_span_tree : bool Indicates whether local thresholding from the Minimum Spanning Tree should be used. disp_filt : bool Indicates whether local thresholding using a disparity filter and 'backbone network' should be used. parc : bool Indicates whether to use parcels instead of coordinates as ROI nodes. prune : bool Indicates whether to prune final graph of disconnected nodes/isolates. atlas : str Name of atlas parcellation used. uatlas : str File path to atlas parcellation Nifti1Image in MNI template space. labels : list List of string labels corresponding to graph nodes. coords : list List of (x, y, z) tuples corresponding to a coordinate atlas used or which represent the center-of-mass of each parcellation node. norm : int Indicates method of normalizing resulting graph. binary : bool Indicates whether to binarize resulting graph edges to form an unweighted graph. atlas_mni : str File path to atlas parcellation Nifti1Image in T1w-warped MNI space. min_length : int Minimum fiber length threshold in mm. fa_path : str File path to FA Nifti1Image. waymask : str Path to a Nifti1Image in native diffusion space to constrain tractography. roi_neighborhood_tol : float Distance (in the units of the streamlines, usually mm). If any coordinate in the streamline is within this distance from the center of any voxel in the ROI, the filtering criterion is set to True for this streamline, otherwise False. Defaults to the distance between the center of each voxel and the corner of the voxel. Default is 10 mm. sphere : str Provide triangulated spheres. Default is repulsion724. Options are: `symmetric362`, `symmetric642`, `symmetric724`, `repulsion724`, `repulsion100`, or `repulsion200` Returns ------- streams : str File path to save streamline array sequence in .trk format. track_type : str Tracking algorithm used (e.g. 'local' or 'particle'). target_samples : int Total number of streamline samples specified to generate streams. conn_model : str Connectivity reconstruction method (e.g. 'csa', 'tensor', 'csd'). dir_path : str Path to directory containing subject derivative data for a given pynets run. network : str Resting-state network based on Yeo-7 and Yeo-17 naming (e.g. 'Default') used to filter nodes in the study of brain subgraphs. node_size : int Spherical centroid node size in the case that coordinate-based centroids are used as ROI's for tracking. dens_thresh : bool Indicates whether a target graph density is to be used as the basis for thresholding. ID : str A subject id or other unique identifier. roi : str File path to binarized/boolean region-of-interest Nifti1Image file. min_span_tree : bool Indicates whether local thresholding from the Minimum Spanning Tree should be used. disp_filt : bool Indicates whether local thresholding using a disparity filter and 'backbone network' should be used. parc : bool Indicates whether to use parcels instead of coordinates as ROI nodes. prune : bool Indicates whether to prune final graph of disconnected nodes/isolates. atlas : str Name of atlas parcellation used. uatlas : str File path to atlas parcellation Nifti1Image in MNI template space. labels : list List of string labels corresponding to graph nodes. coords : list List of (x, y, z) tuples corresponding to a coordinate atlas used or which represent the center-of-mass of each parcellation node. norm : int Indicates method of normalizing resulting graph. binary : bool Indicates whether to binarize resulting graph edges to form an unweighted graph. atlas_mni : str File path to atlas parcellation Nifti1Image in T1w-warped MNI space. curv_thr_list : list List of integer curvature thresholds used to perform ensemble tracking. step_list : list List of float step-sizes used to perform ensemble tracking. fa_path : str File path to FA Nifti1Image. dm_path : str File path to fiber density map Nifti1Image. directget : str The statistical approach to tracking. Options are: det (deterministic), closest (clos), boot (bootstrapped), and prob (probabilistic). max_length : int Maximum fiber length threshold in mm to restrict tracking. """ import gc try: import cPickle as pickle except ImportError: import _pickle as pickle from dipy.io import load_pickle from colorama import Fore, Style from dipy.data import get_sphere from pynets.core import utils from pynets.dmri.track import prep_tissues, reconstruction, create_density_map, track_ensemble # Load diffusion data dwi_img = nib.load(dwi_file) dwi_data = dwi_img.get_fdata() # Fit diffusion model mod_fit = reconstruction(conn_model, load_pickle(gtab_file), dwi_data, B0_mask) # Load atlas parcellation (and its wm-gm interface reduced version for seeding) atlas_data = nib.load(labels_im_file).get_fdata().astype('uint16') atlas_data_wm_gm_int = nib.load( labels_im_file_wm_gm_int).get_fdata().astype('uint16') # Build mask vector from atlas for later roi filtering parcels = [] i = 0 for roi_val in np.unique(atlas_data)[1:]: parcels.append(atlas_data == roi_val) i = i + 1 if np.sum(atlas_data) == 0: raise ValueError( 'ERROR: No non-zero voxels found in atlas. Check any roi masks and/or wm-gm interface images ' 'to verify overlap with dwi-registered atlas.') # Iteratively build a list of streamlines for each ROI while tracking print( "%s%s%s%s" % (Fore.GREEN, 'Target number of samples: ', Fore.BLUE, target_samples)) print(Style.RESET_ALL) print("%s%s%s%s" % (Fore.GREEN, 'Using curvature threshold(s): ', Fore.BLUE, curv_thr_list)) print(Style.RESET_ALL) print("%s%s%s%s" % (Fore.GREEN, 'Using step size(s): ', Fore.BLUE, step_list)) print(Style.RESET_ALL) print("%s%s%s%s" % (Fore.GREEN, 'Tracking type: ', Fore.BLUE, track_type)) print(Style.RESET_ALL) if directget == 'prob': print("%s%s%s%s" % (Fore.GREEN, 'Direction-getting type: ', Fore.BLUE, 'Probabilistic')) elif directget == 'boot': print("%s%s%s%s" % (Fore.GREEN, 'Direction-getting type: ', Fore.BLUE, 'Bootstrapped')) elif directget == 'closest': print("%s%s%s%s" % (Fore.GREEN, 'Direction-getting type: ', Fore.BLUE, 'Closest Peak')) elif directget == 'det': print("%s%s%s%s" % (Fore.GREEN, 'Direction-getting type: ', Fore.BLUE, 'Deterministic Maximum')) print(Style.RESET_ALL) # Commence Ensemble Tractography streamlines = track_ensemble( dwi_data, target_samples, atlas_data_wm_gm_int, parcels, mod_fit, prep_tissues(B0_mask, gm_in_dwi, vent_csf_in_dwi, wm_in_dwi, tiss_class), get_sphere(sphere), directget, curv_thr_list, step_list, track_type, maxcrossing, max_length, roi_neighborhood_tol, min_length, waymask) print('Tracking Complete') # Create streamline density map [streams, dir_path, dm_path] = create_density_map(dwi_img, utils.do_dir_path(atlas, dwi_file), streamlines, conn_model, target_samples, node_size, curv_thr_list, step_list, network, roi, directget, max_length) del streamlines, dwi_data, atlas_data_wm_gm_int, atlas_data, mod_fit, parcels dwi_img.uncache() gc.collect() return streams, track_type, target_samples, conn_model, dir_path, network, node_size, dens_thresh, ID, roi, min_span_tree, disp_filt, parc, prune, atlas, uatlas, labels, coords, norm, binary, atlas_mni, curv_thr_list, step_list, fa_path, dm_path, directget, labels_im_file, roi_neighborhood_tol, max_length
def _run_interface(self, runtime): import gc import os import time import os.path as op from dipy.io import load_pickle from colorama import Fore, Style from dipy.data import get_sphere from pynets.core import utils from pynets.core.utils import load_runconfig from pynets.dmri.estimation import reconstruction from pynets.dmri.track import ( create_density_map, track_ensemble, ) from dipy.io.stateful_tractogram import Space, StatefulTractogram, \ Origin from dipy.io.streamline import save_tractogram from nipype.utils.filemanip import copyfile, fname_presuffix hardcoded_params = load_runconfig() use_life = hardcoded_params['tracking']["use_life"][0] roi_neighborhood_tol = hardcoded_params['tracking'][ "roi_neighborhood_tol"][0] sphere = hardcoded_params['tracking']["sphere"][0] target_samples = hardcoded_params['tracking']["tracking_samples"][0] dir_path = utils.do_dir_path(self.inputs.atlas, os.path.dirname(self.inputs.dwi_file)) namer_dir = "{}/tractography".format(dir_path) if not os.path.isdir(namer_dir): os.makedirs(namer_dir, exist_ok=True) # Load diffusion data dwi_file_tmp_path = fname_presuffix(self.inputs.dwi_file, suffix="_tmp", newpath=runtime.cwd) copyfile(self.inputs.dwi_file, dwi_file_tmp_path, copy=True, use_hardlink=False) dwi_img = nib.load(dwi_file_tmp_path, mmap=True) dwi_data = dwi_img.get_fdata(dtype=np.float32) # Load FA data fa_file_tmp_path = fname_presuffix(self.inputs.fa_path, suffix="_tmp", newpath=runtime.cwd) copyfile(self.inputs.fa_path, fa_file_tmp_path, copy=True, use_hardlink=False) fa_img = nib.load(fa_file_tmp_path, mmap=True) labels_im_file_tmp_path = fname_presuffix(self.inputs.labels_im_file, suffix="_tmp", newpath=runtime.cwd) copyfile(self.inputs.labels_im_file, labels_im_file_tmp_path, copy=True, use_hardlink=False) # Load B0 mask B0_mask_tmp_path = fname_presuffix(self.inputs.B0_mask, suffix="_tmp", newpath=runtime.cwd) copyfile(self.inputs.B0_mask, B0_mask_tmp_path, copy=True, use_hardlink=False) streams = "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s" % ( runtime.cwd, "/streamlines_", "%s" % (self.inputs.subnet + "_" if self.inputs.subnet is not None else ""), "%s" % (op.basename(self.inputs.roi).split(".")[0] + "_" if self.inputs.roi is not None else ""), self.inputs.conn_model, "_", target_samples, "_", "%s" % ("%s%s" % (self.inputs.node_radius, "mm_") if ((self.inputs.node_radius != "parc") and (self.inputs.node_radius is not None)) else "parc_"), "curv-", str(self.inputs.curv_thr_list).replace(", ", "_"), "_step-", str(self.inputs.step_list).replace(", ", "_"), "_traversal-", self.inputs.traversal, "_minlength-", self.inputs.min_length, ".trk", ) if os.path.isfile(f"{namer_dir}/{op.basename(streams)}"): from dipy.io.streamline import load_tractogram copyfile( f"{namer_dir}/{op.basename(streams)}", streams, copy=True, use_hardlink=False, ) tractogram = load_tractogram( streams, fa_img, bbox_valid_check=False, ) streamlines = tractogram.streamlines # Create streamline density map try: [dir_path, dm_path] = create_density_map( fa_img, dir_path, streamlines, self.inputs.conn_model, self.inputs.node_radius, self.inputs.curv_thr_list, self.inputs.step_list, self.inputs.subnet, self.inputs.roi, self.inputs.traversal, self.inputs.min_length, namer_dir, ) except BaseException: print('Density map failed. Check tractography output.') dm_path = None del streamlines, tractogram fa_img.uncache() dwi_img.uncache() gc.collect() self._results["dm_path"] = dm_path self._results["streams"] = streams recon_path = None else: # Fit diffusion model # Save reconstruction to .npy recon_path = "%s%s%s%s%s%s%s%s" % ( runtime.cwd, "/reconstruction_", "%s" % (self.inputs.subnet + "_" if self.inputs.subnet is not None else ""), "%s" % (op.basename(self.inputs.roi).split(".")[0] + "_" if self.inputs.roi is not None else ""), self.inputs.conn_model, "_", "%s" % ("%s%s" % (self.inputs.node_radius, "mm") if ((self.inputs.node_radius != "parc") and (self.inputs.node_radius is not None)) else "parc"), ".hdf5", ) gtab_file_tmp_path = fname_presuffix(self.inputs.gtab_file, suffix="_tmp", newpath=runtime.cwd) copyfile(self.inputs.gtab_file, gtab_file_tmp_path, copy=True, use_hardlink=False) gtab = load_pickle(gtab_file_tmp_path) # Only re-run the reconstruction if we have to if not os.path.isfile(f"{namer_dir}/{op.basename(recon_path)}"): import h5py model = reconstruction( self.inputs.conn_model, gtab, dwi_data, B0_mask_tmp_path, )[0] with h5py.File(recon_path, 'w') as hf: hf.create_dataset("reconstruction", data=model.astype('float32'), dtype='f4') hf.close() copyfile( recon_path, f"{namer_dir}/{op.basename(recon_path)}", copy=True, use_hardlink=False, ) time.sleep(2) del model elif os.path.getsize(f"{namer_dir}/{op.basename(recon_path)}") > 0: print(f"Found existing reconstruction with " f"{self.inputs.conn_model}. Loading...") copyfile( f"{namer_dir}/{op.basename(recon_path)}", recon_path, copy=True, use_hardlink=False, ) time.sleep(5) else: import h5py model = reconstruction( self.inputs.conn_model, gtab, dwi_data, B0_mask_tmp_path, )[0] with h5py.File(recon_path, 'w') as hf: hf.create_dataset("reconstruction", data=model.astype('float32'), dtype='f4') hf.close() copyfile( recon_path, f"{namer_dir}/{op.basename(recon_path)}", copy=True, use_hardlink=False, ) time.sleep(5) del model dwi_img.uncache() del dwi_data # Load atlas wm-gm interface reduced version for seeding labels_im_file_tmp_path_wm_gm_int = fname_presuffix( self.inputs.labels_im_file_wm_gm_int, suffix="_tmp", newpath=runtime.cwd) copyfile(self.inputs.labels_im_file_wm_gm_int, labels_im_file_tmp_path_wm_gm_int, copy=True, use_hardlink=False) t1w2dwi_tmp_path = fname_presuffix(self.inputs.t1w2dwi, suffix="_tmp", newpath=runtime.cwd) copyfile(self.inputs.t1w2dwi, t1w2dwi_tmp_path, copy=True, use_hardlink=False) gm_in_dwi_tmp_path = fname_presuffix(self.inputs.gm_in_dwi, suffix="_tmp", newpath=runtime.cwd) copyfile(self.inputs.gm_in_dwi, gm_in_dwi_tmp_path, copy=True, use_hardlink=False) vent_csf_in_dwi_tmp_path = fname_presuffix( self.inputs.vent_csf_in_dwi, suffix="_tmp", newpath=runtime.cwd) copyfile(self.inputs.vent_csf_in_dwi, vent_csf_in_dwi_tmp_path, copy=True, use_hardlink=False) wm_in_dwi_tmp_path = fname_presuffix(self.inputs.wm_in_dwi, suffix="_tmp", newpath=runtime.cwd) copyfile(self.inputs.wm_in_dwi, wm_in_dwi_tmp_path, copy=True, use_hardlink=False) if self.inputs.waymask: waymask_tmp_path = fname_presuffix(self.inputs.waymask, suffix="_tmp", newpath=runtime.cwd) copyfile(self.inputs.waymask, waymask_tmp_path, copy=True, use_hardlink=False) else: waymask_tmp_path = None # Iteratively build a list of streamlines for each ROI while # tracking print(f"{Fore.GREEN}Target streamlines per iteration: " f"{Fore.BLUE} " f"{target_samples}") print(Style.RESET_ALL) print(f"{Fore.GREEN}Curvature threshold(s): {Fore.BLUE} " f"{self.inputs.curv_thr_list}") print(Style.RESET_ALL) print(f"{Fore.GREEN}Step size(s): {Fore.BLUE} " f"{self.inputs.step_list}") print(Style.RESET_ALL) print(f"{Fore.GREEN}Tracking type: {Fore.BLUE} " f"{self.inputs.track_type}") print(Style.RESET_ALL) if self.inputs.traversal == "prob": print(f"{Fore.GREEN}Direction-getting type: {Fore.BLUE}" f"Probabilistic") elif self.inputs.traversal == "clos": print(f"{Fore.GREEN}Direction-getting type: " f"{Fore.BLUE}Closest Peak") elif self.inputs.traversal == "det": print(f"{Fore.GREEN}Direction-getting type: " f"{Fore.BLUE}Deterministic Maximum") else: raise ValueError("Direction-getting type not recognized!") print(Style.RESET_ALL) # Commence Ensemble Tractography try: streamlines = track_ensemble( target_samples, labels_im_file_tmp_path_wm_gm_int, labels_im_file_tmp_path, recon_path, get_sphere(sphere), self.inputs.traversal, self.inputs.curv_thr_list, self.inputs.step_list, self.inputs.track_type, self.inputs.maxcrossing, int(roi_neighborhood_tol), self.inputs.min_length, waymask_tmp_path, B0_mask_tmp_path, t1w2dwi_tmp_path, gm_in_dwi_tmp_path, vent_csf_in_dwi_tmp_path, wm_in_dwi_tmp_path, self.inputs.tiss_class) gc.collect() except BaseException as w: print(f"\n{Fore.RED}Tractography failed: {w}") print(Style.RESET_ALL) streamlines = None if streamlines is not None: # import multiprocessing # from pynets.core.utils import kill_process_family # return kill_process_family(int( # multiprocessing.current_process().pid)) # Linear Fascicle Evaluation (LiFE) if use_life is True: print('Using LiFE to evaluate streamline plausibility...') from pynets.dmri.utils import \ evaluate_streamline_plausibility dwi_img = nib.load(dwi_file_tmp_path) dwi_data = dwi_img.get_fdata(dtype=np.float32) orig_count = len(streamlines) if self.inputs.waymask: mask_data = nib.load(waymask_tmp_path).get_fdata( ).astype('bool').astype('int') else: mask_data = nib.load(wm_in_dwi_tmp_path).get_fdata( ).astype('bool').astype('int') try: streamlines = evaluate_streamline_plausibility( dwi_data, gtab, mask_data, streamlines, sphere=sphere) except BaseException: print(f"Linear Fascicle Evaluation failed. " f"Visually checking streamlines output " f"{namer_dir}/{op.basename(streams)} is " f"recommended.") if len(streamlines) < 0.5 * orig_count: raise ValueError('LiFE revealed no plausible ' 'streamlines in the tractogram!') del dwi_data, mask_data # Save streamlines to trk stf = StatefulTractogram(streamlines, fa_img, origin=Origin.NIFTI, space=Space.VOXMM) stf.remove_invalid_streamlines() save_tractogram( stf, streams, ) del stf copyfile( streams, f"{namer_dir}/{op.basename(streams)}", copy=True, use_hardlink=False, ) # Create streamline density map try: [dir_path, dm_path] = create_density_map( dwi_img, dir_path, streamlines, self.inputs.conn_model, self.inputs.node_radius, self.inputs.curv_thr_list, self.inputs.step_list, self.inputs.subnet, self.inputs.roi, self.inputs.traversal, self.inputs.min_length, namer_dir, ) except BaseException: print('Density map failed. Check tractography output.') dm_path = None del streamlines dwi_img.uncache() gc.collect() self._results["dm_path"] = dm_path self._results["streams"] = streams else: self._results["streams"] = None self._results["dm_path"] = None tmp_files = [ gtab_file_tmp_path, wm_in_dwi_tmp_path, gm_in_dwi_tmp_path, vent_csf_in_dwi_tmp_path, t1w2dwi_tmp_path ] for j in tmp_files: if j is not None: if os.path.isfile(j): os.system(f"rm -f {j} &") self._results["track_type"] = self.inputs.track_type self._results["conn_model"] = self.inputs.conn_model self._results["dir_path"] = dir_path self._results["subnet"] = self.inputs.subnet self._results["node_radius"] = self.inputs.node_radius self._results["dens_thresh"] = self.inputs.dens_thresh self._results["ID"] = self.inputs.ID self._results["roi"] = self.inputs.roi self._results["min_span_tree"] = self.inputs.min_span_tree self._results["disp_filt"] = self.inputs.disp_filt self._results["parc"] = self.inputs.parc self._results["prune"] = self.inputs.prune self._results["atlas"] = self.inputs.atlas self._results["parcellation"] = self.inputs.parcellation self._results["labels"] = self.inputs.labels self._results["coords"] = self.inputs.coords self._results["norm"] = self.inputs.norm self._results["binary"] = self.inputs.binary self._results["atlas_t1w"] = self.inputs.atlas_t1w self._results["curv_thr_list"] = self.inputs.curv_thr_list self._results["step_list"] = self.inputs.step_list self._results["fa_path"] = fa_file_tmp_path self._results["traversal"] = self.inputs.traversal self._results["labels_im_file"] = labels_im_file_tmp_path self._results["min_length"] = self.inputs.min_length tmp_files = [B0_mask_tmp_path, dwi_file_tmp_path] for j in tmp_files: if j is not None: if os.path.isfile(j): os.system(f"rm -f {j} &") # Exercise caution when deleting copied recon_path # if recon_path is not None: # if os.path.isfile(recon_path): # os.remove(recon_path) return runtime
def _run_interface(self, runtime): import gc import numpy as np import nibabel as nib try: import cPickle as pickle except ImportError: import _pickle as pickle from dipy.io import load_pickle from colorama import Fore, Style from dipy.data import get_sphere from pynets.core import utils from pynets.dmri.track import prep_tissues, reconstruction, create_density_map, track_ensemble # Load diffusion data dwi_img = nib.load(self.inputs.dwi_file) # Fit diffusion model mod_fit = reconstruction(self.inputs.conn_model, load_pickle(self.inputs.gtab_file), np.asarray(dwi_img.dataobj), self.inputs.B0_mask) # Load atlas parcellation (and its wm-gm interface reduced version for seeding) atlas_data = np.array(nib.load(self.inputs.labels_im_file).dataobj).astype('uint16') atlas_data_wm_gm_int = np.asarray(nib.load(self.inputs.labels_im_file_wm_gm_int).dataobj).astype('uint16') # Build mask vector from atlas for later roi filtering parcels = [] i = 0 for roi_val in np.unique(atlas_data)[1:]: parcels.append(atlas_data == roi_val) i = i + 1 if np.sum(atlas_data) == 0: raise ValueError( 'ERROR: No non-zero voxels found in atlas. Check any roi masks and/or wm-gm interface images ' 'to verify overlap with dwi-registered atlas.') # Iteratively build a list of streamlines for each ROI while tracking print("%s%s%s%s" % (Fore.GREEN, 'Target number of samples: ', Fore.BLUE, self.inputs.target_samples)) print(Style.RESET_ALL) print("%s%s%s%s" % (Fore.GREEN, 'Using curvature threshold(s): ', Fore.BLUE, self.inputs.curv_thr_list)) print(Style.RESET_ALL) print("%s%s%s%s" % (Fore.GREEN, 'Using step size(s): ', Fore.BLUE, self.inputs.step_list)) print(Style.RESET_ALL) print("%s%s%s%s" % (Fore.GREEN, 'Tracking type: ', Fore.BLUE, self.inputs.track_type)) print(Style.RESET_ALL) if self.inputs.directget == 'prob': print("%s%s%s%s" % (Fore.GREEN, 'Direction-getting type: ', Fore.BLUE, 'Probabilistic')) elif self.inputs.directget == 'boot': print("%s%s%s%s" % (Fore.GREEN, 'Direction-getting type: ', Fore.BLUE, 'Bootstrapped')) elif self.inputs.directget == 'closest': print("%s%s%s%s" % (Fore.GREEN, 'Direction-getting type: ', Fore.BLUE, 'Closest Peak')) elif self.inputs.directget == 'det': print("%s%s%s%s" % (Fore.GREEN, 'Direction-getting type: ', Fore.BLUE, 'Deterministic Maximum')) else: raise ValueError('Direction-getting type not recognized!') print(Style.RESET_ALL) # Commence Ensemble Tractography streamlines = track_ensemble(np.asarray(dwi_img.dataobj), self.inputs.target_samples, atlas_data_wm_gm_int, parcels, mod_fit, prep_tissues(self.inputs.t1w2dwi, self.inputs.gm_in_dwi, self.inputs.vent_csf_in_dwi, self.inputs.wm_in_dwi, self.inputs.tiss_class), get_sphere(self.inputs.sphere), self.inputs.directget, self.inputs.curv_thr_list, self.inputs.step_list, self.inputs.track_type, self.inputs.maxcrossing, int(self.inputs.roi_neighborhood_tol), self.inputs.min_length, self.inputs.waymask) # Create streamline density map [streams, dir_path, dm_path] = create_density_map(dwi_img, utils.do_dir_path(self.inputs.atlas, self.inputs.dwi_file), streamlines, self.inputs.conn_model, self.inputs.target_samples, self.inputs.node_size, self.inputs.curv_thr_list, self.inputs.step_list, self.inputs.network, self.inputs.roi, self.inputs.directget, self.inputs.min_length) self._results['streams'] = streams self._results['track_type'] = self.inputs.track_type self._results['target_samples'] = self.inputs.target_samples self._results['conn_model'] = self.inputs.conn_model self._results['dir_path'] = dir_path self._results['network'] = self.inputs.network self._results['node_size'] = self.inputs.node_size self._results['dens_thresh'] = self.inputs.dens_thresh self._results['ID'] = self.inputs.ID self._results['roi'] = self.inputs.roi self._results['min_span_tree'] = self.inputs.min_span_tree self._results['disp_filt'] = self.inputs.disp_filt self._results['parc'] = self.inputs.parc self._results['prune'] = self.inputs.prune self._results['atlas'] = self.inputs.atlas self._results['uatlas'] = self.inputs.uatlas self._results['labels'] = self.inputs.labels self._results['coords'] = self.inputs.coords self._results['norm'] = self.inputs.norm self._results['binary'] = self.inputs.binary self._results['atlas_mni'] = self.inputs.atlas_mni self._results['curv_thr_list'] = self.inputs.curv_thr_list self._results['step_list'] = self.inputs.step_list self._results['fa_path'] = self.inputs.fa_path self._results['dm_path'] = dm_path self._results['directget'] = self.inputs.directget self._results['labels_im_file'] = self.inputs.labels_im_file self._results['roi_neighborhood_tol'] = self.inputs.roi_neighborhood_tol self._results['min_length'] = self.inputs.min_length del streamlines, atlas_data_wm_gm_int, atlas_data, mod_fit, parcels dwi_img.uncache() gc.collect() return runtime