57
57
from ...interfaces .reports import FunctionalSummary
58
58
from ...utils .bids import extract_entities
59
59
from ...utils .misc import combine_meepi_source
60
+ from .boldref import init_infant_epi_reference_wf
60
61
61
62
# BOLD workflows
62
63
from .confounds import init_bold_confs_wf , init_carpetplot_wf
@@ -127,12 +128,6 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False, existing_derivatives=Non
127
128
LTA-style affine matrix translating from T1w to FreeSurfer-conformed subject space
128
129
fsnative2t1w_xfm
129
130
LTA-style affine matrix translating from FreeSurfer-conformed subject space to T1w
130
- bold_ref
131
- BOLD reference file
132
- bold_ref_xfm
133
- Transform file in LTA format from bold to reference
134
- n_dummy_scans
135
- Number of nonsteady states at the beginning of the BOLD run
136
131
137
132
Outputs
138
133
-------
@@ -177,6 +172,7 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False, existing_derivatives=Non
177
172
178
173
"""
179
174
from niworkflows .engine .workflows import LiterateWorkflow as Workflow
175
+ from niworkflows .interfaces .bold import NonsteadyStatesDetector
180
176
from niworkflows .interfaces .nibabel import ApplyMask
181
177
from niworkflows .interfaces .utility import DictMerge , KeySelect
182
178
from niworkflows .workflows .epi .refmap import init_epi_reference_wf
@@ -244,9 +240,14 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False, existing_derivatives=Non
244
240
)
245
241
246
242
# Find associated sbref, if possible
247
- entities ["suffix" ] = "sbref"
248
- entities ["extension" ] = [".nii" , ".nii.gz" ] # Overwrite extensions
249
- sbref_files = layout .get (scope = "raw" , return_type = "file" , ** entities )
243
+ overrides = {
244
+ "suffix" : "sbref" ,
245
+ "extension" : [".nii" , ".nii.gz" ],
246
+ }
247
+ if config .execution .bids_filters :
248
+ overrides .update (config .execution .bids_filters .get ('sbref' , {}))
249
+ sb_ents = {** entities , ** overrides }
250
+ sbref_files = layout .get (return_type = "file" , ** sb_ents )
250
251
251
252
sbref_msg = f"No single-band-reference found for { os .path .basename (ref_file )} ."
252
253
if sbref_files and "sbref" in config .workflow .ignore :
@@ -319,10 +320,6 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False, existing_derivatives=Non
319
320
"anat2std_xfm" ,
320
321
"std2anat_xfm" ,
321
322
"template" ,
322
- # from bold reference workflow
323
- "bold_ref" ,
324
- "bold_ref_xfm" ,
325
- "n_dummy_scans" ,
326
323
# from sdcflows (optional)
327
324
"fmap" ,
328
325
"fmap_ref" ,
@@ -514,12 +511,21 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False, existing_derivatives=Non
514
511
)
515
512
bold_confounds_wf .get_node ("inputnode" ).inputs .t1_transform_flags = [False ]
516
513
514
+ dummy_buffer = pe .Node (niu .IdentityInterface (fields = ['n_dummy' ]), name = 'dummy_buffer' )
515
+ if (dummy := config .workflow .dummy_scans ) is not None :
516
+ dummy_buffer .inputs .n_dummy = dummy
517
+ else :
518
+ # Detect dummy scans
519
+ nss_detector = pe .Node (NonsteadyStatesDetector (), name = 'nss_detector' )
520
+ nss_detector .inputs .in_file = ref_file
521
+ workflow .connect (nss_detector , 'n_dummy' , dummy_buffer , 'n_dummy' )
522
+
517
523
# SLICE-TIME CORRECTION (or bypass) #############################################
518
524
if run_stc :
519
525
bold_stc_wf = init_bold_stc_wf (name = "bold_stc_wf" , metadata = metadata )
520
526
# fmt:off
521
527
workflow .connect ([
522
- (inputnode , bold_stc_wf , [('n_dummy_scans ' , 'inputnode.skip_vols' )]),
528
+ (dummy_buffer , bold_stc_wf , [('n_dummy ' , 'inputnode.skip_vols' )]),
523
529
(select_bold , bold_stc_wf , [("out" , 'inputnode.bold_file' )]),
524
530
(bold_stc_wf , boldbuffer , [('outputnode.stc_file' , 'bold_file' )]),
525
531
])
@@ -577,8 +583,11 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False, existing_derivatives=Non
577
583
name = "bold_final" ,
578
584
)
579
585
580
- # Mask input BOLD reference image
581
- initial_boldref_mask = pe .Node (BrainExtraction (), name = "initial_boldref_mask" )
586
+ # Create a reference image for the bold run
587
+ initial_boldref_wf = init_infant_epi_reference_wf (omp_nthreads , is_sbref = bool (sbref_files ))
588
+ initial_boldref_wf .inputs .inputnode .epi_file = (
589
+ pop_file (sbref_files ) if sbref_files else ref_file
590
+ )
582
591
583
592
# This final boldref will be calculated after bold_bold_trans_wf, which includes one or more:
584
593
# HMC (head motion correction)
@@ -602,8 +611,8 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False, existing_derivatives=Non
602
611
# BOLD buffer has slice-time corrected if it was run, original otherwise
603
612
(boldbuffer , bold_split , [('bold_file' , 'in_file' )]),
604
613
# HMC
605
- (inputnode , bold_hmc_wf , [
606
- ('bold_ref ' , 'inputnode.raw_ref_image' )]),
614
+ (initial_boldref_wf , bold_hmc_wf , [
615
+ ('outputnode.boldref_file ' , 'inputnode.raw_ref_image' )]),
607
616
(validate_bolds , bold_hmc_wf , [
608
617
(("out_file" , pop_file ), 'inputnode.bold_file' )]),
609
618
(bold_hmc_wf , outputnode , [
@@ -659,8 +668,8 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False, existing_derivatives=Non
659
668
('outputnode.rmsd_file' , 'inputnode.rmsd_file' )]),
660
669
(bold_reg_wf , bold_confounds_wf , [
661
670
('outputnode.itk_t1_to_bold' , 'inputnode.t1_bold_xform' )]),
662
- (inputnode , bold_confounds_wf , [
663
- ('n_dummy_scans ' , 'inputnode.skip_vols' )]),
671
+ (dummy_buffer , bold_confounds_wf , [
672
+ ('n_dummy ' , 'inputnode.skip_vols' )]),
664
673
(bold_final , bold_confounds_wf , [
665
674
('bold' , 'inputnode.bold' ),
666
675
('mask' , 'inputnode.bold_mask' ),
@@ -672,7 +681,7 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False, existing_derivatives=Non
672
681
('outputnode.tcompcor_mask' , 'tcompcor_mask' ),
673
682
]),
674
683
# Summary
675
- (inputnode , summary , [('n_dummy_scans ' , 'algo_dummy_scans' )]),
684
+ (dummy_buffer , summary , [('n_dummy ' , 'algo_dummy_scans' )]),
676
685
(bold_reg_wf , summary , [('outputnode.fallback' , 'fallback' )]),
677
686
(outputnode , summary , [('confounds' , 'confounds_file' )]),
678
687
# Select echo indices for original/validated BOLD files
@@ -874,8 +883,8 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False, existing_derivatives=Non
874
883
('bold_file' , 'inputnode.name_source' )]),
875
884
(bold_hmc_wf , ica_aroma_wf , [
876
885
('outputnode.movpar_file' , 'inputnode.movpar_file' )]),
877
- (inputnode , ica_aroma_wf , [
878
- ('n_dummy_scans ' , 'inputnode.skip_vols' )]),
886
+ (dummy_buffer , ica_aroma_wf , [
887
+ ('n_dummy ' , 'inputnode.skip_vols' )]),
879
888
(bold_confounds_wf , join , [
880
889
('outputnode.confounds_file' , 'in_file' )]),
881
890
(bold_confounds_wf , mrg_conf_metadata ,
@@ -1051,9 +1060,8 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False, existing_derivatives=Non
1051
1060
("outputnode.bold" , "inputnode.in_files" ),
1052
1061
]),
1053
1062
] if not multiecho else [
1054
- (inputnode , initial_boldref_mask , [('bold_ref' , 'in_file' )]),
1055
- (initial_boldref_mask , bold_t2s_wf , [
1056
- ("out_mask" , "inputnode.bold_mask" ),
1063
+ (initial_boldref_wf , bold_t2s_wf , [
1064
+ ("outputnode.boldref_mask" , "inputnode.bold_mask" ),
1057
1065
]),
1058
1066
(bold_bold_trans_wf , join_echos , [
1059
1067
("outputnode.bold" , "bold_files" ),
@@ -1125,14 +1133,13 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False, existing_derivatives=Non
1125
1133
("fmap_coeff" , "inputnode.fmap_coeff" ),
1126
1134
("fmap_mask" , "inputnode.fmap_mask" )]),
1127
1135
(output_select , summary , [("sdc_method" , "distortion_correction" )]),
1128
- (inputnode , initial_boldref_mask , [('bold_ref' , 'in_file' )]),
1129
- (inputnode , coeff2epi_wf , [
1130
- ("bold_ref" , "inputnode.target_ref" )]),
1131
- (initial_boldref_mask , coeff2epi_wf , [
1132
- ("out_mask" , "inputnode.target_mask" )]), # skull-stripped brain
1136
+ (initial_boldref_wf , coeff2epi_wf , [
1137
+ ("outputnode.boldref_file" , "inputnode.target_ref" )]),
1138
+ (initial_boldref_wf , coeff2epi_wf , [
1139
+ ("outputnode.boldref_mask" , "inputnode.target_mask" )]), # skull-stripped brain
1133
1140
(coeff2epi_wf , unwarp_wf , [
1134
1141
("outputnode.fmap_coeff" , "inputnode.fmap_coeff" )]),
1135
- (inputnode , sdc_report , [("bold_ref " , "before" )]),
1142
+ (initial_boldref_wf , sdc_report , [("outputnode.boldref_file " , "before" )]),
1136
1143
(bold_hmc_wf , unwarp_wf , [
1137
1144
("outputnode.xforms" , "inputnode.hmc_xforms" )]),
1138
1145
(bold_split , unwarp_wf , [
0 commit comments