diff --git a/.python-version b/.python-version index c8cfe3959..7c7a975f4 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.10 +3.10 \ No newline at end of file diff --git a/scilpy/tractograms/dps_and_dpp_management.py b/scilpy/tractograms/dps_and_dpp_management.py new file mode 100644 index 000000000..1f85ef2dc --- /dev/null +++ b/scilpy/tractograms/dps_and_dpp_management.py @@ -0,0 +1,204 @@ +# -*- coding: utf-8 -*- +import numpy as np + + +def project_map_to_streamlines(sft, map_volume, endpoints_only=False): + """ + Projects a map onto the points of streamlines. + + Parameters + ---------- + sft: StatefulTractogram + Input tractogram. + map_volume: DataVolume + Input map. + + Optional: + --------- + endpoints_only: bool + If True, will only project the map_volume onto the endpoints of the + streamlines (all values along streamlines set to zero). If False, + will project the map_volume onto all points of the streamlines. + + Returns + ------- + streamline_data: + map_volume projected to each point of the streamlines. + """ + if len(map_volume.data.shape) == 4: + dimension = map_volume.data.shape[3] + else: + dimension = 1 + + streamline_data = [] + if endpoints_only: + for s in sft.streamlines: + p1_data = map_volume.get_value_at_coordinate( + s[0][0], s[0][1], s[0][2], + space=sft.space, origin=sft.origin) + p2_data = map_volume.get_value_at_coordinate( + s[-1][0], s[-1][1], s[-1][2], + space=sft.space, origin=sft.origin) + + thisstreamline_data = np.ones((len(s), dimension)) * np.nan + + thisstreamline_data[0] = p1_data + thisstreamline_data[-1] = p2_data + thisstreamline_data = np.asarray(thisstreamline_data) + + streamline_data.append( + np.reshape(thisstreamline_data, + (len(thisstreamline_data), dimension))) + else: + for s in sft.streamlines: + thisstreamline_data = [] + for p in s: + thisstreamline_data.append(map_volume.get_value_at_coordinate( + p[0], p[1], p[2], space=sft.space, origin=sft.origin)) + + streamline_data.append( + np.reshape(thisstreamline_data, + (len(thisstreamline_data), dimension))) + + return streamline_data + + +def perform_streamline_operation_per_point(op_name, sft, dpp_name='metric', + endpoints_only=False): + """Peforms an operation per point for all streamlines. + + Parameters + ---------- + op_name: str + A callable that takes a list of streamline data per point (4D) and + returns a list of streamline data per point. + sft: StatefulTractogram + The streamlines used in the operation. + dpp_name: str + The name of the data per point to be used in the operation. + endpoints_only: bool + If True, will only perform operation on endpoints + + Returns + ------- + new_sft: StatefulTractogram + sft with data per streamline resulting from the operation. + """ + + # Performing operation + call_op = OPERATIONS[op_name] + if endpoints_only: + new_data_per_point = [] + for s in sft.data_per_point[dpp_name]: + this_data_per_point = np.nan * np.ones((len(s), 1)) + this_data_per_point[0] = call_op(s[0]) + this_data_per_point[-1] = call_op(s[-1]) + new_data_per_point.append( + np.reshape(this_data_per_point, (len(this_data_per_point), 1))) + else: + new_data_per_point = [] + for s in sft.data_per_point[dpp_name]: + this_data_per_point = [] + for p in s: + this_data_per_point.append(call_op(p)) + new_data_per_point.append( + np.reshape(this_data_per_point, (len(this_data_per_point), 1))) + + # Extracting streamlines + return new_data_per_point + + +def perform_operation_per_streamline(op_name, sft, dpp_name='metric', + endpoints_only=False): + """Performs an operation across all data points for each streamline. + + Parameters + ---------- + op_name: str + A callable that takes a list of streamline data per streamline and + returns a list of data per streamline. + sft: StatefulTractogram + The streamlines used in the operation. + dpp_name: str + The name of the data per point to be used in the operation. + endpoints_only: bool + If True, will only perform operation on endpoints + + Returns + ------- + new_sft: StatefulTractogram + sft with data per streamline resulting from the operation. + """ + # Performing operation + call_op = OPERATIONS[op_name] + if endpoints_only: + new_data_per_streamline = [] + for s in sft.data_per_point[dpp_name]: + start = s[0] + end = s[-1] + concat = np.concatenate((start[:], end[:])) + new_data_per_streamline.append(call_op(concat)) + else: + new_data_per_streamline = [] + for s in sft.data_per_point[dpp_name]: + s_np = np.asarray(s) + new_data_per_streamline.append(call_op(s_np)) + + return new_data_per_streamline + + +def perform_pairwise_streamline_operation_on_endpoints(op_name, sft, + dpp_name='metric'): + """Peforms an operation across endpoints for each streamline. + + Parameters + ---------- + op_name: str + A callable that takes a list of streamline data per streamline and + returns a list of data per streamline. + sft: StatefulTractogram + The streamlines used in the operation. + dpp_name: str + The name of the data per point to be used in the operation. + + Returns + ------- + new_sft: StatefulTractogram + sft with data per streamline resulting from the operation. + """ + # Performing operation + call_op = OPERATIONS[op_name] + new_data_per_streamline = [] + for s in sft.data_per_point[dpp_name]: + new_data_per_streamline.append(call_op(s[0], s[-1])[0, 1]) + + return new_data_per_streamline + + +def stream_mean(array): + return np.squeeze(np.mean(array, axis=0)) + + +def stream_sum(array): + return np.squeeze(np.sum(array, axis=0)) + + +def stream_min(array): + return np.squeeze(np.min(array, axis=0)) + + +def stream_max(array): + return np.squeeze(np.max(array, axis=0)) + + +def stream_correlation(array1, array2): + return np.corrcoef(array1, array2) + + +OPERATIONS = { + 'mean': stream_mean, + 'sum': stream_sum, + 'min': stream_min, + 'max': stream_max, + 'correlation': stream_correlation, +} diff --git a/scilpy/tractograms/streamline_operations.py b/scilpy/tractograms/streamline_operations.py index 18d247df1..7df3a396c 100644 --- a/scilpy/tractograms/streamline_operations.py +++ b/scilpy/tractograms/streamline_operations.py @@ -84,7 +84,6 @@ def _get_point_on_line(first_point, second_point, vox_lower_corner): return first_point + ray * (t0 + t1) / 2. - def filter_streamlines_by_length(sft, min_length=0., max_length=np.inf): """ Filter streamlines using minimum and max length. diff --git a/scilpy/tractograms/tests/test_dps_and_dpp_management.py b/scilpy/tractograms/tests/test_dps_and_dpp_management.py new file mode 100644 index 000000000..1fc2a7e88 --- /dev/null +++ b/scilpy/tractograms/tests/test_dps_and_dpp_management.py @@ -0,0 +1,18 @@ +def test_project_map_to_streamlines(): + # toDo + pass + + +def test_perform_streamline_operation_per_point(): + # toDo + pass + + +def test_perform_operation_per_streamline(): + # toDo + pass + + +def test_perform_streamline_operation_on_endpoints(): + # toDo + pass diff --git a/scripts/scil_tractogram_dpp_math.py b/scripts/scil_tractogram_dpp_math.py new file mode 100755 index 000000000..bedaace47 --- /dev/null +++ b/scripts/scil_tractogram_dpp_math.py @@ -0,0 +1,223 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +Performs an operation on data per point (dpp) from input streamlines. + +Although the input data always comes from the dpp, the output can be either +a dpp or a data_per_streamline (dps), depending on the chosen options. +Two modes of operation are supported: dpp and dps. + - In dps mode, the operation is performed on dpp across the dimension of + the streamlines resulting in a single value (or array in the 4D case) + per streamline, stored as dps. + - In dpp mode, the operation is performed on each point separately, + resulting in a new dpp. + +If endpoints_only and dpp mode is set the operation will only +be calculated at the streamline endpoints the rest of the +values along the streamline will be NaN + +If endpoints_only and dps mode is set operation will be calculated +across the data at the endpoints and stored as a +single value (or array in the 4D case) per streamline. + +Endpoint only operation: +correlation: correlation calculated between arrays extracted from +streamline endpoints (data must be multivalued per point) and dps +mode must be set. +""" + +import argparse +import logging + +from dipy.io.streamline import save_tractogram, StatefulTractogram + +from scilpy.io.streamlines import load_tractogram_with_reference +from scilpy.io.utils import (add_bbox_arg, + add_overwrite_arg, + add_reference_arg, + add_verbose_arg, + assert_inputs_exist, + assert_outputs_exist) +from scilpy.tractograms.dps_and_dpp_management import ( + perform_pairwise_streamline_operation_on_endpoints, + perform_streamline_operation_per_point, + perform_operation_per_streamline) + + +def _build_arg_parser(): + p = argparse.ArgumentParser( + formatter_class=argparse.RawTextHelpFormatter, + description=__doc__) + + p.add_argument('operation', metavar='OPERATION', + choices=['mean', 'sum', 'min', + 'max', 'correlation'], + help='The type of operation to be performed on the \n' + 'streamlines. Must\nbe one of the following: \n' + '%(choices)s.') + p.add_argument('in_tractogram', metavar='INPUT_FILE', + help='Input tractogram containing streamlines and \n' + 'metadata.') + p.add_argument('--mode', required=True, choices=['dpp', 'dps'], + help='Set to dps if the operation is to be performed \n' + 'across all dimensions resulting in a single value per \n' + 'streamline. Set to dpp if the operation is to be \n' + 'performed on each point separately resulting in a \n' + 'single value per point.') + p.add_argument('--in_dpp_name', nargs='+', required=True, + help='Name or list of names of the data_per_point for \n' + 'operation to be performed on. If more than one dpp \n' + 'is selected, the same operation will be applied \n' + 'separately to each one.') + p.add_argument('--out_name', nargs='+', required=True, + help='Name of the resulting data_per_point or \n' + 'data_per_streamline to be saved in the output \n' + 'tractogram. If more than one --in_dpp_name was used, \n' + 'enter the same number of --out_name values.') + p.add_argument('out_tractogram', metavar='OUTPUT_FILE', + help='The file where the remaining streamlines \n' + 'are saved.') + p.add_argument('--endpoints_only', action='store_true', default=False, + help='If set, will only perform operation on endpoints \n' + 'If not set, will perform operation on all streamline \n' + 'points.') + p.add_argument('--keep_all_dpp_dps', action='store_true', + help='If set, previous data_per_point will be preserved \n' + 'in the output tractogram. Else, only --out_dpp_name \n' + 'keys will be saved.') + p.add_argument('--overwrite_dpp_dps', action='store_true', + help='If set, if --keep_all_dpp_dps is set and some \n' + '--out_dpp_name keys already existed in your \n' + ' data_per_point or data_per_streamline, allow \n' + ' overwriting old data_per_point.') + + add_reference_arg(p) + add_verbose_arg(p) + add_overwrite_arg(p) + add_bbox_arg(p) + + return p + + +def main(): + parser = _build_arg_parser() + args = parser.parse_args() + + if args.verbose: + logging.getLogger().setLevel(logging.INFO) + + assert_inputs_exist(parser, args.in_tractogram) + assert_outputs_exist(parser, args, args.out_tractogram) + + # Load the input files. + logging.info("Loading file {}".format(args.in_tractogram)) + sft = load_tractogram_with_reference(parser, args, args.in_tractogram) + + if len(sft.streamlines) == 0: + logging.info("Input tractogram contains no streamlines. Exiting.") + return + + if len(args.in_dpp_name) != len(args.out_name): + parser.error('The number of in_dpp_names and out_names must be ' + 'the same.') + + # Check to see if there are duplicates in the out_names + if len(args.out_name) != len(set(args.out_name)): + parser.error('The output names (out_names) must be unique.') + + # Input name checks + for in_dpp_name in args.in_dpp_name: + # Check to see if the data per point exists. + if in_dpp_name not in sft.data_per_point: + logging.info('Data per point {} not found in input tractogram.' + .format(in_dpp_name)) + return + + # warning if dpp mode and data in single number per point + data_shape = sft.data_per_point[in_dpp_name][0].shape + if args.mode == 'dpp' and data_shape[0] == 1: + logging.warning('dpp from key {} is a single number per point. ' + 'Performing a dpp-mode operation on this data ' + 'will not do anything. Continuing.') + + # Check if first data_per_point is multivalued + if args.operation == 'correlation' and data_shape[0] == 1: + logging.info('Correlation operation requires multivalued data per ' + 'point. Exiting.') + return + + if args.operation == 'correlation' and args.mode == 'dpp': + logging.info('Correlation operation requires dps mode. Exiting.') + return + + if not args.overwrite_dpp_dps: + if in_dpp_name in args.out_name: + logging.info('out_name {} already exists in input tractogram. ' + 'Set overwrite_dpp_dps or choose a different ' + 'out_name. Exiting.'.format(in_dpp_name)) + return + + data_per_point = {} + data_per_streamline = {} + for in_dpp_name, out_name in zip(args.in_dpp_name, + args.out_name): + # Perform the requested operation. + if args.operation == 'correlation': + logging.info('Performing {} across endpoint data and saving as ' + 'new dpp {}'.format(args.operation, out_name)) + new_dps = perform_pairwise_streamline_operation_on_endpoints( + args.operation, sft, in_dpp_name) + + data_per_streamline[out_name] = new_dps + elif args.mode == 'dpp': + # Results in new data per point + logging.info( + 'Performing {} on data from each streamine point ' + 'and saving as new dpp {}'.format( + args.operation, out_name)) + new_dpp = perform_streamline_operation_per_point( + args.operation, sft, in_dpp_name, args.endpoints_only) + data_per_point[out_name] = new_dpp + elif args.mode == 'dps': + # Results in new data per streamline + logging.info( + 'Performing {} across each streamline and saving resulting ' + 'data per streamline {}'.format(args.operation, out_name)) + new_data_per_streamline = perform_operation_per_streamline( + args.operation, sft, in_dpp_name, args.endpoints_only) + data_per_streamline[out_name] = new_data_per_streamline + + if args.keep_all_dpp_dps: + sft.data_per_streamline.update(data_per_streamline) + sft.data_per_point.update(data_per_point) + + new_sft = sft + else: + new_sft = sft.from_sft(sft.streamlines, sft, + data_per_point=data_per_point, + data_per_streamline=data_per_streamline) + + # Print DPP names + if data_per_point not in [None, {}]: + print("New data_per_point keys are: ") + for key in args.out_name: + print(" - {} with shape per point {}" + .format(key, new_sft.data_per_point[key][0].shape[1:])) + + # Print DPS names + if data_per_streamline not in [None, {}]: + print("New data_per_streamline keys are: ") + for key in args.out_name: + print(" - {} with shape per streamline {}" + .format(key, new_sft.data_per_streamline[key].shape[1:])) + + # Save the new streamlines (and metadata) + logging.info('Saving {} streamlines to {}.'.format(len(new_sft), + args.out_tractogram)) + save_tractogram(new_sft, args.out_tractogram, + bbox_valid_check=args.bbox_check) + + +if __name__ == "__main__": + main() diff --git a/scripts/scil_tractogram_project_map_to_streamlines.py b/scripts/scil_tractogram_project_map_to_streamlines.py new file mode 100755 index 000000000..027515781 --- /dev/null +++ b/scripts/scil_tractogram_project_map_to_streamlines.py @@ -0,0 +1,149 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +Projects maps extracted from a map onto the points of streamlines. + +The default options will take data from a nifti image (3D or 4D) and +project it onto the points of streamlines. If the image is 4D, the data +is stored as a list of 1D arrays per streamline. If the image is 3D, +the data is stored as a list of values per streamline. +""" + +import argparse +import logging + +import nibabel as nib +from dipy.io.streamline import save_tractogram + +from scilpy.io.streamlines import load_tractogram_with_reference +from scilpy.io.utils import (add_overwrite_arg, + add_reference_arg, + add_verbose_arg, + assert_inputs_exist, + assert_outputs_exist) +from scilpy.image.volume_space_management import DataVolume +from scilpy.tractograms.dps_and_dpp_management import ( + project_map_to_streamlines) + + +def _build_arg_parser(): + p = argparse.ArgumentParser( + description=__doc__, + formatter_class=argparse.RawTextHelpFormatter) + + # Mandatory arguments input and output tractogram must be in trk format + p.add_argument('in_tractogram', + help='Fiber bundle file.') + p.add_argument('out_tractogram', + help='Output file.') + p.add_argument('--in_maps', nargs='+', required=True, + help='Nifti map to project onto streamlines.') + p.add_argument('--out_dpp_name', nargs='+', required=True, + help='Name of the data_per_point to be saved in the \n' + 'output tractogram.') + + # Optional arguments + p.add_argument('--trilinear', action='store_true', + help='If set, will use trilinear interpolation \n' + 'else will use nearest neighbor interpolation \n' + 'by default.') + p.add_argument('--endpoints_only', action='store_true', + help='If set, will only project the map onto the \n' + 'endpoints of the streamlines (all other values along \n' + 'streamlines will be NaN). If not set, will project \n' + 'the map onto all points of the streamlines.') + + p.add_argument('--keep_all_dpp', action='store_true', + help='If set, previous data_per_point will be preserved \n' + 'in the output tractogram. Else, only --out_dpp_name \n' + 'keys will be saved.') + p.add_argument('--overwrite_dpp', action='store_true', + help='If set, if --keep_all_dpp is set and some \n' + '--out_dpp_name keys already existed in your \n' + 'data_per_point, allow overwriting old data_per_point.') + + add_reference_arg(p) + add_overwrite_arg(p) + add_verbose_arg(p) + return p + + +def main(): + parser = _build_arg_parser() + args = parser.parse_args() + + assert_inputs_exist(parser, [args.in_tractogram] + args.in_maps) + + assert_outputs_exist(parser, args, [args.out_tractogram]) + + if args.verbose: + logging.getLogger().setLevel(logging.INFO) + + logging.info("Loading the tractogram...") + sft = load_tractogram_with_reference(parser, args, args.in_tractogram) + sft.to_voxmm() + sft.to_corner() + + if len(sft.streamlines) == 0: + logging.warning('Empty bundle file {}. Skipping'.format( + args.in_tractogram)) + return + + # Check to see if the number of maps and dpp_names are the same + if len(args.in_maps) != len(args.out_dpp_name): + parser.error('The number of maps and dpp_names must be the same.') + + # Check to see if there are duplicates in the out_dpp_names + if len(args.out_dpp_name) != len(set(args.out_dpp_name)): + parser.error('The output names (out_dpp_names) must be unique.') + + # Check to see if the output names already exist in the input tractogram + if not args.overwrite_dpp: + for out_dpp_name in args.out_dpp_name: + if out_dpp_name in sft.data_per_point: + logging.info('out_name {} already exists in input tractogram. ' + 'Set overwrite_data or choose a different ' + 'out_name. Exiting.'.format(out_dpp_name)) + return + + data_per_point = {} + for fmap, dpp_name in zip(args.in_maps, args.out_dpp_name): + logging.info("Loading the map...") + map_img = nib.load(fmap) + map_data = map_img.get_fdata(caching='unchanged', dtype=float) + map_res = map_img.header.get_zooms()[:3] + + if args.trilinear: + interp = "trilinear" + else: + interp = "nearest" + + map_volume = DataVolume(map_data, map_res, interp) + + logging.info("Projecting map onto streamlines") + streamline_data = project_map_to_streamlines( + sft, map_volume, + endpoints_only=args.endpoints_only) + + logging.info("Saving the tractogram...") + + data_per_point[dpp_name] = streamline_data + + if args.keep_all_dpp: + sft.data_per_point.update(data_per_point) + out_sft = sft + else: + out_sft = sft.from_sft(sft.streamlines, sft, + data_per_point=data_per_point) + + print("New data_per_point keys are: ") + for key in args.out_dpp_name: + print(" - {} with shape per point {}" + .format(key, out_sft.data_per_point[key][0].shape[1:])) + + save_tractogram(out_sft, args.out_tractogram) + + +if __name__ == '__main__': + main() diff --git a/scripts/tests/test_tractogram_dpp_math.py b/scripts/tests/test_tractogram_dpp_math.py new file mode 100644 index 000000000..69387b53d --- /dev/null +++ b/scripts/tests/test_tractogram_dpp_math.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import os +import tempfile + +from scilpy.io.fetcher import get_testing_files_dict, fetch_data, get_home + + +# If they already exist, this only takes 5 seconds (check md5sum) +fetch_data(get_testing_files_dict(), keys=['tractometry.zip']) +fetch_data(get_testing_files_dict(), keys=['tracking.zip']) +tmp_dir = tempfile.TemporaryDirectory() + + +def test_help_option(script_runner): + ret = script_runner.run('scil_tractogram_dpp_math.py', '--help') + assert ret.success + + +def test_execution_tractogram_point_math_mean_3D_defaults(script_runner): + os.chdir(os.path.expanduser(tmp_dir.name)) + in_bundle = os.path.join(get_home(), 'tractometry', + 'IFGWM_uni.trk') + in_t1 = os.path.join(get_home(), 'tractometry', + 'mni_masked.nii.gz') + + t1_on_bundle = 't1_on_streamlines.trk' + + script_runner.run('scil_tractogram_project_map_to_streamlines.py', + in_bundle, t1_on_bundle, + '--in_maps', in_t1, + '--out_dpp_name', 't1') + + ret = script_runner.run('scil_tractogram_dpp_math.py', + 'mean', + t1_on_bundle, + 't1_mean_on_streamlines.trk', + '--mode', 'dps', + '--in_dpp_name', 't1', + '--out_name', 't1_mean') + + assert ret.success + + +def test_execution_tractogram_point_math_mean_4D_correlation(script_runner): + os.chdir(os.path.expanduser(tmp_dir.name)) + in_bundle = os.path.join(get_home(), 'tracking', + 'local_split_0.trk') + + in_fodf = os.path.join(get_home(), 'tracking', + 'fodf.nii.gz') + fodf_on_bundle = 'fodf_on_streamlines.trk' + + script_runner.run('scil_tractogram_project_map_to_streamlines.py', + in_bundle, fodf_on_bundle, + '--in_maps', in_fodf, in_fodf, + '--out_dpp_name', 'fodf', 'fodf2') + + ret = script_runner.run('scil_tractogram_dpp_math.py', + 'correlation', + fodf_on_bundle, + 'fodf_correlation_on_streamlines.trk', + '--mode', 'dpp', + '--in_dpp_name', 'fodf', + '--out_name', 'fodf_correlation') + + assert ret.success diff --git a/scripts/tests/test_tractogram_project_map_to_streamlines.py b/scripts/tests/test_tractogram_project_map_to_streamlines.py new file mode 100644 index 000000000..ce3b125fe --- /dev/null +++ b/scripts/tests/test_tractogram_project_map_to_streamlines.py @@ -0,0 +1,88 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +import os +import tempfile + +from scilpy.io.fetcher import fetch_data, get_home, get_testing_files_dict + +# If they already exist, this only takes 5 seconds (check md5sum) +fetch_data(get_testing_files_dict(), keys=['others.zip']) +tmp_dir = tempfile.TemporaryDirectory() + + +def test_help_option(script_runner): + ret = script_runner.run( + 'scil_tractogram_project_map_to_streamlines.py', '--help') + assert ret.success + + +def test_execution_3D_map(script_runner): + os.chdir(os.path.expanduser(tmp_dir.name)) + in_t1 = os.path.join(get_home(), 'tractometry', 'mni_masked.nii.gz') + in_tracto_1 = os.path.join(get_home(), 'others', + 'IFGWM_sub.trk') + + ret = script_runner.run('scil_tractogram_project_map_to_streamlines.py', + in_tracto_1, 't1_on_streamlines.trk', + '--in_maps', in_t1, + '--out_dpp_name', 't1') + assert ret.success + + +def test_execution_4D_map(script_runner): + os.chdir(os.path.expanduser(tmp_dir.name)) + in_rgb = os.path.join(get_home(), 'others', 'rgb.nii.gz') + in_tracto_1 = os.path.join(get_home(), 'others', + 'IFGWM_sub.trk') + + ret = script_runner.run('scil_tractogram_project_map_to_streamlines.py', + in_tracto_1, 'rgb_on_streamlines.trk', + '--in_maps', in_rgb, + '--out_dpp_name', 'rgb') + assert ret.success + + +def test_execution_3D_map_endpoints_only(script_runner): + os.chdir(os.path.expanduser(tmp_dir.name)) + in_t1 = os.path.join(get_home(), 'tractometry', 'mni_masked.nii.gz') + in_tracto_1 = os.path.join(get_home(), 'others', + 'IFGWM_sub.trk') + + ret = script_runner.run('scil_tractogram_project_map_to_streamlines.py', + in_tracto_1, + 't1_on_streamlines_endpoints.trk', + '--in_maps', in_t1, + '--out_dpp_name', 't1', + '--endpoints_only') + assert ret.success + + +def test_execution_4D_map_endpoints_only(script_runner): + os.chdir(os.path.expanduser(tmp_dir.name)) + in_rgb = os.path.join(get_home(), 'others', 'rgb.nii.gz') + in_tracto_1 = os.path.join(get_home(), 'others', + 'IFGWM_sub.trk') + + ret = script_runner.run('scil_tractogram_project_map_to_streamlines.py', + in_tracto_1, + 'rgb_on_streamlines_endpoints.trk', + '--in_maps', in_rgb, + '--out_dpp_name', 'rgb', + '--endpoints_only') + assert ret.success + + +def test_execution_3D_map_trilinear(script_runner): + os.chdir(os.path.expanduser(tmp_dir.name)) + in_t1 = os.path.join(get_home(), 'tractometry', 'mni_masked.nii.gz') + in_tracto_1 = os.path.join(get_home(), 'others', + 'IFGWM_sub.trk') + + ret = script_runner.run('scil_tractogram_project_map_to_streamlines.py', + in_tracto_1, + 't1_on_streamlines_trilinear.trk', + '--in_maps', in_t1, + '--out_dpp_name', 't1', + '--trilinear') + assert ret.success