@@ -287,6 +287,7 @@ def init_single_subject_wf(subject_id):
287
287
return workflow
288
288
289
289
from .dwi .base import init_dwi_preproc_wf
290
+
290
291
# Append the dMRI section to the existing anatomical excerpt
291
292
# That way we do not need to stream down the number of DWI datasets
292
293
anat_preproc_wf .__postdesc__ = (
@@ -301,61 +302,86 @@ def init_single_subject_wf(subject_id):
301
302
"""
302
303
)
303
304
305
+ # SDC Step 0: Determine whether fieldmaps can/should be estimated
306
+ fmap_estimators = None
307
+ if "fieldmap" not in config .workflow .ignore :
308
+ from sdcflows import fieldmaps as fm
309
+ from sdcflows .utils .wrangler import find_estimators
310
+ from sdcflows .workflows .base import init_fmap_preproc_wf
311
+
312
+ # SDC Step 1: Run basic heuristics to identify available data for fieldmap estimation
313
+ fmap_estimators = find_estimators (config .execution .layout )
314
+
315
+ # Add fieldmap-less estimators
316
+ if not fmap_estimators and config .workflow .use_syn :
317
+ # estimators = [fm.FieldmapEstimation()]
318
+ raise NotImplementedError
319
+
320
+ # Nuts and bolts: initialize individual run's pipeline
321
+ dwi_preproc_list = []
304
322
for dwi_file in subject_data ["dwi" ]:
305
- dwi_preproc_wf = init_dwi_preproc_wf (dwi_file )
323
+ dwi_preproc_wf = init_dwi_preproc_wf (
324
+ dwi_file ,
325
+ has_fieldmap = bool (fmap_estimators ),
326
+ )
306
327
307
328
# fmt: off
308
329
workflow .connect ([
309
- (anat_preproc_wf , dwi_preproc_wf ,
310
- [("outputnode.t1w_preproc" , "inputnode.t1w_preproc" ),
311
- ("outputnode.t1w_mask" , "inputnode.t1w_mask" ),
312
- ("outputnode.t1w_dseg" , "inputnode.t1w_dseg" ),
313
- ("outputnode.t1w_aseg" , "inputnode.t1w_aseg" ),
314
- ("outputnode.t1w_aparc" , "inputnode.t1w_aparc" ),
315
- ("outputnode.t1w_tpms" , "inputnode.t1w_tpms" ),
316
- ("outputnode.template" , "inputnode.template" ),
317
- ("outputnode.anat2std_xfm" , "inputnode.anat2std_xfm" ),
318
- ("outputnode.std2anat_xfm" , "inputnode.std2anat_xfm" ),
319
- # Undefined if --fs-no-reconall, but this is safe
320
- ("outputnode.subjects_dir" , "inputnode.subjects_dir" ),
321
- ("outputnode.t1w2fsnative_xfm" , "inputnode.t1w2fsnative_xfm" ),
322
- ("outputnode.fsnative2t1w_xfm" , "inputnode.fsnative2t1w_xfm" )]),
330
+ (anat_preproc_wf , dwi_preproc_wf , [
331
+ ("outputnode.t1w_preproc" , "inputnode.t1w_preproc" ),
332
+ ("outputnode.t1w_mask" , "inputnode.t1w_mask" ),
333
+ ("outputnode.t1w_dseg" , "inputnode.t1w_dseg" ),
334
+ ("outputnode.t1w_aseg" , "inputnode.t1w_aseg" ),
335
+ ("outputnode.t1w_aparc" , "inputnode.t1w_aparc" ),
336
+ ("outputnode.t1w_tpms" , "inputnode.t1w_tpms" ),
337
+ ("outputnode.template" , "inputnode.template" ),
338
+ ("outputnode.anat2std_xfm" , "inputnode.anat2std_xfm" ),
339
+ ("outputnode.std2anat_xfm" , "inputnode.std2anat_xfm" ),
340
+ # Undefined if --fs-no-reconall, but this is safe
341
+ ("outputnode.subjects_dir" , "inputnode.subjects_dir" ),
342
+ ("outputnode.t1w2fsnative_xfm" , "inputnode.t1w2fsnative_xfm" ),
343
+ ("outputnode.fsnative2t1w_xfm" , "inputnode.fsnative2t1w_xfm" ),
344
+ ]),
323
345
(bids_info , dwi_preproc_wf , [("subject" , "inputnode.subject_id" )]),
324
346
])
325
347
# fmt: on
326
348
327
- if "fieldmap" in config .workflow .ignore :
328
- return workflow
329
-
330
- from sdcflows import fieldmaps as fm
331
- from sdcflows .utils .wrangler import find_estimators
332
- from sdcflows .workflows .base import init_fmap_preproc_wf
349
+ # Keep a handle to each workflow
350
+ dwi_preproc_list .append (dwi_preproc_wf )
333
351
334
- # SDCFlows connection
335
- # Step 1: Run basic heuristics to identify available data for fieldmap estimation
336
- estimators = find_estimators (config .execution .layout )
337
-
338
- if not estimators and config .workflow .use_syn : # Add fieldmap-less estimators
339
- # estimators = [fm.FieldmapEstimation()]
340
- raise NotImplementedError
352
+ if not fmap_estimators :
353
+ return workflow
341
354
342
- # Step 2: Manually add further estimators (e.g., fieldmap-less)
355
+ # SDC Step 2: Manually add further estimators (e.g., fieldmap-less)
343
356
fmap_wf = init_fmap_preproc_wf (
344
357
debug = config .execution .debug ,
345
- estimators = estimators ,
358
+ estimators = fmap_estimators ,
346
359
omp_nthreads = config .nipype .omp_nthreads ,
347
360
output_dir = str (output_dir ),
348
361
subject = subject_id ,
349
362
)
350
363
364
+ # TODO: Requires nipreps/sdcflows#147
365
+ for dwi_preproc_wf in dwi_preproc_list :
366
+ # fmt: off
367
+ workflow .connect ([
368
+ (fmap_wf , dwi_preproc_wf , [
369
+ ("outputnode.fmap" , "inputnode.fmap" ),
370
+ ("outputnode.fmap_ref" , "inputnode.fmap_ref" ),
371
+ ("outputnode.fmap_coeff" , "inputnode.fmap_coeff" ),
372
+ ("outputnode.fmap_mask" , "inputnode.fmap_mask" ),
373
+ ("outputnode.fmap_id" , "inputnode.fmap_id" ),
374
+ ]),
375
+ ])
376
+ # fmt: on
377
+
351
378
# Overwrite ``out_path_base`` of sdcflows's DataSinks
352
379
for node in fmap_wf .list_node_names ():
353
380
if node .split ("." )[- 1 ].startswith ("ds_" ):
354
381
fmap_wf .get_node (node ).interface .out_path_base = "dmriprep"
355
- workflow .add_nodes ([fmap_wf ])
356
382
357
383
# Step 3: Manually connect PEPOLAR
358
- for estimator in estimators :
384
+ for estimator in fmap_estimators :
359
385
if estimator .method != fm .EstimatorType .PEPOLAR :
360
386
continue
361
387
@@ -372,18 +398,18 @@ def init_single_subject_wf(subject_id):
372
398
raise NotImplementedError
373
399
# from niworkflows.interfaces.utility import KeySelect
374
400
# est_id = estimator.bids_id
375
- # fmap_select = pe.MapNode(
401
+ # estim_select = pe.MapNode(
376
402
# KeySelect(fields=["metadata", "dwi_reference", "dwi_mask", "gradients_rasb",]),
377
403
# name=f"fmap_select_{est_id}",
378
404
# run_without_submitting=True,
379
405
# iterfields=["key"]
380
406
# )
381
- # fmap_select .inputs.key = [
407
+ # estim_select .inputs.key = [
382
408
# str(s.path) for s in estimator.sources if s.suffix in ("epi", "dwi", "sbref")
383
409
# ]
384
410
# # fmt:off
385
411
# workflow.connect([
386
- # (referencenode, fmap_select , [("dwi_file", "keys"),
412
+ # (referencenode, estim_select , [("dwi_file", "keys"),
387
413
# ("metadata", "metadata"),
388
414
# ("dwi_reference", "dwi_reference"),
389
415
# ("gradients_rasb", "gradients_rasb")]),
0 commit comments