test_wrappers.py 16.9 KB
Newer Older
1
2
3
4
5
6
7
8
9
#!/usr/bin/env python
#
# test_wrappers.py -
#
# Author: Paul McCarthy <pauldmccarthy@gmail.com>
#

import os.path   as op
import itertools as it
10
import textwrap  as tw
Paul McCarthy's avatar
Paul McCarthy committed
11
12
import              os
import              shlex
13
14

import numpy as np
15
16
17
18

import fsl.wrappers                       as fw
import fsl.utils.assertions               as asrt
import fsl.utils.run                      as run
19
from fsl.utils.tempdir import tempdir
20

21
from .. import mockFSLDIR, make_random_image
22
23


24
def checkResult(cmd, base, args, stripdir=None):
Paul McCarthy's avatar
Paul McCarthy committed
25
26
27
28
    """Check that the generate dcommand matches the expected command.

    Pre python 3.7, we couldn't control the order in which command
    line args were generated, so we needed to test all possible orderings.
29

30
31
32
33
34
    :arg cmd:      Generated command
    :arg base:     Beginning of expected command
    :arg args:     Sequence of expected arguments
    :arg stripdir: Sequence of indices indicating arguments
                   for whihc any leading directory should be ignored.
35
    """
36
37
38
39
40
41
42

    if stripdir is not None:
        cmd = list(cmd.split())
        for si in stripdir:
            cmd[si] = op.basename(cmd[si])
        cmd = ' '.join(cmd)

43
44
45
46
47
48
49
    permutations = it.permutations(args, len(args))
    possible     = [' '.join([base] + list(p))  for p in permutations]

    return any([cmd == p for p in possible])


def test_bet():
50
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('bet',)) as fsldir:
51
52
53
        bet      = op.join(fsldir, 'bin', 'bet')
        result   = fw.bet('input', 'output', mask=True, c=(10, 20, 30))
        expected = (bet + ' input output', ('-m', '-c 10 20 30'))
54
        assert checkResult(result.stdout[0], *expected, stripdir=[2])
55
56
57


def test_robustfov():
58
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('robustfov',)) as fsldir:
59
60
61
        rfov     = op.join(fsldir, 'bin', 'robustfov')
        result   = fw.robustfov('input', 'output', b=180)
        expected = (rfov + ' -i input', ('-r output', '-b 180'))
62
        assert checkResult(result.stdout[0], *expected)
63
64
65


def test_eddy_cuda():
66
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('eddy_cuda',)) as fsldir:
67
68
69
70
71
72
73
74
75
76
77
78
        eddy     = op.join(fsldir, 'bin', 'eddy_cuda')
        result   = fw.eddy_cuda('imain', 'mask', 'index', 'acqp',
                                'bvecs', 'bvals', 'out', dont_mask_output=True)
        expected = (eddy, ('--imain=imain',
                           '--mask=mask',
                           '--index=index',
                           '--acqp=acqp',
                           '--bvecs=bvecs',
                           '--bvals=bvals',
                           '--out=out',
                           '--dont_mask_output'))

79
        assert checkResult(result.stdout[0], *expected)
80
81
82


def test_topup():
83
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('topup',)) as fsldir:
84
85
86
        topup    = op.join(fsldir, 'bin', 'topup')
        result   = fw.topup('imain', 'datain', minmet=1)
        expected = topup + ' --imain=imain --datain=datain --minmet=1'
87
        assert result.stdout[0] == expected
88
89
90


def test_flirt():
91
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('flirt',)) as fsldir:
92
93
94
95
        flirt    = op.join(fsldir, 'bin', 'flirt')
        result   = fw.flirt('src', 'ref', usesqform=True, anglerep='euler')
        expected = (flirt + ' -in src -ref ref',
                    ('-usesqform', '-anglerep euler'))
96
        assert checkResult(result.stdout[0], *expected)
97
98


99
100
101
102
103
104
105
106
def test_epi_reg():
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('epi_reg',)) as fsldir:
        epi_reg  = op.join(fsldir, 'bin', 'epi_reg')
        result   = fw.epi_reg('epi', 't1', 't1brain', 'out')
        expected = epi_reg + ' --epi=epi --t1=t1 --t1brain=t1brain --out=out'
        assert result.stdout[0] == expected


