def transform_to_affine(streams, header, affine): try: from dipy.tracking.utils import transform_tracking_output except ImportError: from dipy.tracking.utils import move_streamlines as transform_tracking_output rotation, scale = np.linalg.qr(affine) streams = transform_tracking_output(streams, rotation) scale[0:3, 0:3] = np.dot(scale[0:3, 0:3], np.diag(1.0 / header["voxel_size"])) scale[0:3, 3] = abs(scale[0:3, 3]) streams = transform_tracking_output(streams, scale) return streams
def test_streamline_registration(): sl1 = [np.array([[0, 0, 0], [0, 0, 0.5], [0, 0, 1], [0, 0, 1.5]]), np.array([[0, 0, 0], [0, 0.5, 0.5], [0, 1, 1]])] affine_mat = np.eye(4) affine_mat[:3, 3] = np.random.randn(3) sl2 = list(transform_tracking_output(sl1, affine_mat)) aligned, matrix = streamline_registration(sl2, sl1) npt.assert_almost_equal(matrix, np.linalg.inv(affine_mat)) npt.assert_almost_equal(aligned[0], sl1[0]) npt.assert_almost_equal(aligned[1], sl1[1]) # We assume the two tracks come from the same space, but it might have # some affine associated with it: base_aff = np.eye(4) * np.random.rand() base_aff[:3, 3] = np.array([1, 2, 3]) base_aff[3, 3] = 1 with nbtmp.InTemporaryDirectory() as tmpdir: for use_aff in [None, base_aff]: fname1 = op.join(tmpdir, 'sl1.trk') fname2 = op.join(tmpdir, 'sl2.trk') if use_aff is not None: img = nib.Nifti1Image(np.zeros((2, 2, 2)), use_aff) # Move the streamlines to this other space, and report it: tgm1 = StatefulTractogram( transform_tracking_output(sl1, np.linalg.inv(use_aff)), img, Space.VOX) save_trk(tgm1, fname1, bbox_valid_check=False) tgm2 = StatefulTractogram( transform_tracking_output(sl2, np.linalg.inv(use_aff)), img, Space.VOX) save_trk(tgm2, fname2, bbox_valid_check=False) else: img = nib.Nifti1Image(np.zeros((2, 2, 2)), np.eye(4)) tgm1 = StatefulTractogram(sl1, img, Space.RASMM) tgm2 = StatefulTractogram(sl2, img, Space.RASMM) save_trk(tgm1, fname1, bbox_valid_check=False) save_trk(tgm2, fname2, bbox_valid_check=False) aligned, matrix = streamline_registration(fname2, fname1) npt.assert_almost_equal(aligned[0], sl1[0], decimal=5) npt.assert_almost_equal(aligned[1], sl1[1], decimal=5)
def _export_bundles(self, row): odf_model = self.tracking_params['odf_model'] directions = self.tracking_params['directions'] seg_algo = self.segmentation_params['seg_algo'] for func, folder in zip([self._clean_bundles, self._segment], ['clean_bundles', 'bundles']): bundles_file = func(row) bundles_dir = op.join(row['results_dir'], folder) os.makedirs(bundles_dir, exist_ok=True) trk = nib.streamlines.load(bundles_file) tg = trk.tractogram streamlines = tg.streamlines for bundle in self.bundle_dict: if bundle != "whole_brain": uid = self.bundle_dict[bundle]['uid'] idx = np.where(tg.data_per_streamline['bundle'] == uid)[0] this_sl = dtu.transform_tracking_output( streamlines[idx], np.linalg.inv(row['dwi_affine'])) this_tgm = StatefulTractogram(this_sl, row['dwi_img'], Space.VOX) fname = op.split( self._get_fname( row, f'_space-RASMM_model-{odf_model}_desc-' f'{directions}-{seg_algo}-{bundle}' f'_tractography.trk')) fname = op.join(fname[0], bundles_dir, fname[1]) save_tractogram(this_tgm, fname, bbox_valid_check=False) meta = dict(source=bundles_file) meta_fname = fname.split('.')[0] + '.json' afd.write_json(meta_fname, meta)
def _apply_affine_sft(self, sft, affine, reference, origin): sls = dtu.transform_tracking_output(sft.streamlines, affine) return StatefulTractogram(sls, reference, self.space, origin=origin, data_per_streamline=sft.data_per_streamline)
def __iter__(self): # Make tracks, move them to point space and return track = self._generate_tractogram() return utils.transform_tracking_output(track, self.affine, save_seeds=self.save_seeds)
def export_bundles(subses_dict, clean_bundles_file, bundles_file, bundle_dict, tracking_params, segmentation_params): img = nib.load(subses_dict['dwi_file']) for this_bundles_file, folder in zip([clean_bundles_file, bundles_file], ['clean_bundles', 'bundles']): bundles_dir = op.join(subses_dict['results_dir'], folder) os.makedirs(bundles_dir, exist_ok=True) trk = nib.streamlines.load(this_bundles_file) tg = trk.tractogram streamlines = tg.streamlines for bundle in bundle_dict: if bundle != "whole_brain": uid = bundle_dict[bundle]['uid'] idx = np.where(tg.data_per_streamline['bundle'] == uid)[0] this_sl = dtu.transform_tracking_output( streamlines[idx], np.linalg.inv(img.affine)) this_tgm = StatefulTractogram(this_sl, img, Space.VOX) fname = op.split( get_fname(subses_dict, f'-{bundle}' f'_tractography.trk', tracking_params=tracking_params, segmentation_params=segmentation_params)) fname = op.join(bundles_dir, fname[1]) logger.info(f"Saving {fname}") save_tractogram(this_tgm, fname, bbox_valid_check=False) meta = dict(source=this_bundles_file) meta_fname = fname.split('.')[0] + '.json' afd.write_json(meta_fname, meta) return True
def streamline_registration(moving, static, n_points=100, native_resampled=False): """ Register two collections of streamlines ('bundles') to each other Parameters ---------- moving, static : lists of 3 by n, or str The two bundles to be registered. Given either as lists of arrays with 3D coordinates, or strings containing full paths to these files. n_points : int, optional How many points to resample to. Default: 100. native_resampled : bool, optional Whether to return the moving bundle in the original space, but resampled in the static space to n_points. Returns ------- aligned : list Streamlines from the moving group, moved to be closely matched to the static group. matrix : array (4, 4) The affine transformation that takes us from 'moving' to 'static' """ # Load the streamlines, if you were given a file-name if isinstance(moving, str): moving = load_trk(moving, 'same', bbox_valid_check=False).streamlines if isinstance(static, str): static = load_trk(static, 'same', bbox_valid_check=False).streamlines srr = StreamlineLinearRegistration() srm = srr.optimize(static=set_number_of_points(static, n_points), moving=set_number_of_points(moving, n_points)) aligned = srm.transform(moving) if native_resampled: aligned = set_number_of_points(aligned, n_points) aligned = transform_tracking_output(aligned, np.linalg.inv(srm.matrix)) return aligned, srm.matrix
gtab, template=MNI_T2_img) reg.write_mapping(mapping, './mapping.nii.gz') else: mapping = reg.read_mapping('./mapping.nii.gz', img, MNI_T2_img) bundle_names = ["CST", "UF", "CC_ForcepsMajor", "CC_ForcepsMinor"] bundles = api.make_bundle_dict(bundle_names=bundle_names, seg_algo="reco") print("Tracking...") if not op.exists('dti_streamlines_reco.trk'): seed_roi = np.zeros(img.shape[:-1]) for bundle in bundles: if bundle != 'whole_brain': sl_xform = dts.Streamlines( dtu.transform_tracking_output(bundles[bundle]['sl'], MNI_T2_img.affine)) delta = dts.values_from_volume(mapping.backward, sl_xform, np.eye(4)) sl_xform = [sum(d, s) for d, s in zip(delta, sl_xform)] sl_xform = dts.Streamlines( dtu.transform_tracking_output(sl_xform, np.linalg.inv( MNI_T2_img.affine))) sft = StatefulTractogram(sl_xform, img, Space.RASMM) save_tractogram(sft, f'./{bundle}_atlas.trk') sl_xform = dts.Streamlines( dtu.transform_tracking_output(sl_xform,
def _run_interface(self, runtime): from dipy.tracking.utils import affine_from_fsl_mat_file try: from dipy.tracking.utils import transform_tracking_output except ImportError: from dipy.tracking.utils import ( move_streamlines as transform_tracking_output, ) dx, dy, dz = get_data_dims(self.inputs.image_file) vx, vy, vz = get_vox_dims(self.inputs.image_file) image_file = nb.load(self.inputs.image_file) affine = image_file.affine out_filename = op.abspath(self.inputs.out_filename) # Reads MRTrix tracks header, streamlines = read_mrtrix_tracks(self.inputs.in_file, as_generator=True) iflogger.info("MRTrix Header:") iflogger.info(header) # Writes to Trackvis trk_header = nb.trackvis.empty_header() trk_header["dim"] = [dx, dy, dz] trk_header["voxel_size"] = [vx, vy, vz] trk_header["n_count"] = header["count"] if isdefined(self.inputs.matrix_file) and isdefined( self.inputs.registration_image_file): iflogger.info("Applying transformation from matrix file %s", self.inputs.matrix_file) xfm = np.genfromtxt(self.inputs.matrix_file) iflogger.info(xfm) registration_image_file = nb.load( self.inputs.registration_image_file) reg_affine = registration_image_file.affine r_dx, r_dy, r_dz = get_data_dims( self.inputs.registration_image_file) r_vx, r_vy, r_vz = get_vox_dims( self.inputs.registration_image_file) iflogger.info( "Using affine from registration image file %s", self.inputs.registration_image_file, ) iflogger.info(reg_affine) trk_header["vox_to_ras"] = reg_affine trk_header["dim"] = [r_dx, r_dy, r_dz] trk_header["voxel_size"] = [r_vx, r_vy, r_vz] affine = np.dot(affine, np.diag(1.0 / np.array([vx, vy, vz, 1]))) transformed_streamlines = transform_to_affine( streamlines, trk_header, affine) aff = affine_from_fsl_mat_file(xfm, [vx, vy, vz], [r_vx, r_vy, r_vz]) iflogger.info(aff) axcode = aff2axcodes(reg_affine) trk_header["voxel_order"] = axcode[0] + axcode[1] + axcode[2] final_streamlines = transform_tracking_output( transformed_streamlines, aff) trk_tracks = ((ii, None, None) for ii in final_streamlines) trk.write(out_filename, trk_tracks, trk_header) iflogger.info("Saving transformed Trackvis file as %s", out_filename) iflogger.info("New TrackVis Header:") iflogger.info(trk_header) else: iflogger.info( "Applying transformation from scanner coordinates to %s", self.inputs.image_file, ) axcode = aff2axcodes(affine) trk_header["voxel_order"] = axcode[0] + axcode[1] + axcode[2] trk_header["vox_to_ras"] = affine transformed_streamlines = transform_to_affine( streamlines, trk_header, affine) trk_tracks = ((ii, None, None) for ii in transformed_streamlines) trk.write(out_filename, trk_tracks, trk_header) iflogger.info("Saving Trackvis file as %s", out_filename) iflogger.info("TrackVis Header:") iflogger.info(trk_header) return runtime
def test_AFQ_data_waypoint(): """ Test with some actual data again, this time for track segmentation """ tmpdir, bids_path, _ = get_temp_hardi() bundle_names = ["SLF", "ARC", "CST", "FP"] tracking_params = dict(odf_model="dti", seed_mask=RoiMask(), n_seeds=100, random_seeds=True, rng_seed=42) segmentation_params = dict(filter_by_endpoints=False, seg_algo="AFQ", return_idx=True) clean_params = dict(return_idx=True) myafq = api.AFQ(bids_path=bids_path, dmriprep='vistasoft', bundle_info=bundle_names, scalars=["dti_FA", "dti_MD"], robust_tensor_fitting=True, tracking_params=tracking_params, segmentation_params=segmentation_params, clean_params=clean_params) # Replace the mapping and streamlines with precomputed: file_dict = afd.read_stanford_hardi_tractography() mapping = file_dict['mapping.nii.gz'] streamlines = file_dict['tractography_subsampled.trk'] streamlines = dts.Streamlines( dtu.transform_tracking_output( [s for s in streamlines if s.shape[0] > 100], np.linalg.inv(myafq.dwi_affine[0]))) mapping_file = op.join( myafq.data_frame.results_dir[0], 'sub-01_ses-01_dwi_mapping_from-DWI_to_MNI_xfm.nii.gz') nib.save(mapping, mapping_file) reg_prealign_file = op.join( myafq.data_frame.results_dir[0], 'sub-01_ses-01_dwi_prealign_from-DWI_to-MNI_xfm.npy') np.save(reg_prealign_file, np.eye(4)) tgram = load_tractogram(myafq.bundles[0], myafq.dwi_img[0]) bundles = aus.tgram_to_bundles(tgram, myafq.bundle_dict, myafq.dwi_img[0]) npt.assert_(len(bundles['CST_L']) > 0) # Test ROI exporting: myafq.export_rois() assert op.exists( op.join(myafq.data_frame['results_dir'][0], 'ROIs', 'sub-01_ses-01_dwi_desc-ROI-CST_R-1-include.json')) # Test bundles exporting: myafq.export_bundles() assert op.exists( op.join( myafq.data_frame['results_dir'][0], 'bundles', 'sub-01_ses-01_dwi_space-RASMM_model-DTI_desc-det-AFQ-CST_L_tractography.trk' )) # noqa # Test creation of file with bundle indices: assert op.exists( op.join( myafq.data_frame['results_dir'][0], 'sub-01_ses-01_dwi_space-RASMM_model-DTI_desc-det-AFQ-clean_tractography_idx.json' )) # noqa tract_profiles = pd.read_csv(myafq.tract_profiles[0]) assert tract_profiles.shape == (400, 5) myafq.plot_tract_profiles() assert op.exists( op.join( myafq.data_frame['results_dir'][0], 'sub-01_ses-01_dwi_space-RASMM_model-DTI_desc-det-AFQ_dti_fa_profile_plots.png' )) # noqa assert op.exists( op.join( myafq.data_frame['results_dir'][0], 'sub-01_ses-01_dwi_space-RASMM_model-DTI_desc-det-AFQ_dti_md_profile_plots.png' )) # noqa # Before we run the CLI, we'll remove the bundles and ROI folders, to see # that the CLI generates them shutil.rmtree(op.join(myafq.data_frame['results_dir'][0], 'bundles')) shutil.rmtree(op.join(myafq.data_frame['results_dir'][0], 'ROIs')) # Test the CLI: print("Running the CLI:") # Set up config to use the same parameters as above: # ROI mask needs to be put in quotes in config tracking_params = dict(odf_model="DTI", seed_mask="RoiMask()", n_seeds=100, random_seeds=True, rng_seed=42) config = dict(BIDS=dict(bids_path=bids_path, dmriprep='vistasoft'), REGISTRATION=dict(robust_tensor_fitting=True), BUNDLES=dict(bundle_info=bundle_names, scalars=["dti_fa", "dti_md"]), VIZ=dict(viz_backend="plotly_no_gif"), TRACTOGRAPHY=tracking_params, SEGMENTATION=segmentation_params, CLEANING=clean_params) config_file = op.join(tmpdir.name, "afq_config.toml") with open(config_file, 'w') as ff: toml.dump(config, ff) cmd = "pyAFQ " + config_file out = os.system(cmd) assert out == 0 # The combined tract profiles should already exist from the CLI Run: from_file = pd.read_csv( myafq._get_fname(myafq.data_frame.iloc[0], '_profiles.csv')) # And should be identical to what we would get by rerunning this: combined_profiles = myafq.combine_profiles() assert combined_profiles.shape == (400, 7) assert_series_equal(combined_profiles['dti_fa'], from_file['dti_fa']) # Make sure the CLI did indeed generate these: myafq.export_rois() assert op.exists( op.join(myafq.data_frame['results_dir'][0], 'ROIs', 'sub-01_ses-01_dwi_desc-ROI-CST_R-1-include.json')) myafq.export_bundles() assert op.exists( op.join( myafq.data_frame['results_dir'][0], 'bundles', 'sub-01_ses-01_dwi_space-RASMM_model-DTI_desc-det-AFQ-CST_L_tractography.trk' )) # noqa
def test_AFQ_data_waypoint(): """ Test with some actual data again, this time for track segmentation """ tmpdir = nbtmp.InTemporaryDirectory() afd.organize_stanford_data(path=tmpdir.name) dmriprep_path = op.join(tmpdir.name, 'stanford_hardi', 'derivatives', 'dmriprep') bundle_names = ["SLF", "ARC", "CST", "FP"] tracking_params = dict(odf_model="DTI") segmentation_params = dict(filter_by_endpoints=False, seg_algo="AFQ", return_idx=True) clean_params = dict(return_idx=True) myafq = api.AFQ(dmriprep_path=dmriprep_path, sub_prefix='sub', bundle_names=bundle_names, scalars=["dti_fa", "dti_md"], tracking_params=tracking_params, segmentation_params=segmentation_params, clean_params=clean_params) # Replace the mapping and streamlines with precomputed: file_dict = afd.read_stanford_hardi_tractography() mapping = file_dict['mapping.nii.gz'] streamlines = file_dict['tractography_subsampled.trk'] streamlines = dts.Streamlines( dtu.transform_tracking_output( [s for s in streamlines if s.shape[0] > 100], np.linalg.inv(myafq.dwi_affine[0]))) sl_file = op.join( myafq.data_frame.results_dir[0], 'sub-01_sess-01_dwi_space-RASMM_model-DTI_desc-det_tractography.trk') sft = StatefulTractogram(streamlines, myafq.data_frame.dwi_file[0], Space.VOX) save_tractogram(sft, sl_file, bbox_valid_check=False) mapping_file = op.join( myafq.data_frame.results_dir[0], 'sub-01_sess-01_dwi_mapping_from-DWI_to_MNI_xfm.nii.gz') nib.save(mapping, mapping_file) reg_prealign_file = op.join( myafq.data_frame.results_dir[0], 'sub-01_sess-01_dwi_prealign_from-DWI_to-MNI_xfm.npy') np.save(reg_prealign_file, np.eye(4)) tgram = load_tractogram(myafq.bundles[0], myafq.dwi_img[0]) bundles = aus.tgram_to_bundles(tgram, myafq.bundle_dict, myafq.dwi_img[0]) npt.assert_(len(bundles['CST_R']) > 0) # Test ROI exporting: myafq.export_rois() assert op.exists(op.join( myafq.data_frame['results_dir'][0], 'ROIs', 'sub-01_sess-01_dwi_desc-ROI-CST_R-1-include.json')) # Test bundles exporting: myafq.export_bundles() assert op.exists(op.join( myafq.data_frame['results_dir'][0], 'bundles', 'sub-01_sess-01_dwi_space-RASMM_model-DTI_desc-det-AFQ-CST_L_tractography.trk')) # noqa # Test creation of file with bundle indices: assert op.exists(op.join( myafq.data_frame['results_dir'][0], 'sub-01_sess-01_dwi_space-RASMM_model-DTI_desc-det-AFQ-clean_tractography_idx.json')) # noqa tract_profiles = pd.read_csv(myafq.tract_profiles[0]) assert tract_profiles.shape == (800, 5) # Before we run the CLI, we'll remove the bundles and ROI folders, to see # that the CLI generates them shutil.rmtree(op.join(myafq.data_frame['results_dir'][0], 'bundles')) shutil.rmtree(op.join(myafq.data_frame['results_dir'][0], 'ROIs')) # Test the CLI: print("Running the CLI:") # Bare bones config only points to the files config = dict(files=dict(dmriprep_path=dmriprep_path)) config_file = op.join(tmpdir.name, "afq_config.toml") with open(config_file, 'w') as ff: toml.dump(config, ff) cmd = "pyAFQ " + config_file out = os.system(cmd) assert out == 0 # The combined tract profiles should already exist from the CLI Run: from_file = pd.read_csv(op.join(myafq.afq_dir, 'tract_profiles.csv')) # And should be identical to what we would get by rerunning this: combined_profiles = myafq.combine_profiles() assert combined_profiles.shape == (800, 7) assert_frame_equal(combined_profiles, from_file) # Make sure the CLI did indeed generate these: myafq.export_rois() assert op.exists(op.join( myafq.data_frame['results_dir'][0], 'ROIs', 'sub-01_sess-01_dwi_desc-ROI-CST_R-1-include.json')) myafq.export_bundles() assert op.exists(op.join( myafq.data_frame['results_dir'][0], 'bundles', 'sub-01_sess-01_dwi_space-RASMM_model-DTI_desc-det-AFQ-CST_L_tractography.trk')) # noqa
def test_AFQ_data_waypoint(): """ Test with some actual data again, this time for track segmentation """ tmpdir, bids_path, _ = get_temp_hardi() t1_path = op.join(tmpdir.name, "T1.nii.gz") nib.save(afd.read_mni_template(mask=True, weight="T1w"), t1_path) bundle_names = ["SLF", "ARC", "CST", "FP"] tracking_params = dict(odf_model="dti", seed_mask=RoiMask(), n_seeds=100, random_seeds=True, rng_seed=42) segmentation_params = dict(filter_by_endpoints=False, seg_algo="AFQ", return_idx=True) clean_params = dict(return_idx=True) myafq = api.AFQ( bids_path=bids_path, dmriprep='vistasoft', bundle_info=bundle_names, scalars=["dti_FA", "dti_MD", TemplateScalar("T1", t1_path)], robust_tensor_fitting=True, tracking_params=tracking_params, segmentation_params=segmentation_params, clean_params=clean_params) # Replace the mapping and streamlines with precomputed: file_dict = afd.read_stanford_hardi_tractography() mapping = file_dict['mapping.nii.gz'] streamlines = file_dict['tractography_subsampled.trk'] streamlines = dts.Streamlines( dtu.transform_tracking_output( [s for s in streamlines if s.shape[0] > 100], np.linalg.inv(myafq.dwi_affine["01"]))) mapping_file = op.join( myafq.results_dir["01"], 'sub-01_ses-01_dwi_mapping_from-DWI_to_MNI_xfm.nii.gz') nib.save(mapping, mapping_file) reg_prealign_file = op.join( myafq.results_dir["01"], 'sub-01_ses-01_dwi_prealign_from-DWI_to-MNI_xfm.npy') np.save(reg_prealign_file, np.eye(4)) tgram = load_tractogram(myafq.bundles["01"], myafq.img["01"]) bundles = aus.tgram_to_bundles(tgram, myafq.bundle_dict, myafq.img["01"]) npt.assert_(len(bundles['CST_L']) > 0) # Test ROI exporting: myafq.export_rois() assert op.exists( op.join(myafq.results_dir["01"], 'ROIs', 'sub-01_ses-01_dwi_desc-ROI-CST_R-1-include.json')) # Test bundles exporting: myafq.export_indiv_bundles() assert op.exists( op.join( myafq.results_dir["01"], 'bundles', 'sub-01_ses-01_dwi_space-RASMM_model-DTI_desc-det-AFQ-CST_L_tractography.trk' )) # noqa tract_profile_fname = myafq.profiles["01"] tract_profiles = pd.read_csv(tract_profile_fname) assert tract_profiles.shape == (500, 6) myafq.tract_profile_plots assert op.exists( op.join( myafq.results_dir["01"], "tract_profile_plots", 'sub-01_ses-01_dwi_space-RASMM_model-DTI_desc-det-AFQ_dti_fa_profile_plots.png' )) # noqa assert op.exists( op.join( myafq.results_dir["01"], "tract_profile_plots", 'sub-01_ses-01_dwi_space-RASMM_model-DTI_desc-det-AFQ_dti_md_profile_plots.png' )) # noqa # Before we run the CLI, we'll remove the bundles and ROI folders, to see # that the CLI generates them shutil.rmtree(op.join(myafq.results_dir["01"], 'bundles')) shutil.rmtree(op.join(myafq.results_dir["01"], 'ROIs')) os.remove(tract_profile_fname) # Test the CLI: print("Running the CLI:") # Set up config to use the same parameters as above: # ROI mask needs to be put in quotes in config tracking_params = dict(odf_model="DTI", seed_mask="RoiMask()", n_seeds=100, random_seeds=True, rng_seed=42) config = dict(BIDS=dict(bids_path=bids_path, dmriprep='vistasoft'), DATA=dict(robust_tensor_fitting=True), BUNDLES=dict(bundle_info=bundle_names, scalars=[ "dti_fa", "dti_md", f"TemplateScalar('T1', '{t1_path}')" ]), VIZ=dict(viz_backend="plotly_no_gif"), TRACTOGRAPHY=tracking_params, SEGMENTATION=segmentation_params, CLEANING=clean_params) config_file = op.join(tmpdir.name, "afq_config.toml") with open(config_file, 'w') as ff: toml.dump(config, ff) # save memory results_dir = myafq.results_dir["01"] del myafq gc.collect() cmd = "pyAFQ " + config_file completed_process = subprocess.run(cmd, shell=True, capture_output=True) if completed_process.returncode != 0: print(completed_process.stdout) print(completed_process.stderr) assert completed_process.returncode == 0 # The tract profiles should already exist from the CLI Run: from_file = pd.read_csv(tract_profile_fname) assert from_file.shape == (500, 6) assert_series_equal(tract_profiles['dti_fa'], from_file['dti_fa']) # Make sure the CLI did indeed generate these: assert op.exists( op.join(results_dir, 'ROIs', 'sub-01_ses-01_dwi_desc-ROI-CST_R-1-include.json')) assert op.exists( op.join( results_dir, 'bundles', 'sub-01_ses-01_dwi_space-RASMM_model-DTI_desc-det-AFQ-CST_L_tractography.trk' )) # noqa