3030def init_bold_reference_wf (
3131 omp_nthreads ,
3232 bold_file = None ,
33+ sbref_files = None ,
3334 brainmask_thresh = 0.85 ,
3435 pre_mask = False ,
3536 multiecho = False ,
@@ -57,6 +58,10 @@ def init_bold_reference_wf(
5758 Maximum number of threads an individual process may use
5859 bold_file : :obj:`str`
5960 BOLD series NIfTI file
61+ sbref_files : :obj:`list` or :obj:`bool`
62+ Single band (as opposed to multi band) reference NIfTI file.
63+ If ``True`` is passed, the workflow is built to accommodate SBRefs,
64+ but the input is left undefined (i.e., it is left open for connection)
6065 brainmask_thresh: :obj:`float`
6166 Lower threshold for the probabilistic brainmask to obtain
6267 the final binary mask (default: 0.85).
@@ -109,16 +114,12 @@ def init_bold_reference_wf(
109114
110115 """
111116 workflow = Workflow (name = name )
112- if multiecho :
113- workflow .__desc__ = """\
117+ workflow .__desc__ = f"""\
114118 First, a reference volume and its skull-stripped version were generated
115- from the first echo using a custom methodology of *fMRIPrep*.
116- """
117- else :
118- workflow .__desc__ = """\
119- First, a reference volume and its skull-stripped version were generated
120- using a custom methodology of *fMRIPrep*.
119+ { 'from the shortest echo of the BOLD run' * multiecho } using a custom
120+ methodology of *fMRIPrep*.
121121"""
122+
122123 inputnode = pe .Node (
123124 niu .IdentityInterface (
124125 fields = ["bold_file" , "bold_mask" , "dummy_scans" , "sbref_file" ]
@@ -146,17 +147,12 @@ def init_bold_reference_wf(
146147 if bold_file is not None :
147148 inputnode .inputs .bold_file = bold_file
148149
149- if multiecho :
150- validate = pe .MapNode (
151- ValidateImage (),
152- name = "validate" ,
153- mem_gb = DEFAULT_MEMORY_MIN_GB ,
154- iterfield = ["in_file" ],
155- )
156- else :
157- validate = pe .Node (
158- ValidateImage (), name = "validate" , mem_gb = DEFAULT_MEMORY_MIN_GB
159- )
150+ val_bold = pe .MapNode (
151+ ValidateImage (),
152+ name = "val_bold" ,
153+ mem_gb = DEFAULT_MEMORY_MIN_GB ,
154+ iterfield = ["in_file" ],
155+ )
160156
161157 gen_ref = pe .Node (
162158 EstimateReferenceImage (multiecho = multiecho ), name = "gen_ref" , mem_gb = 1
@@ -173,25 +169,23 @@ def init_bold_reference_wf(
173169 run_without_submitting = True ,
174170 mem_gb = DEFAULT_MEMORY_MIN_GB ,
175171 )
176- sel_1st = pe .Node (niu .Select (index = [0 ]),
177- name = "sel_1st" , run_without_submitting = True )
172+ bold_1st = pe .Node (niu .Select (index = [0 ]),
173+ name = "bold_1st" , run_without_submitting = True )
174+ validate_1st = pe .Node (niu .Select (index = [0 ]),
175+ name = "validate_1st" , run_without_submitting = True )
178176
179177 # fmt: off
180178 workflow .connect ([
181- (inputnode , validate , [
182- (("bold_file" , ensure_list ) if multiecho else "bold_file" ,
183- "in_file" ),
184- ]),
179+ (inputnode , val_bold , [(("bold_file" , ensure_list ), "in_file" )]),
185180 (inputnode , enhance_and_skullstrip_bold_wf , [
186181 ("bold_mask" , "inputnode.pre_mask" ),
187182 ]),
188- (inputnode , gen_ref , [("sbref_file" , "sbref_file" )]),
189183 (inputnode , calc_dummy_scans , [("dummy_scans" , "dummy_scans" )]),
190- (validate , gen_ref , [("out_file" , "in_file" )]),
184+ (val_bold , gen_ref , [("out_file" , "in_file" )]),
191185 (gen_ref , enhance_and_skullstrip_bold_wf , [
192186 ("ref_image" , "inputnode.in_file" ),
193187 ]),
194- (validate , sel_1st , [(("out_file" , ensure_list ), "inlist" )]),
188+ (val_bold , bold_1st , [(("out_file" , ensure_list ), "inlist" )]),
195189 (gen_ref , calc_dummy_scans , [("n_volumes_to_discard" , "algo_dummy_scans" )]),
196190 (calc_dummy_scans , outputnode , [("skip_vols_num" , "skip_vols" )]),
197191 (gen_ref , outputnode , [
@@ -203,11 +197,39 @@ def init_bold_reference_wf(
203197 ("outputnode.mask_file" , "bold_mask" ),
204198 ("outputnode.skull_stripped_file" , "ref_image_brain" ),
205199 ]),
206- (validate , outputnode , [("out_report" , "validation_report" )]),
207- (sel_1st , outputnode , [("out" , "bold_file" )]),
200+ (val_bold , validate_1st , [(("out_report" , ensure_list ), "inlist" )]),
201+ (bold_1st , outputnode , [("out" , "bold_file" )]),
202+ (validate_1st , outputnode , [("out" , "validation_report" )]),
208203 ])
209204 # fmt: on
210205
206+ if sbref_files :
207+ nsbrefs = 0
208+ if sbref_files is not True :
209+ # If not boolean, then it is a list-of or pathlike.
210+ inputnode .inputs .sbref_file = sbref_files
211+ nsbrefs = 1 if isinstance (sbref_files , str ) else len (sbref_files )
212+
213+ val_sbref = pe .MapNode (
214+ ValidateImage (),
215+ name = "val_sbref" ,
216+ mem_gb = DEFAULT_MEMORY_MIN_GB ,
217+ iterfield = ["in_file" ],
218+ )
219+ # fmt: off
220+ workflow .connect ([
221+ (inputnode , val_sbref , [(("sbref_file" , ensure_list ), "in_file" )]),
222+ (val_sbref , gen_ref , [("sbref_file" , "sbref_file" )]),
223+ ])
224+ # fmt: on
225+
226+ # Edit the boilerplate as the SBRef will be the reference
227+ workflow .__desc__ = f"""\
228+ First, a reference volume and its skull-stripped version were generated
229+ by aligning and averaging{ ' the first echo of' * multiecho }
230+ { nsbrefs or '' } single-band references (SBRefs).
231+ """
232+
211233 if gen_report :
212234 mask_reportlet = pe .Node (SimpleShowMaskRPT (), name = "mask_reportlet" )
213235 # fmt: off
0 commit comments