107
def test_applyxfm():
108
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('flirt',)) as fsldir:
109
110
111
112
113
114
115
        flirt    = op.join(fsldir, 'bin', 'flirt')
        result   = fw.applyxfm('src', 'ref', 'mat', 'out', interp='trilinear')
        expected = (flirt + ' -in src -ref ref',
                    ('-applyxfm',
                     '-out out',
                     '-init mat',
                     '-interp trilinear'))
116
        assert checkResult(result.stdout[0], *expected)
117
118


119
def test_applyxfm4D():
Paul McCarthy's avatar
Paul McCarthy committed
120
121
122
123
124
125
126
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('applyxfm4D',)) as fsldir:
        applyxfm = op.join(fsldir, 'bin', 'applyxfm4D')
        result   = fw.applyxfm4D(
            'src', 'ref', 'out', 'mat', fourdigit=True, userprefix='boo')
        expected = (applyxfm + ' src ref out mat',
                    ('-fourdigit',
                     '-userprefix boo'))
127
        assert checkResult(result.stdout[0], *expected)
Paul McCarthy's avatar
Paul McCarthy committed
128
129


130
def test_invxfm():
131
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('convert_xfm',)) as fsldir:
132
133
134
        cnvxfm   = op.join(fsldir, 'bin', 'convert_xfm')
        result   = fw.invxfm('mat', 'output')
        expected = cnvxfm + ' -omat output -inverse mat'
135
        assert result.stdout[0] == expected
136
137
138


def test_concatxfm():
139
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('convert_xfm',)) as fsldir:
140
141
142
        cnvxfm   = op.join(fsldir, 'bin', 'convert_xfm')
        result   = fw.concatxfm('mat1', 'mat2', 'output')
        expected = cnvxfm + ' -omat output -concat mat2 mat1'
143
        assert result.stdout[0] == expected
144
145
146


def test_mcflirt():
147
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('mcflirt',)) as fsldir:
148
149
150
151
152
153
        mcflirt  = op.join(fsldir, 'bin', 'mcflirt')
        result   = fw.mcflirt('input', out='output', cost='normcorr', dof=12)
        expected = (mcflirt + ' -in input',
                    ('-out output',
                     '-cost normcorr',
                     '-dof 12'))
154
        assert checkResult(result.stdout[0], *expected)
155
156
157


def test_fnirt():
158
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('fnirt',)) as fsldir:
159
        fnirt    = op.join(fsldir, 'bin', 'fnirt')
160
        result   = fw.fnirt('src', ref='ref', iout='iout', fout='fout',
161
                            subsamp=(8, 6, 4, 2))
162
163
164
        expected = (fnirt + ' --in=src',
                    ('--ref=ref',
                     '--iout=iout',
165
166
                     '--fout=fout',
                     '--subsamp=8,6,4,2'))
167
        assert checkResult(result.stdout[0], *expected)
168
169
170


def test_applywarp():
171
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('applywarp',)) as fsldir:
172
        applywarp = op.join(fsldir, 'bin', 'applywarp')
173
174
175
        result    = fw.applywarp('src', 'ref', 'out', warp='warp', abs=True, super=True)
        expected  = (applywarp + ' --in=src --ref=ref --out=out',
                     ('--warp=warp', '--abs', '--super'))
176
        assert checkResult(result.stdout[0], *expected)
177
178
179


def test_invwarp():
180
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('invwarp',)) as fsldir:
181
182
183
184
185
        invwarp  = op.join(fsldir, 'bin', 'invwarp')
        result   = fw.invwarp('warp', 'ref', 'out',
                              rel=True, noconstraint=True)
        expected = (invwarp + ' --warp=warp --ref=ref --out=out',
                     ('--rel', '--noconstraint'))
186
        assert checkResult(result.stdout[0], *expected)
187
188
189


def test_convertwarp():
190
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('convertwarp',)) as fsldir:
191
        cnvwarp  = op.join(fsldir, 'bin', 'convertwarp')
