@@ -378,6 +378,21 @@ def init_single_subject_wf(subject_id):
378
378
if anat_only :
379
379
return workflow
380
380
381
+ # Susceptibility distortion correction
382
+ fmap_estimators = None
383
+ if "fieldmap" not in config .workflow .ignore :
384
+ from sdcflows .utils .wrangler import find_estimators
385
+ from sdcflows .workflows .base import init_fmap_preproc_wf
386
+
387
+ # SDC Step 1: Run basic heuristics to identify available data for fieldmap estimation
388
+ # For now, no fmapless
389
+ fmap_estimators = find_estimators (
390
+ layout = config .execution .layout ,
391
+ subject = subject_id ,
392
+ fmapless = False , # config.workflow.use_syn,
393
+ force_fmapless = False , # config.workflow.force_syn,
394
+ )
395
+
381
396
# Append the functional section to the existing anatomical exerpt
382
397
# That way we do not need to stream down the number of bold datasets
383
398
anat_preproc_wf .__postdesc__ = (
@@ -406,16 +421,19 @@ def init_single_subject_wf(subject_id):
406
421
print ("No BOLD files found for one or more reference groupings" )
407
422
return workflow
408
423
424
+ func_preproc_wfs = []
409
425
for idx , bold_files in enumerate (bold_groupings ):
410
426
bold_ref_wf = init_epi_reference_wf (
411
427
auto_bold_nss = True ,
412
428
name = f'bold_reference_wf{ idx } ' ,
413
429
omp_nthreads = config .nipype .omp_nthreads
414
430
)
415
431
bold_ref_wf .inputs .inputnode .in_files = bold_files
416
-
417
432
for idx , bold_file in enumerate (bold_files ):
418
- func_preproc_wf = init_func_preproc_wf (bold_file )
433
+ func_preproc_wf = init_func_preproc_wf (
434
+ bold_file ,
435
+ has_fieldmap = bool (fmap_estimators )
436
+ )
419
437
# fmt: off
420
438
workflow .connect ([
421
439
(bold_ref_wf , func_preproc_wf , [
@@ -446,6 +464,79 @@ def init_single_subject_wf(subject_id):
446
464
]),
447
465
])
448
466
# fmt: on
467
+ func_preproc_wfs .append (func_preproc_wf )
468
+
469
+ if not fmap_estimators :
470
+ config .loggers .workflow .warning (
471
+ "Data for fieldmap estimation not present. Please note that these data "
472
+ "will not be corrected for susceptibility distortions."
473
+ )
474
+ return workflow
475
+
476
+ config .loggers .workflow .info (
477
+ f"Fieldmap estimators found: { [e .method for e in fmap_estimators ]} "
478
+ )
479
+
480
+ from sdcflows .workflows .base import init_fmap_preproc_wf
481
+ from sdcflows import fieldmaps as fm
482
+
483
+ fmap_wf = init_fmap_preproc_wf (
484
+ debug = bool (config .execution .debug ), # TODO: Add debug option for fieldmaps
485
+ estimators = fmap_estimators ,
486
+ omp_nthreads = config .nipype .omp_nthreads ,
487
+ output_dir = nibabies_dir ,
488
+ subject = subject_id ,
489
+ )
490
+ fmap_wf .__desc__ = f"""
491
+
492
+ Fieldmap data preprocessing
493
+
494
+ : A total of { len (fmap_estimators )} fieldmaps were found available within the input
495
+ BIDS structure for this particular subject.
496
+ """
497
+
498
+ for func_preproc_wf in func_preproc_wfs :
499
+ # fmt: off
500
+ workflow .connect ([
501
+ (fmap_wf , func_preproc_wf , [
502
+ ("outputnode.fmap" , "inputnode.fmap" ),
503
+ ("outputnode.fmap_ref" , "inputnode.fmap_ref" ),
504
+ ("outputnode.fmap_coeff" , "inputnode.fmap_coeff" ),
505
+ ("outputnode.fmap_mask" , "inputnode.fmap_mask" ),
506
+ ("outputnode.fmap_id" , "inputnode.fmap_id" ),
507
+ ]),
508
+ ])
509
+ # fmt: on
510
+
511
+ # Overwrite ``out_path_base`` of sdcflows's DataSinks
512
+ for node in fmap_wf .list_node_names ():
513
+ if node .split ("." )[- 1 ].startswith ("ds_" ):
514
+ fmap_wf .get_node (node ).interface .out_path_base = ""
515
+
516
+ # Step 3: Manually connect PEPOLAR
517
+ for estimator in fmap_estimators :
518
+ config .loggers .workflow .info (f"""\
519
+ Setting-up fieldmap "{ estimator .bids_id } " ({ estimator .method } ) with \
520
+ <{ ', ' .join (s .path .name for s in estimator .sources )} >""" )
521
+ if estimator .method in (fm .EstimatorType .MAPPED , fm .EstimatorType .PHASEDIFF ):
522
+ continue
523
+
524
+ suffices = set (s .suffix for s in estimator .sources )
525
+
526
+ if estimator .method == fm .EstimatorType .PEPOLAR and sorted (suffices ) == ["epi" ]:
527
+ getattr (fmap_wf .inputs , f"in_{ estimator .bids_id } " ).in_data = [
528
+ str (s .path ) for s in estimator .sources
529
+ ]
530
+ getattr (fmap_wf .inputs , f"in_{ estimator .bids_id } " ).metadata = [
531
+ s .metadata for s in estimator .sources
532
+ ]
533
+ continue
534
+
535
+ if estimator .method == fm .EstimatorType .PEPOLAR :
536
+ raise NotImplementedError (
537
+ "Sophisticated PEPOLAR schemes (e.g., using DWI+EPI) are unsupported."
538
+ )
539
+
449
540
return workflow
450
541
451
542
0 commit comments