@@ -349,8 +349,7 @@ def init_bold_fit_wf(
349
349
)
350
350
351
351
func_fit_reports_wf = init_func_fit_reports_wf (
352
- # TODO: Enable sdc report even if we find coregref
353
- sdc_correction = not (coreg_boldref or fieldmap_id is None ),
352
+ sdc_correction = fieldmap_id is not None ,
354
353
freesurfer = config .workflow .run_reconall ,
355
354
output_dir = config .execution .fmriprep_dir ,
356
355
)
@@ -360,6 +359,7 @@ def init_bold_fit_wf(
360
359
('boldref' , 'hmc_boldref' ),
361
360
('dummy_scans' , 'dummy_scans' ),
362
361
]),
362
+ (hmcref_buffer , fmapref_buffer , [('boldref' , 'boldref_files' )]),
363
363
(regref_buffer , outputnode , [
364
364
('boldref' , 'coreg_boldref' ),
365
365
('boldmask' , 'bold_mask' ),
@@ -462,10 +462,82 @@ def init_bold_fit_wf(
462
462
else :
463
463
config .loggers .workflow .info ('Found motion correction transforms - skipping Stage 2' )
464
464
465
- # Stage 3: Create coregistration reference
466
- # Fieldmap correction only happens during fit if this stage is needed
465
+ # Stage 3: Register fieldmap to boldref and reconstruct in BOLD space
466
+ if fieldmap_id :
467
+ config .loggers .workflow .info ('Stage 3: Adding fieldmap reconstruction workflow' )
468
+ fmap_select = pe .Node (
469
+ KeySelect (
470
+ fields = ['fmap_ref' , 'fmap_coeff' , 'fmap_mask' , 'sdc_method' ],
471
+ key = fieldmap_id ,
472
+ ),
473
+ name = 'fmap_select' ,
474
+ run_without_submitting = True ,
475
+ )
476
+
477
+ boldref_fmap = pe .Node (ReconstructFieldmap (inverse = [True ]), name = 'boldref_fmap' , mem_gb = 1 )
478
+
479
+ workflow .connect ([
480
+ (inputnode , fmap_select , [
481
+ ('fmap_ref' , 'fmap_ref' ),
482
+ ('fmap_coeff' , 'fmap_coeff' ),
483
+ ('fmap_mask' , 'fmap_mask' ),
484
+ ('sdc_method' , 'sdc_method' ),
485
+ ('fmap_id' , 'keys' ),
486
+ ]),
487
+ (fmapref_buffer , boldref_fmap , [('out' , 'target_ref_file' )]),
488
+ (fmapreg_buffer , boldref_fmap , [('boldref2fmap_xfm' , 'transforms' )]),
489
+ (fmap_select , boldref_fmap , [
490
+ ('fmap_coeff' , 'in_coeffs' ),
491
+ ('fmap_ref' , 'fmap_ref_file' ),
492
+ ]),
493
+ (fmap_select , func_fit_reports_wf , [('fmap_ref' , 'inputnode.fmap_ref' )]),
494
+ (fmap_select , summary , [('sdc_method' , 'distortion_correction' )]),
495
+ (fmapref_buffer , func_fit_reports_wf , [('out' , 'inputnode.sdc_boldref' )]),
496
+ (fmapreg_buffer , func_fit_reports_wf , [
497
+ ('boldref2fmap_xfm' , 'inputnode.boldref2fmap_xfm' ),
498
+ ]),
499
+ (boldref_fmap , func_fit_reports_wf , [('out_file' , 'inputnode.fieldmap' )]),
500
+ ]) # fmt:skip
501
+
502
+ if not boldref2fmap_xform :
503
+ config .loggers .workflow .info ('Stage 3: Registering fieldmap to boldref' )
504
+ fmapreg_wf = init_coeff2epi_wf (
505
+ debug = 'fieldmaps' in config .execution .debug ,
506
+ omp_nthreads = config .nipype .omp_nthreads ,
507
+ sloppy = config .execution .sloppy ,
508
+ name = 'fmapreg_wf' ,
509
+ )
510
+
511
+ itk_mat2txt = pe .Node (ConcatenateXFMs (out_fmt = 'itk' ), name = 'itk_mat2txt' )
512
+
513
+ ds_fmapreg_wf = init_ds_registration_wf (
514
+ bids_root = layout .root ,
515
+ output_dir = config .execution .fmriprep_dir ,
516
+ source = 'boldref' ,
517
+ dest = fieldmap_id .replace ('_' , '' ),
518
+ name = 'ds_fmapreg_wf' ,
519
+ )
520
+ ds_fmapreg_wf .inputs .inputnode .source_files = [bold_file ]
521
+
522
+ workflow .connect ([
523
+ (fmap_select , fmapreg_wf , [
524
+ ('fmap_ref' , 'inputnode.fmap_ref' ),
525
+ ('fmap_mask' , 'inputnode.fmap_mask' ),
526
+ ]),
527
+ (fmapreg_wf , itk_mat2txt , [('outputnode.target2fmap_xfm' , 'in_xfms' )]),
528
+ (itk_mat2txt , ds_fmapreg_wf , [('out_xfm' , 'inputnode.xform' )]),
529
+ (ds_fmapreg_wf , fmapreg_buffer , [('outputnode.xform' , 'boldref2fmap_xfm' )]),
530
+ ]) # fmt:skip
531
+ else :
532
+ config .loggers .workflow .info (
533
+ 'Stage 3: Found fieldmap transform - skipping registration'
534
+ )
535
+ else :
536
+ config .loggers .workflow .info ('No fieldmap correction - skipping Stage 3' )
537
+
538
+ # Stage 4: Create coregistration reference
467
539
if not coreg_boldref :
468
- config .loggers .workflow .info ('Stage 3 : Adding coregistration boldref workflow' )
540
+ config .loggers .workflow .info ('Stage 4 : Adding coregistration boldref workflow' )
469
541
470
542
# Select initial boldref, enhance contrast, and generate mask
471
543
if sbref_files and nb .load (sbref_files [0 ]).ndim > 3 :
@@ -492,63 +564,15 @@ def init_bold_fit_wf(
492
564
ds_boldmask_wf .inputs .inputnode .source_files = [bold_file ]
493
565
494
566
workflow .connect ([
495
- (hmcref_buffer , fmapref_buffer , [('boldref' , 'boldref_files' )]),
496
567
(fmapref_buffer , enhance_boldref_wf , [('out' , 'inputnode.in_file' )]),
497
568
(hmc_boldref_source_buffer , ds_coreg_boldref_wf , [
498
569
('in_file' , 'inputnode.source_files' ),
499
570
]),
500
571
(ds_coreg_boldref_wf , regref_buffer , [('outputnode.boldref' , 'boldref' )]),
501
572
(ds_boldmask_wf , regref_buffer , [('outputnode.boldmask' , 'boldmask' )]),
502
- (fmapref_buffer , func_fit_reports_wf , [('out' , 'inputnode.sdc_boldref' )]),
503
573
]) # fmt:skip
504
574
505
575
if fieldmap_id :
506
- fmap_select = pe .Node (
507
- KeySelect (
508
- fields = ['fmap_ref' , 'fmap_coeff' , 'fmap_mask' , 'sdc_method' ],
509
- key = fieldmap_id ,
510
- ),
511
- name = 'fmap_select' ,
512
- run_without_submitting = True ,
513
- )
514
-
515
- if not boldref2fmap_xform :
516
- fmapreg_wf = init_coeff2epi_wf (
517
- debug = 'fieldmaps' in config .execution .debug ,
518
- omp_nthreads = config .nipype .omp_nthreads ,
519
- sloppy = config .execution .sloppy ,
520
- name = 'fmapreg_wf' ,
521
- )
522
-
523
- itk_mat2txt = pe .Node (ConcatenateXFMs (out_fmt = 'itk' ), name = 'itk_mat2txt' )
524
-
525
- ds_fmapreg_wf = init_ds_registration_wf (
526
- bids_root = layout .root ,
527
- output_dir = config .execution .fmriprep_dir ,
528
- source = 'boldref' ,
529
- dest = fieldmap_id .replace ('_' , '' ),
530
- name = 'ds_fmapreg_wf' ,
531
- )
532
- ds_fmapreg_wf .inputs .inputnode .source_files = [bold_file ]
533
-
534
- workflow .connect ([
535
- (enhance_boldref_wf , fmapreg_wf , [
536
- ('outputnode.bias_corrected_file' , 'inputnode.target_ref' ),
537
- ('outputnode.mask_file' , 'inputnode.target_mask' ),
538
- ]),
539
- (fmap_select , fmapreg_wf , [
540
- ('fmap_ref' , 'inputnode.fmap_ref' ),
541
- ('fmap_mask' , 'inputnode.fmap_mask' ),
542
- ]),
543
- (fmapreg_wf , itk_mat2txt , [('outputnode.target2fmap_xfm' , 'in_xfms' )]),
544
- (itk_mat2txt , ds_fmapreg_wf , [('out_xfm' , 'inputnode.xform' )]),
545
- (ds_fmapreg_wf , fmapreg_buffer , [('outputnode.xform' , 'boldref2fmap_xfm' )]),
546
- ]) # fmt:skip
547
-
548
- boldref_fmap = pe .Node (
549
- ReconstructFieldmap (inverse = [True ]), name = 'boldref_fmap' , mem_gb = 1
550
- )
551
-
552
576
distortion_params = pe .Node (
553
577
DistortionParameters (
554
578
metadata = metadata ,
@@ -569,19 +593,6 @@ def init_bold_fit_wf(
569
593
skullstrip_bold_wf = init_skullstrip_bold_wf ()
570
594
571
595
workflow .connect ([
572
- (inputnode , fmap_select , [
573
- ('fmap_ref' , 'fmap_ref' ),
574
- ('fmap_coeff' , 'fmap_coeff' ),
575
- ('fmap_mask' , 'fmap_mask' ),
576
- ('sdc_method' , 'sdc_method' ),
577
- ('fmap_id' , 'keys' ),
578
- ]),
579
- (fmapref_buffer , boldref_fmap , [('out' , 'target_ref_file' )]),
580
- (fmapreg_buffer , boldref_fmap , [('boldref2fmap_xfm' , 'transforms' )]),
581
- (fmap_select , boldref_fmap , [
582
- ('fmap_coeff' , 'in_coeffs' ),
583
- ('fmap_ref' , 'fmap_ref_file' ),
584
- ]),
585
596
(fmapref_buffer , unwarp_boldref , [('out' , 'ref_file' )]),
586
597
(enhance_boldref_wf , unwarp_boldref , [
587
598
('outputnode.bias_corrected_file' , 'in_file' ),
@@ -600,13 +611,15 @@ def init_bold_fit_wf(
600
611
(skullstrip_bold_wf , ds_boldmask_wf , [
601
612
('outputnode.mask_file' , 'inputnode.boldmask' ),
602
613
]),
603
- (fmap_select , func_fit_reports_wf , [('fmap_ref' , 'inputnode.fmap_ref' )]),
604
- (fmap_select , summary , [('sdc_method' , 'distortion_correction' )]),
605
- (fmapreg_buffer , func_fit_reports_wf , [
606
- ('boldref2fmap_xfm' , 'inputnode.boldref2fmap_xfm' ),
607
- ]),
608
- (boldref_fmap , func_fit_reports_wf , [('out_file' , 'inputnode.fieldmap' )]),
609
614
]) # fmt:skip
615
+
616
+ if not boldref2fmap_xform :
617
+ workflow .connect ([
618
+ (enhance_boldref_wf , fmapreg_wf , [
619
+ ('outputnode.bias_corrected_file' , 'inputnode.target_ref' ),
620
+ ('outputnode.mask_file' , 'inputnode.target_mask' ),
621
+ ]),
622
+ ]) # fmt:skip
610
623
else :
611
624
workflow .connect ([
612
625
(enhance_boldref_wf , ds_coreg_boldref_wf , [
@@ -617,7 +630,7 @@ def init_bold_fit_wf(
617
630
]),
618
631
]) # fmt:skip
619
632
else :
620
- config .loggers .workflow .info ('Found coregistration reference - skipping Stage 3 ' )
633
+ config .loggers .workflow .info ('Found coregistration reference - skipping Stage 4 ' )
621
634
622
635
# TODO: Allow precomputed bold masks to be passed
623
636
# Also needs consideration for how it interacts above
@@ -628,6 +641,7 @@ def init_bold_fit_wf(
628
641
]) # fmt:skip
629
642
630
643
if not boldref2anat_xform :
644
+ config .loggers .workflow .info ('Stage 5: Adding coregistration workflow' )
631
645
use_bbr = (
632
646
True
633
647
if 'bbr' in config .workflow .force
@@ -654,7 +668,6 @@ def init_bold_fit_wf(
654
668
name = 'ds_boldreg_wf' ,
655
669
)
656
670
657
- # fmt:off
658
671
workflow .connect ([
659
672
(inputnode , bold_reg_wf , [
660
673
('t1w_preproc' , 'inputnode.t1w_preproc' ),
@@ -671,9 +684,9 @@ def init_bold_fit_wf(
671
684
(bold_reg_wf , ds_boldreg_wf , [('outputnode.itk_bold_to_t1' , 'inputnode.xform' )]),
672
685
(ds_boldreg_wf , outputnode , [('outputnode.xform' , 'boldref2anat_xfm' )]),
673
686
(bold_reg_wf , summary , [('outputnode.fallback' , 'fallback' )]),
674
- ])
675
- # fmt:on
687
+ ]) # fmt:skip
676
688
else :
689
+ config .loggers .workflow .info ('Found coregistration transform - skipping Stage 5' )
677
690
outputnode .inputs .boldref2anat_xfm = boldref2anat_xform
678
691
679
692
return workflow
0 commit comments