192
        result   = fw.convertwarp('out', 'ref', absout=True, jacobian='jacobian')
193
        expected = (cnvwarp + ' --ref=ref --out=out',
194
                     ('--absout', '--jacobian=jacobian'))
195
        assert checkResult(result.stdout[0], *expected)
196
197
198


def test_fugue():
199
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('fugue',)) as fsldir:
200
201
202
203
204
205
206
        fugue    = op.join(fsldir, 'bin', 'fugue')
        result   = fw.fugue(input='input', warp='warp',
                            median=True, dwell=10)
        expected = (fugue, ('--in=input',
                            '--warp=warp',
                            '--median',
                            '--dwell=10'))
207
        assert checkResult(result.stdout[0], *expected)
208
209
210
211



def test_sigloss():
212
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('sigloss',)) as fsldir:
213
214
215
216
        sigloss  = op.join(fsldir, 'bin', 'sigloss')
        result   = fw.sigloss('input', 'sigloss', mask='mask', te=0.5)
        expected = (sigloss + ' --in input --sigloss sigloss',
                    ('--mask mask', '--te 0.5'))
217
        assert checkResult(result.stdout[0], *expected)
218
219


Paul McCarthy's avatar
Paul McCarthy committed
220
221
222
223
224
225
226
227
228
229
230
def test_prelude():
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('prelude',)) as fsldir:
        prelude  = op.join(fsldir, 'bin', 'prelude')
        result   = fw.prelude(complex='complex',
                              out='out',
                              labelslices=True,
                              start=5)
        expected = (prelude, ('--complex=complex',
                              '--out=out',
                              '--labelslices',
                              '--start=5'))
231
        assert checkResult(result.stdout[0], *expected)
Paul McCarthy's avatar
Paul McCarthy committed
232
233


234
def test_melodic():
235
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('melodic',)) as fsldir:
236
237
238
239
        melodic  = op.join(fsldir, 'bin', 'melodic')
        result   = fw.melodic('input', dim=50, mask='mask', Oall=True)
        expected = (melodic + ' --in=input',
                    ('--dim=50', '--mask=mask', '--Oall'))
240
        assert checkResult(result.stdout[0], *expected)
241
242
243


def test_fsl_regfilt():
244
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('fsl_regfilt',)) as fsldir:
245
246
247
248
249
        regfilt  = op.join(fsldir, 'bin', 'fsl_regfilt')
        result   = fw.fsl_regfilt('input', 'output', 'design',
                                  filter=(1, 2, 3, 4), vn=True)
        expected = (regfilt + ' --in=input --out=output --design=design',
                    ('--filter=1,2,3,4', '--vn'))
250
        assert checkResult(result.stdout[0], *expected)
251
252
253
254



def test_fslreorient2std():
255
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('fslreorient2std',)) as fsldir:
256
257
258
        r2std    = op.join(fsldir, 'bin', 'fslreorient2std')
        result   = fw.fslreorient2std('input', 'output')
        expected = r2std + ' input output'
259
        assert result.stdout[0] == expected
260
261
262


def test_fslroi():
263
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('fslroi',)) as fsldir:
264
265
266
267
        fslroi   = op.join(fsldir, 'bin', 'fslroi')

        result   = fw.fslroi('input', 'output', 1, 10)
        expected = fslroi + ' input output 1 10'
268
        assert result.stdout[0] == expected
269
270
271

        result   = fw.fslroi('input', 'output', 1, 10, 2, 20, 3, 30)
        expected = fslroi + ' input output 1 10 2 20 3 30'
272
        assert result.stdout[0] == expected
273
274
275

        result   = fw.fslroi('input', 'output', 1, 10, 2, 20, 3, 30, 4, 40)
        expected = fslroi + ' input output 1 10 2 20 3 30 4 40'
276
        assert result.stdout[0] == expected
277
278
279


def test_slicer():
280
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('slicer',)) as fsldir:
281
282
283
        slicer   = op.join(fsldir, 'bin', 'slicer')
        result   = fw.slicer('input1', 'input2', i=(20, 100), x=(20, 'x.png'))
        expected = slicer + ' input1 input2 -i 20 100 -x 20 x.png'
