From 65a51503713685764497e7d5f47c139d49c50314 Mon Sep 17 00:00:00 2001 From: Paul McCarthy <pauldmccarthy@gmail.com> Date: Sun, 21 Jul 2019 14:32:36 +0100 Subject: [PATCH] ENH: parse_data.Image allows additional Image.__init__ arguments to be passed. Used by fsl_convert_x5 --- fsl/scripts/fsl_convert_x5.py | 42 ++++++++++++++++++++--------------- fsl/transform/x5.py | 20 ++++++++++++++++- fsl/utils/parse_data.py | 12 ++++++---- 3 files changed, 51 insertions(+), 23 deletions(-) diff --git a/fsl/scripts/fsl_convert_x5.py b/fsl/scripts/fsl_convert_x5.py index 33f063c15..f7bf84981 100644 --- a/fsl/scripts/fsl_convert_x5.py +++ b/fsl/scripts/fsl_convert_x5.py @@ -9,17 +9,18 @@ transformation file formats. """ -import os.path as op -import sys -import shutil -import logging -import argparse -from collections import OrderedDict +import os.path as op +import functools as ft +import sys +import shutil +import logging +import argparse -import fsl.data.image as fslimage -import fsl.transform.flirt as flirt -import fsl.transform.fnirt as fnirt -import fsl.transform.x5 as x5 +import fsl.data.image as fslimage +import fsl.utils.parse_data as parse_data +import fsl.transform.flirt as flirt +import fsl.transform.fnirt as fnirt +import fsl.transform.x5 as x5 log = logging.getLogger(__name__) @@ -49,11 +50,14 @@ def parseArgs(args): subparsers = parser.add_subparsers(dest='ctype') flirt = subparsers.add_parser('flirt') fnirt = subparsers.add_parser('fnirt') + imgtype = ft.partial(parse_data.Image, loadData=False) flirt.add_argument('input', help=helps['input']) flirt.add_argument('output', help=helps['output']) - flirt.add_argument('-s', '--source', help=helps['source']) - flirt.add_argument('-r', '--reference', help=helps['reference']) + flirt.add_argument('-s', '--source', help=helps['source'], + type=imgtype) + flirt.add_argument('-r', '--reference', help=helps['reference'], + type=imgtype) flirt.add_argument('-if', '--input_format', help=helps['input_format'], choices=('x5', 'mat')) flirt.add_argument('-of', '--output_format', help=helps['output_format'], @@ -61,8 +65,10 @@ def parseArgs(args): fnirt .add_argument('input', help=helps['input']) fnirt .add_argument('output', help=helps['output']) - fnirt .add_argument('-s', '--source', help=helps['source']) - fnirt .add_argument('-r', '--reference', help=helps['reference']) + fnirt .add_argument('-s', '--source', help=helps['source'], + type=imgtype) + fnirt .add_argument('-r', '--reference', help=helps['reference'], + type=imgtype) fnirt .add_argument('-if', '--input_format', help=helps['input_format'], choices=('x5', 'nii')) fnirt .add_argument('-of', '--output_format', help=helps['output_format'], @@ -109,8 +115,8 @@ def flirtToX5(args): """Convert a linear FLIRT transformation matrix to an X5 transformation file. """ - src = fslimage.Image(args.source, loadData=False) - ref = fslimage.Image(args.reference, loadData=False) + src = args.source + ref = args.reference xform = flirt.readFlirt(args.input) xform = flirt.fromFlirt(xform, src, ref, 'world', 'world') x5.writeLinearX5(args.output, xform, src, ref) @@ -127,8 +133,8 @@ def fnirtToX5(args): """Convert a non-linear FNIRT transformation into an X5 transformation file. """ - src = fslimage.Image(args.source, loadData=False) - ref = fslimage.Image(args.reference, loadData=False) + src = args.source + ref = args.reference field = fnirt.readFnirt(args.input, src=src, ref=ref) field = fnirt.fromFnirt(field, 'world', 'world') x5.writeNonLinearX5(args.output, field) diff --git a/fsl/transform/x5.py b/fsl/transform/x5.py index 5d25dced4..f14a165a0 100644 --- a/fsl/transform/x5.py +++ b/fsl/transform/x5.py @@ -10,6 +10,7 @@ transformations from/to BIDS X5 files. The following functions are available: .. autosummary:: :nosignatures: + inferType readLinearX5 writeLinearX5 readNonLinearX5 @@ -339,6 +340,23 @@ class X5Error(Exception): pass +def inferType(fname): + """Return the type of the given X5 file - either ``'linear'``or + ``'nonlinear'``. + + :arg fname: Name of a X5 file + :returns: ``'linear'``or ``'nonlinear'`` + """ + with h5py.File(fname, 'r') as f: + + ftype = f.attrs.get('Type') + + if ftype not in ('linear', 'nonlinear'): + raise X5Error('Unknown type: {}'.format(ftype)) + + return ftype + + def readLinearX5(fname): """Read a linear X5 transformation file from ``fname``. @@ -565,7 +583,7 @@ def _readDeformation(group): def _writeDeformation(group, field): - """Write a deformation fieldto the given group. + """Write a deformation field to the given group. :arg group: A ``h5py.Group`` object :arg field: A :class:`.DeformationField` object diff --git a/fsl/utils/parse_data.py b/fsl/utils/parse_data.py index 20e51d752..1c16e97de 100644 --- a/fsl/utils/parse_data.py +++ b/fsl/utils/parse_data.py @@ -8,8 +8,9 @@ Argparse is the built-in python library for resolving command line arguments. -The functions in this module can be passed on to the ``type`` argument in the ``ArgumentParser.add_command`` method -to interpret command line arguments as neuroimageing objects (.e.g, NIFTI image files) +The functions in this module can be passed on to the ``type`` argument in the +``ArgumentParser.add_command`` method to interpret command line arguments as +neuroimaging objects (.e.g, NIFTI image files) .. autosummary:: @@ -27,18 +28,21 @@ from fsl.utils import path import argparse -def Image(filename): +def Image(filename, *args, **kwargs): """ Reads in an image from a NIFTI or Analyze file. :arg filename: filename provided by the user :return: fsl.data.image.Image object + + All other arguments are passed through to the :class:`.Image` upon + creation. """ try: full_filename = image.addExt(filename) except path.PathError as e: raise argparse.ArgumentTypeError(*e.args) - return image.Image(full_filename) + return image.Image(full_filename, *args, **kwargs) def ImageOut(basename): -- GitLab