47
47
BOLD_PATH = "ds054/sub-100185/func/sub-100185_task-machinegame_run-01_bold.nii.gz"
48
48
49
49
50
+ def make_prep_and_save (
51
+ prep_interface ,
52
+ base_directory ,
53
+ out_path_base = None ,
54
+ ** kwargs ,
55
+ ):
56
+ prep = save = prep_interface (
57
+ ** kwargs ,
58
+ ** ({"out_path_base" : out_path_base } if prep_interface == bintfs .DerivativesDataSink else {}),
59
+ )
60
+ if prep_interface is bintfs .DerivativesDataSink :
61
+ prep .inputs .base_directory = base_directory
62
+ else :
63
+ save = bintfs .SaveDerivative (base_directory = base_directory )
64
+
65
+ return prep , save
66
+
67
+
68
+ def connect_and_run_save (prep_result , save ):
69
+ if prep_result .interface is bintfs .DerivativesDataSink :
70
+ return prep_result
71
+
72
+ save .inputs .in_file = prep_result .outputs .out_file
73
+ save .inputs .relative_path = prep_result .outputs .out_path
74
+ save .inputs .metadata = prep_result .outputs .out_meta
75
+
76
+ return save .run ()
77
+
78
+
50
79
@pytest .mark .parametrize ("interface" , [bintfs .DerivativesDataSink , bintfs .PrepareDerivative ])
51
80
@pytest .mark .parametrize ("out_path_base" , [None , "fmriprep" ])
52
81
@pytest .mark .parametrize (
@@ -296,36 +325,26 @@ def test_DerivativesDataSink_build_path(
296
325
ds_inputs .append (str (fname ))
297
326
298
327
base_directory = tmp_path / "output"
299
- work_dir = tmp_path / "work"
300
328
base_directory .mkdir ()
301
- work_dir .mkdir ()
302
329
303
- prep = save = interface (
330
+ prep , save = make_prep_and_save (
331
+ interface ,
332
+ base_directory = str (base_directory ),
333
+ out_path_base = out_path_base ,
304
334
in_file = ds_inputs ,
305
335
source_file = source ,
306
336
dismiss_entities = dismiss_entities ,
307
337
** entities ,
308
- ** ({"out_path_base" : out_path_base } if interface == bintfs .DerivativesDataSink else {}),
309
338
)
310
- if interface == bintfs .DerivativesDataSink :
311
- prep .inputs .base_directory = str (base_directory )
312
- else :
313
- save = bintfs .SaveDerivative (base_directory = str (base_directory ))
314
-
315
339
if isinstance (expectation , type ):
316
340
with pytest .raises (expectation ):
317
341
prep .run ()
318
342
return
319
343
320
- prep_outputs = save_outputs = prep .run ().outputs
321
-
322
- if save is not prep :
323
- save .inputs .in_file = prep_outputs .out_file
324
- save .inputs .relative_path = prep_outputs .out_path
325
- save .inputs .metadata = prep_outputs .out_meta
326
- save_outputs = save .run ().outputs
344
+ prep_result = prep .run ()
345
+ save_result = connect_and_run_save (prep_result , save )
327
346
328
- output = save_outputs .out_file
347
+ output = save_result . outputs .out_file
329
348
if isinstance (expectation , str ):
330
349
expectation = [expectation ]
331
350
output = [output ]
@@ -363,7 +382,8 @@ def test_DerivativesDataSink_build_path(
363
382
assert sha1 (Path (out ).read_bytes ()).hexdigest () == chksum
364
383
365
384
366
- def test_DerivativesDataSink_dtseries_json (tmp_path ):
385
+ @pytest .mark .parametrize ("interface" , [bintfs .DerivativesDataSink , bintfs .PrepareDerivative ])
386
+ def test_DerivativesDataSink_dtseries_json (tmp_path , interface ):
367
387
cifti_fname = str (tmp_path / "test.dtseries.nii" )
368
388
369
389
axes = (nb .cifti2 .SeriesAxis (start = 0 , step = 2 , size = 20 ),
@@ -378,20 +398,22 @@ def test_DerivativesDataSink_dtseries_json(tmp_path):
378
398
source_file .parent .mkdir (parents = True )
379
399
source_file .touch ()
380
400
381
- dds = bintfs . DerivativesDataSink (
382
- in_file = cifti_fname ,
401
+ prep , save = make_prep_and_save (
402
+ interface ,
383
403
base_directory = str (tmp_path ),
404
+ out_path_base = "" ,
405
+ in_file = cifti_fname ,
384
406
source_file = str (source_file ),
385
407
compress = False ,
386
- out_path_base = "" ,
387
408
space = "fsLR" ,
388
409
grayordinates = "91k" ,
389
410
RepetitionTime = 2.0 ,
390
411
)
391
412
392
- res = dds .run ()
413
+ prep_result = prep .run ()
414
+ save_result = connect_and_run_save (prep_result , save )
393
415
394
- out_path = Path (res .outputs .out_file )
416
+ out_path = Path (save_result .outputs .out_file )
395
417
396
418
assert out_path .name == "sub-01_task-rest_space-fsLR_bold.dtseries.nii"
397
419
old_sidecar = out_path .with_name ("sub-01_task-rest_space-fsLR_bold.dtseries.json" )
@@ -402,6 +424,7 @@ def test_DerivativesDataSink_dtseries_json(tmp_path):
402
424
assert "RepetitionTime" in json .loads (new_sidecar .read_text ())
403
425
404
426
427
+ @pytest .mark .parametrize ("interface" , [bintfs .DerivativesDataSink , bintfs .PrepareDerivative ])
405
428
@pytest .mark .parametrize (
406
429
"space, size, units, xcodes, zipped, fixed, data_dtype" ,
407
430
[
@@ -427,7 +450,7 @@ def test_DerivativesDataSink_dtseries_json(tmp_path):
427
450
],
428
451
)
429
452
def test_DerivativesDataSink_bold (
430
- tmp_path , space , size , units , xcodes , zipped , fixed , data_dtype
453
+ tmp_path , interface , space , size , units , xcodes , zipped , fixed , data_dtype
431
454
):
432
455
fname = str (tmp_path / "source.nii" ) + (".gz" if zipped else "" )
433
456
@@ -438,25 +461,29 @@ def test_DerivativesDataSink_bold(
438
461
nb .Nifti1Image (np .zeros (size ), np .eye (4 ), hdr ).to_filename (fname )
439
462
440
463
# BOLD derivative in T1w space
441
- dds = bintfs .DerivativesDataSink (
464
+ prep , _ = make_prep_and_save (
465
+ interface ,
442
466
base_directory = str (tmp_path ),
443
467
keep_dtype = True ,
444
468
data_dtype = data_dtype or Undefined ,
445
469
desc = "preproc" ,
446
470
source_file = BOLD_PATH ,
447
471
space = space or Undefined ,
448
472
in_file = fname ,
449
- ). run ()
473
+ )
450
474
451
- nii = nb .load (dds .outputs .out_file )
452
- assert dds .outputs .fixed_hdr == fixed
475
+ prep_result = prep .run ()
476
+
477
+ nii = nb .load (prep_result .outputs .out_file )
478
+ assert prep_result .outputs .fixed_hdr == fixed
453
479
if data_dtype :
454
480
assert nii .get_data_dtype () == np .dtype (data_dtype )
455
481
assert int (nii .header ["qform_code" ]) == XFORM_CODES [space ]
456
482
assert int (nii .header ["sform_code" ]) == XFORM_CODES [space ]
457
483
assert nii .header .get_xyzt_units () == ("mm" , "sec" )
458
484
459
485
486
+ @pytest .mark .parametrize ("interface" , [bintfs .DerivativesDataSink , bintfs .PrepareDerivative ])
460
487
@pytest .mark .parametrize (
461
488
"space, size, units, xcodes, fixed" ,
462
489
[
@@ -480,7 +507,7 @@ def test_DerivativesDataSink_bold(
480
507
(None , (30 , 30 , 30 ), (None , "sec" ), (0 , 0 ), [True ]),
481
508
],
482
509
)
483
- def test_DerivativesDataSink_t1w (tmp_path , space , size , units , xcodes , fixed ):
510
+ def test_DerivativesDataSink_t1w (tmp_path , interface , space , size , units , xcodes , fixed ):
484
511
fname = str (tmp_path / "source.nii.gz" )
485
512
486
513
hdr = nb .Nifti1Header ()
@@ -490,22 +517,26 @@ def test_DerivativesDataSink_t1w(tmp_path, space, size, units, xcodes, fixed):
490
517
nb .Nifti1Image (np .zeros (size ), np .eye (4 ), hdr ).to_filename (fname )
491
518
492
519
# BOLD derivative in T1w space
493
- dds = bintfs .DerivativesDataSink (
520
+ prep , _ = make_prep_and_save (
521
+ interface ,
494
522
base_directory = str (tmp_path ),
495
523
keep_dtype = True ,
496
524
desc = "preproc" ,
497
525
source_file = T1W_PATH ,
498
526
space = space or Undefined ,
499
527
in_file = fname ,
500
- ).run ()
528
+ )
529
+
530
+ prep_result = prep .run ()
501
531
502
- nii = nb .load (dds .outputs .out_file )
503
- assert dds .outputs .fixed_hdr == fixed
532
+ nii = nb .load (prep_result .outputs .out_file )
533
+ assert prep_result .outputs .fixed_hdr == fixed
504
534
assert int (nii .header ["qform_code" ]) == XFORM_CODES [space ]
505
535
assert int (nii .header ["sform_code" ]) == XFORM_CODES [space ]
506
536
assert nii .header .get_xyzt_units () == ("mm" , "unknown" )
507
537
508
538
539
+ @pytest .mark .parametrize ("interface" , [bintfs .DerivativesDataSink , bintfs .PrepareDerivative ])
509
540
@pytest .mark .parametrize (
510
541
"source_file" ,
511
542
[
@@ -517,7 +548,7 @@ def test_DerivativesDataSink_t1w(tmp_path, space, size, units, xcodes, fixed):
517
548
@pytest .mark .parametrize ("source_dtype" , ["<i4" , "<f4" ])
518
549
@pytest .mark .parametrize ("in_dtype" , ["<i4" , "<f4" ])
519
550
def test_DerivativesDataSink_data_dtype_source (
520
- tmp_path , source_file , source_dtype , in_dtype
551
+ tmp_path , interface , source_file , source_dtype , in_dtype
521
552
):
522
553
523
554
def make_empty_nii_with_dtype (fname , dtype ):
@@ -539,19 +570,23 @@ def make_empty_nii_with_dtype(fname, dtype):
539
570
for s in source_file :
540
571
make_empty_nii_with_dtype (s , source_dtype )
541
572
542
- dds = bintfs .DerivativesDataSink (
573
+ prep , save = make_prep_and_save (
574
+ interface ,
543
575
base_directory = str (tmp_path ),
544
576
data_dtype = "source" ,
545
577
desc = "preproc" ,
546
578
source_file = source_file ,
547
579
in_file = in_file ,
548
- ).run ()
580
+ )
581
+
582
+ prep_result = prep .run ()
549
583
550
- nii = nb .load (dds .outputs .out_file )
584
+ nii = nb .load (prep_result .outputs .out_file )
551
585
assert nii .get_data_dtype () == np .dtype (source_dtype )
552
586
553
587
554
- def test_DerivativesDataSink_fmapid (tmp_path ):
588
+ @pytest .mark .parametrize ("interface" , [bintfs .DerivativesDataSink , bintfs .PrepareDerivative ])
589
+ def test_DerivativesDataSink_fmapid (tmp_path , interface ):
555
590
"""Ascertain #637 is not regressing."""
556
591
source_file = [
557
592
(tmp_path / s )
@@ -569,7 +604,8 @@ def test_DerivativesDataSink_fmapid(tmp_path):
569
604
in_file = tmp_path / "report.svg"
570
605
in_file .write_text ("" )
571
606
572
- dds = bintfs .DerivativesDataSink (
607
+ prep , save = make_prep_and_save (
608
+ interface ,
573
609
base_directory = str (tmp_path ),
574
610
datatype = "figures" ,
575
611
suffix = "fieldmap" ,
@@ -579,12 +615,17 @@ def test_DerivativesDataSink_fmapid(tmp_path):
579
615
fmapid = "auto00000" ,
580
616
source_file = [str (s .absolute ()) for s in source_file ],
581
617
in_file = str (in_file ),
582
- ).run ()
583
- assert dds .outputs .out_file .endswith ("sub-36_fmapid-auto00000_desc-pepolar_fieldmap.svg" )
618
+ )
619
+
620
+ prep_result = prep .run ()
621
+ save_result = connect_and_run_save (prep_result , save )
622
+
623
+ assert save_result .outputs .out_file .endswith ("sub-36_fmapid-auto00000_desc-pepolar_fieldmap.svg" )
584
624
585
625
626
+ @pytest .mark .parametrize ("interface" , [bintfs .DerivativesDataSink , bintfs .PrepareDerivative ])
586
627
@pytest .mark .parametrize ("dtype" , ("i2" , "u2" , "f4" ))
587
- def test_DerivativesDataSink_values (tmp_path , dtype ):
628
+ def test_DerivativesDataSink_values (tmp_path , interface , dtype ):
588
629
# We use static checksums above, which ensures we don't break things, but
589
630
# pins the tests to specific values.
590
631
# Here we use random values, check that the values are preserved, and then
@@ -599,16 +640,19 @@ def test_DerivativesDataSink_values(tmp_path, dtype):
599
640
orig_data = np .asanyarray (nb .load (fname ).dataobj )
600
641
expected = np .rint (orig_data ) if dtype [0 ] in "iu" else orig_data
601
642
602
- dds = bintfs .DerivativesDataSink (
643
+ prep , _ = make_prep_and_save (
644
+ interface ,
603
645
base_directory = str (tmp_path ),
604
646
keep_dtype = True ,
605
647
data_dtype = dtype ,
606
648
desc = "preproc" ,
607
649
source_file = T1W_PATH ,
608
650
in_file = fname ,
609
- ).run ()
651
+ )
652
+
653
+ prep_result = prep .run ()
610
654
611
- out_file = Path (dds .outputs .out_file )
655
+ out_file = Path (prep_result .outputs .out_file )
612
656
613
657
nii = nb .load (out_file )
614
658
assert np .allclose (nii .dataobj , expected )
@@ -617,14 +661,17 @@ def test_DerivativesDataSink_values(tmp_path, dtype):
617
661
out_file .unlink ()
618
662
619
663
# Rerun to ensure determinism with non-zero data
620
- dds = bintfs .DerivativesDataSink (
664
+ prep , _ = make_prep_and_save (
665
+ interface ,
621
666
base_directory = str (tmp_path ),
622
667
keep_dtype = True ,
623
668
data_dtype = dtype ,
624
669
desc = "preproc" ,
625
670
source_file = T1W_PATH ,
626
671
in_file = fname ,
627
- ).run ()
672
+ )
673
+
674
+ prep_result = prep .run ()
628
675
629
676
assert sha1 (out_file .read_bytes ()).hexdigest () == checksum
630
677
0 commit comments