diff --git a/scripts/scil_apply_transform_to_bvecs.py b/scripts/scil_apply_transform_to_bvecs.py new file mode 100644 index 000000000..d8f926d7e --- /dev/null +++ b/scripts/scil_apply_transform_to_bvecs.py @@ -0,0 +1,60 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +Transform bvecs using an affine/rigid transformation. +""" + +import argparse + +import numpy as np + +from dipy.io.gradients import read_bvals_bvecs + +from scilpy.io.utils import (add_overwrite_arg, assert_inputs_exist, + assert_outputs_exist, load_matrix_in_any_format) +from scilpy.utils.filenames import split_name_with_nii +from scilpy.utils.image import transform_anatomy + + +def _build_arg_parser(): + p = argparse.ArgumentParser(formatter_class=argparse.RawTextHelpFormatter, + description=__doc__) + + p.add_argument('in_bvecs', + help='Path of the bvec file, in FSL format') + p.add_argument('in_transfo', + help='Path of the file containing the 4x4 \n' + 'transformation, matrix (.txt, .npy or .mat).') + p.add_argument('out_bvecs', + help='Output filename of the transformed bvecs.') + + p.add_argument('--inverse', action='store_true', + help='Apply the inverse transformation.') + + add_overwrite_arg(p) + + return p + + +def main(): + parser = _build_arg_parser() + args = parser.parse_args() + + assert_inputs_exist(parser, [args.in_bvecs, args.in_transfo]) + assert_outputs_exist(parser, args, args.out_bvecs) + + transfo = load_matrix_in_any_format(args.in_transfo)[:3, :3] + + if args.inverse: + transfo = np.linalg.inv(transfo) + + _, bvecs = read_bvals_bvecs(None, args.in_bvecs) + + bvecs = bvecs @ transfo + + np.savetxt(str(args.out_bvecs), bvecs.T) + + +if __name__ == "__main__": + main() diff --git a/scripts/tests/test_apply_transform_to_bvecs.py b/scripts/tests/test_apply_transform_to_bvecs.py new file mode 100644 index 000000000..ee3718c8f --- /dev/null +++ b/scripts/tests/test_apply_transform_to_bvecs.py @@ -0,0 +1,30 @@ +#!/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=['bst.zip']) +fetch_data(get_testing_files_dict(), keys=['processing.zip']) +tmp_dir = tempfile.TemporaryDirectory() + + +def test_help_option(script_runner): + ret = script_runner.run('scil_apply_transform_to_bvecs.py', '--help') + assert ret.success + + +def test_execution_bst(script_runner): + os.chdir(os.path.expanduser(tmp_dir.name)) + in_bvecs = os.path.join(get_home(), 'processing', + 'dwi.bvec') + in_aff = os.path.join(get_home(), 'bst', + 'output0GenericAffine.mat') + ret = script_runner.run('scil_apply_transform_to_bvecs.py', + in_bvecs, in_aff, + 'bvecs_transformed.bvec', '--inverse') + assert ret.success