284
        assert result.stdout[0] == expected
285
286
287


def test_cluster():
288
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('cluster',)) as fsldir:
289
290
291
292
293
        cluster  = op.join(fsldir, 'bin', 'cluster')
        result   = fw.cluster('input', 'thresh',
                              fractional=True, osize='osize')
        expected = (cluster + ' --in=input --thresh=thresh',
                    ('--fractional', '--osize=osize'))
294
        assert checkResult(result.stdout[0], *expected)
295
296
297


def test_fslmaths():
298
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('fslmaths',)) as fsldir:
299
300
301
302
303
        cmd    = op.join(fsldir, 'bin', 'fslmaths')
        result = fw.fslmaths('input') \
            .abs().bin().binv().recip().Tmean().Tstd().Tmin().Tmax() \
            .fillh().ero().dilM().dilF().add('addim').sub('subim') \
            .mul('mulim').div('divim').mas('masim').rem('remim')   \
304
            .thr('thrim').uthr('uthrim').inm('inmim').bptf(1, 10) \
305
            .smooth(sigma=6).kernel('3D').fmeanu().run('output')
306
307
308
309
310
311

        expected = [cmd, 'input',
                    '-abs', '-bin', '-binv', '-recip', '-Tmean', '-Tstd',
                    '-Tmin', '-Tmax', '-fillh', '-ero', '-dilM', '-dilF',
                    '-add addim', '-sub subim', '-mul mulim', '-div divim',
                    '-mas masim', '-rem remim', '-thr thrim', '-uthr uthrim',
312
313
                    '-inm inmim', '-bptf 1 10', '-s 6', '-kernel 3D', '-fmeanu',
                    'output']
314
315
        expected = ' '.join(expected)

316
        assert result.stdout[0] == expected
317

318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
    # test LOAD output
    with tempdir() as td, mockFSLDIR(bin=('fslmaths',)) as fsldir:
        expect = make_random_image(op.join(td, 'output.nii.gz'))

        with open(op.join(fsldir, 'bin', 'fslmaths'), 'wt') as f:
            f.write(tw.dedent("""
            #!/usr/bin/env python
            import sys
            import shutil
            shutil.copy('{}', sys.argv[2])
            """.format(op.join(td, 'output.nii.gz'))).strip())
            os.chmod(op.join(fsldir, 'bin', 'fslmaths'), 0o755)

        got = fw.fslmaths('input').run()
        assert np.all(expect.dataobj[:] == got.dataobj[:])
        got = fw.fslmaths('input').run(fw.LOAD)
        assert np.all(expect.dataobj[:] == got.dataobj[:])
Paul McCarthy's avatar
Paul McCarthy committed
335
336

def test_fast():
337
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('fast',)) as fsldir:
Paul McCarthy's avatar
Paul McCarthy committed
338
339
340
341

        cmd = op.join(fsldir, 'bin', 'fast')

        result   = fw.fast('input', 'myseg', n_classes=3)
Paul McCarthy's avatar
Paul McCarthy committed
342
        expected = [cmd, '--out=myseg', '--class=3', 'input']
Paul McCarthy's avatar
Paul McCarthy committed
343

344
        assert result.stdout[0] == ' '.join(expected)
Paul McCarthy's avatar
Paul McCarthy committed
345
346

        result   = fw.fast(('in1', 'in2', 'in3'), 'myseg', n_classes=3)
Paul McCarthy's avatar
Paul McCarthy committed
347
348
        expected = [cmd, '--out=myseg', '--class=3', 'in1', 'in2', 'in3']
        assert result.stdout[0] == ' '.join(expected)
Paul McCarthy's avatar
Paul McCarthy committed
349

Paul McCarthy's avatar
Paul McCarthy committed
350
351
        result   = fw.fast(('in1', 'in2', 'in3'), 'myseg', n_classes=3, verbose=True)
        expected = [cmd, '--out=myseg', '--class=3', '--verbose', 'in1', 'in2', 'in3']
