Skip to content

Commit 4489b76

Browse files
committed
Merge branch 'master' into fix/DockerTags
2 parents 00aeb8a + e319517 commit 4489b76

File tree

5 files changed

+72
-43
lines changed

5 files changed

+72
-43
lines changed

CHANGES

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ Upcoming release 0.13
22
=====================
33

44
* TST: reduce the size of docker images & use tags for images (https://github.com/nipy/nipype/pull/1564)
5+
* ENH: Implement missing inputs/outputs in FSL AvScale (https://github.com/nipy/nipype/pull/1563)
56

67

78
Release 0.12.1 (August 3, 2016)

nipype/interfaces/base.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1660,7 +1660,7 @@ def _run_wrapper(self, runtime):
16601660
runtime = self._run_interface(runtime)
16611661
return runtime
16621662

1663-
def _run_interface(self, runtime, correct_return_codes=[0]):
1663+
def _run_interface(self, runtime, correct_return_codes=(0,)):
16641664
"""Execute command via subprocess
16651665
16661666
Parameters

nipype/interfaces/fsl/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from .model import (Level1Design, FEAT, FEATModel, FILMGLS, FEATRegister,
1313
FLAMEO, ContrastMgr, MultipleRegressDesign, L2Model, SMM,
1414
MELODIC, SmoothEstimate, Cluster, Randomise, GLM)
15-
from .utils import (Smooth, Merge, ExtractROI, Split, ImageMaths, ImageMeants,
15+
from .utils import (AvScale, Smooth, Merge, ExtractROI, Split, ImageMaths, ImageMeants,
1616
ImageStats, FilterRegressor, Overlay, Slicer,
1717
PlotTimeSeries, PlotMotionParams, ConvertXFM,
1818
SwapDimensions, PowerSpectrum, Reorient2Std,

nipype/interfaces/fsl/tests/test_auto_AvScale.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55

66
def test_AvScale_inputs():
7-
input_map = dict(args=dict(argstr='%s',
7+
input_map = dict(all_param=dict(argstr='--allparams',
8+
),
9+
args=dict(argstr='%s',
810
),
911
environ=dict(nohash=True,
1012
usedefault=True,
@@ -13,9 +15,12 @@ def test_AvScale_inputs():
1315
usedefault=True,
1416
),
1517
mat_file=dict(argstr='%s',
16-
position=0,
18+
position=-2,
1719
),
1820
output_type=dict(),
21+
ref_file=dict(argstr='%s',
22+
position=-1,
23+
),
1924
terminal_output=dict(nohash=True,
2025
),
2126
)
@@ -32,9 +37,11 @@ def test_AvScale_outputs():
3237
determinant=dict(),
3338
forward_half_transform=dict(),
3439
left_right_orientation_preserved=dict(),
40+
rot_angles=dict(),
3541
rotation_translation_matrix=dict(),
3642
scales=dict(),
3743
skews=dict(),
44+
translations=dict(),
3845
)
3946
outputs = AvScale.output_spec()
4047

nipype/interfaces/fsl/utils.py

Lines changed: 60 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
import os
2424
import os.path as op
25+
import re
2526
from glob import glob
2627
import warnings
2728
import tempfile
@@ -608,25 +609,32 @@ def aggregate_outputs(self, runtime=None, needed_outputs=None):
608609
return outputs
609610

610611

611-
class AvScaleInputSpec(FSLCommandInputSpec):
612-
mat_file = File(exists=True, argstr="%s",
613-
desc='mat file to read', position=0)
612+
class AvScaleInputSpec(CommandLineInputSpec):
613+
all_param = traits.Bool(False, argstr='--allparams')
614+
mat_file = File(exists=True, argstr='%s',
615+
desc='mat file to read', position=-2)
616+
ref_file = File(exists=True, argstr='%s', position=-1,
617+
desc='reference file to get center of rotation')
614618

615619

616620
class AvScaleOutputSpec(TraitedSpec):
617-
rotation_translation_matrix = traits.Any(
618-
desc='Rotation and Translation Matrix')
619-
scales = traits.Any(desc='Scales (x,y,z)')
620-
skews = traits.Any(desc='Skews')
621-
average_scaling = traits.Any(desc='Average Scaling')
622-
determinant = traits.Any(desc='Determinant')
623-
forward_half_transform = traits.Any(desc='Forward Half Transform')
624-
backward_half_transform = traits.Any(desc='Backwards Half Transform')
621+
rotation_translation_matrix = traits.List(
622+
traits.List(traits.Float), desc='Rotation and Translation Matrix')
623+
scales = traits.List(traits.Float, desc='Scales (x,y,z)')
624+
skews = traits.List(traits.Float, desc='Skews')
625+
average_scaling = traits.Float(desc='Average Scaling')
626+
determinant = traits.Float(desc='Determinant')
627+
forward_half_transform = traits.List(
628+
traits.List(traits.Float), desc='Forward Half Transform')
629+
backward_half_transform = traits.List(
630+
traits.List(traits.Float), desc='Backwards Half Transform')
625631
left_right_orientation_preserved = traits.Bool(
626632
desc='True if LR orientation preserved')
633+
rot_angles = traits.List(traits.Float, desc='rotation angles')
634+
translations = traits.List(traits.Float, desc='translations')
627635

628636

629-
class AvScale(FSLCommand):
637+
class AvScale(CommandLine):
630638
"""Use FSL avscale command to extract info from mat file output of FLIRT
631639
632640
Examples
@@ -643,34 +651,47 @@ class AvScale(FSLCommand):
643651

644652
_cmd = 'avscale'
645653

646-
def _format_arg(self, name, trait_spec, value):
647-
return super(AvScale, self)._format_arg(name, trait_spec, value)
648-
649-
def aggregate_outputs(self, runtime=None, needed_outputs=None):
650-
outputs = self._outputs()
651-
652-
def lines_to_float(lines):
653-
out = []
654-
for line in lines:
655-
values = line.split()
656-
out.append([float(val) for val in values])
657-
return out
658-
659-
out = runtime.stdout.split('\n')
660-
661-
outputs.rotation_translation_matrix = lines_to_float(out[1:5])
662-
outputs.scales = lines_to_float([out[6].split(" = ")[1]])
663-
outputs.skews = lines_to_float([out[8].split(" = ")[1]])
664-
outputs.average_scaling = lines_to_float([out[10].split(" = ")[1]])
665-
outputs.determinant = lines_to_float([out[12].split(" = ")[1]])
666-
if out[13].split(": ")[1] == 'preserved':
667-
outputs.left_right_orientation_preserved = True
668-
else:
669-
outputs.left_right_orientation_preserved = False
670-
outputs.forward_half_transform = lines_to_float(out[16:20])
671-
outputs.backward_half_transform = lines_to_float(out[22:-1])
654+
def _run_interface(self, runtime):
655+
runtime = super(AvScale, self)._run_interface(runtime)
656+
657+
658+
expr = re.compile(
659+
'Rotation\ &\ Translation\ Matrix:\n(?P<rot_tran_mat>[0-9\.\ \n-]+)[\s\n]*'
660+
'(Rotation\ Angles\ \(x,y,z\)\ \[rads\]\ =\ (?P<rot_angles>[0-9\.\ -]+))?[\s\n]*'
661+
'(Translations\ \(x,y,z\)\ \[mm\]\ =\ (?P<translations>[0-9\.\ -]+))?[\s\n]*'
662+
'Scales\ \(x,y,z\)\ =\ (?P<scales>[0-9\.\ -]+)[\s\n]*'
663+
'Skews\ \(xy,xz,yz\)\ =\ (?P<skews>[0-9\.\ -]+)[\s\n]*'
664+
'Average\ scaling\ =\ (?P<avg_scaling>[0-9\.-]+)[\s\n]*'
665+
'Determinant\ =\ (?P<determinant>[0-9\.-]+)[\s\n]*'
666+
'Left-Right\ orientation:\ (?P<lr_orientation>[A-Za-z]+)[\s\n]*'
667+
'Forward\ half\ transform\ =[\s]*\n'
668+
'(?P<fwd_half_xfm>[0-9\.\ \n-]+)[\s\n]*'
669+
'Backward\ half\ transform\ =[\s]*\n'
670+
'(?P<bwd_half_xfm>[0-9\.\ \n-]+)[\s\n]*')
671+
out = expr.search(runtime.stdout).groupdict()
672+
outputs = {}
673+
outputs['rotation_translation_matrix'] = [[
674+
float(v) for v in r.strip().split(' ')] for r in out['rot_tran_mat'].strip().split('\n')]
675+
outputs['scales'] = [float(s) for s in out['scales'].strip().split(' ')]
676+
outputs['skews'] = [float(s) for s in out['skews'].strip().split(' ')]
677+
outputs['average_scaling'] = float(out['avg_scaling'].strip())
678+
outputs['determinant'] = float(out['determinant'].strip())
679+
outputs['left_right_orientation_preserved'] = out['lr_orientation'].strip() == 'preserved'
680+
outputs['forward_half_transform'] = [[
681+
float(v) for v in r.strip().split(' ')] for r in out['fwd_half_xfm'].strip().split('\n')]
682+
outputs['backward_half_transform'] = [[
683+
float(v) for v in r.strip().split(' ')] for r in out['bwd_half_xfm'].strip().split('\n')]
684+
685+
if self.inputs.all_param:
686+
outputs['rot_angles'] = [float(r) for r in out['rot_angles'].strip().split(' ')]
687+
outputs['translations'] = [float(r) for r in out['translations'].strip().split(' ')]
688+
689+
690+
setattr(self, '_results', outputs)
691+
return runtime
672692

673-
return outputs
693+
def _list_outputs(self):
694+
return self._results
674695

675696

676697
class OverlayInputSpec(FSLCommandInputSpec):

0 commit comments

Comments
 (0)