352
        assert result.stdout[0] == ' '.join(expected)
353
354
355
356
357
358
359
360
361
362
363
364
365


def test_fsl_anat():
    with asrt.disabled(), \
         run.dryrun(), \
         mockFSLDIR(bin=('fsl_anat',)) as fsldir:

        cmd = op.join(fsldir, 'bin', 'fsl_anat')

        result   = fw.fsl_anat('t1', out='fsl_anat', bias_smoothing=25)
        expected = [cmd, '-i', 't1', '-o', 'fsl_anat', '-t', 'T1',
                    '-s', '25']

366
        assert result.stdout[0] == ' '.join(expected)
Michiel Cottaar's avatar
Michiel Cottaar committed
367
368
369
370
371
372
373
374
375


def test_gps():
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('gps',)) as fsldir:
        gps = op.join(fsldir, 'bin', 'gps')
        result = fw.gps('bvecs', 128, optws=True, ranseed=123)
        expected = (gps + ' --ndir=128 --out=bvecs',
                    ('--optws', '--ranseed=123'))
        assert checkResult(result.stdout[0], *expected)
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403


def test_tbss():
    exes = {
        'preproc'  : 'tbss_1_preproc',
        'reg'      : 'tbss_2_reg',
        'postreg'  : 'tbss_3_postreg',
        'prestats' : 'tbss_4_prestats',
        'non_FA'   : 'tbss_non_FA',
        'fill'     : 'tbss_fill'
    }

    with asrt.disabled(), \
         run.dryrun(), \
         mockFSLDIR(bin=exes.values()) as fsldir:
        for k in exes:
            exes[k] = op.join(fsldir, 'bin', exes[k])

        assert fw.tbss.preproc('1', '2')[0] == ' '.join([exes['preproc'], '1', '2'])
        assert fw.tbss.reg(T=True)[0]       == ' '.join([exes['reg'], '-T'])
        assert fw.tbss.reg(n=True)[0]       == ' '.join([exes['reg'], '-n'])
        assert fw.tbss.reg(t='target')[0]   == ' '.join([exes['reg'], '-t', 'target'])
        assert fw.tbss.postreg(S=True)[0]   == ' '.join([exes['postreg'], '-S'])
        assert fw.tbss.postreg(T=True)[0]   == ' '.join([exes['postreg'], '-T'])
        assert fw.tbss.prestats(0.3)[0]     == ' '.join([exes['prestats'], '0.3'])
        assert fw.tbss.non_FA('alt')[0]     == ' '.join([exes['non_FA'], 'alt'])
        assert fw.tbss.fill('stat', 0.4, 'mean_fa', 'output', n=True).stdout[0] == \
            ' '.join([exes['fill'], 'stat', '0.4', 'mean_fa', 'output', '-n'])
404
405
406
407

def test_fsl_prepare_fieldmap():
    with asrt.disabled(), run.dryrun(), mockFSLDIR(bin=('fsl_prepare_fieldmap',)) as fsldir:
        fpf = op.join(fsldir, 'bin', 'fsl_prepare_fieldmap')
Paul McCarthy's avatar
Paul McCarthy committed
408
409
410
411
412
        result   = fw.fsl_prepare_fieldmap(phase_image='ph',
                                           magnitude_image='mag',
                                           out_image='out',
                                           deltaTE=2.46,
                                           nocheck=True)
413
414
        expected = (fpf, ('SIEMENS', 'ph', 'mag', 'out', '2.46', '--nocheck'))
        assert checkResult(result.stdout[0], *expected)
Paul McCarthy's avatar
Paul McCarthy committed
415
416
417
418
419
420
421
422
423
424
425
426


def test_fsl_sub():
    with run.dryrun(), mockFSLDIR(bin=('fsl_sub',)) as fsldir:
        expected = [op.join(fsldir, 'bin', 'fsl_sub'),
                    '--jobhold', '123',
                    '--queue', 'long.q',
                    'some_command', '--some_arg']

        result = fw.fsl_sub(
            'some_command', '--some_arg', jobhold='123', queue='long.q')
        assert shlex.split(result[0]) == expected