54
54
init_ds_registration_wf ,
55
55
init_ds_volumes_wf ,
56
56
init_func_derivatives_wf ,
57
+ prepare_timing_parameters ,
57
58
)
58
59
from .registration import init_bold_reg_wf , init_bold_t1_trans_wf
59
60
from .resampling import (
@@ -189,9 +190,16 @@ def init_bold_wf(
189
190
"t1w_mask" ,
190
191
"t1w_dseg" ,
191
192
"t1w_tpms" ,
193
+ # FreeSurfer outputs
192
194
"subjects_dir" ,
193
195
"subject_id" ,
194
196
"fsnative2t1w_xfm" ,
197
+ "white" ,
198
+ "midthickness" ,
199
+ "pial" ,
200
+ "thickness" ,
201
+ "sphere_reg_fsLR" ,
202
+ "anat_ribbon" ,
195
203
# Fieldmap registration
196
204
"fmap" ,
197
205
"fmap_ref" ,
@@ -206,6 +214,9 @@ def init_bold_wf(
206
214
"std_cohort" ,
207
215
"std_t1w" ,
208
216
"std_mask" ,
217
+ # MNI152NLin6Asym warp, for CIFTI use
218
+ "anat2mni6_xfm" ,
219
+ "mni6_mask" ,
209
220
],
210
221
),
211
222
name = "inputnode" ,
@@ -389,7 +400,7 @@ def init_bold_wf(
389
400
(bold_anat_wf , ds_bold_t1_wf , [('outputnode.bold_file' , 'inputnode.bold' )]),
390
401
]) # fmt:skip
391
402
392
- if spaces .get_spaces (nonstandard = False , dim = (3 ,)):
403
+ if spaces .cached . get_spaces (nonstandard = False , dim = (3 ,)):
393
404
# Missing:
394
405
# * Clipping BOLD after resampling
395
406
# * Resampling parcellations
@@ -462,6 +473,87 @@ def init_bold_wf(
462
473
(bold_anat_wf , bold_surf_wf , [("outputnode.bold_file" , "inputnode.bold_t1w" )]),
463
474
]) # fmt:skip
464
475
476
+ if config .workflow .cifti_output :
477
+ from .resampling import init_bold_fsLR_resampling_wf , init_bold_grayords_wf
478
+
479
+ bold_MNI6_wf = init_bold_volumetric_resample_wf (
480
+ metadata = all_metadata [0 ],
481
+ fieldmap_id = fieldmap_id if not multiecho else None ,
482
+ omp_nthreads = omp_nthreads ,
483
+ name = 'bold_MNI6_wf' ,
484
+ )
485
+
486
+ bold_fsLR_resampling_wf = init_bold_fsLR_resampling_wf (
487
+ estimate_goodvoxels = config .workflow .project_goodvoxels ,
488
+ grayord_density = config .workflow .cifti_output ,
489
+ omp_nthreads = omp_nthreads ,
490
+ mem_gb = mem_gb ["resampled" ],
491
+ )
492
+
493
+ bold_grayords_wf = init_bold_grayords_wf (
494
+ grayord_density = config .workflow .cifti_output ,
495
+ mem_gb = mem_gb ["resampled" ],
496
+ repetition_time = all_metadata [0 ]["RepetitionTime" ],
497
+ )
498
+
499
+ ds_bold_cifti = pe .Node (
500
+ DerivativesDataSink (
501
+ base_directory = fmriprep_dir ,
502
+ space = 'fsLR' ,
503
+ density = config .workflow .cifti_output ,
504
+ suffix = 'bold' ,
505
+ compress = False ,
506
+ TaskName = all_metadata [0 ].get ('TaskName' ),
507
+ ** prepare_timing_parameters (all_metadata [0 ]),
508
+ ),
509
+ name = 'ds_bold_cifti' ,
510
+ run_without_submitting = True ,
511
+ )
512
+ ds_bold_cifti .inputs .source_file = bold_file
513
+
514
+ workflow .connect ([
515
+ # Resample BOLD to MNI152NLin6Asym, may duplicate bold_std_wf above
516
+ (inputnode , bold_MNI6_wf , [
517
+ ("mni6_mask" , "inputnode.target_ref_file" ),
518
+ ("mni6_mask" , "inputnode.target_mask" ),
519
+ ("anat2mni6_xfm" , "inputnode.anat2std_xfm" ),
520
+ ("fmap_ref" , "inputnode.fmap_ref" ),
521
+ ("fmap_coeff" , "inputnode.fmap_coeff" ),
522
+ ("fmap_id" , "inputnode.fmap_id" ),
523
+ ]),
524
+ (bold_fit_wf , bold_MNI6_wf , [
525
+ ("outputnode.coreg_boldref" , "inputnode.bold_ref_file" ),
526
+ ("outputnode.boldref2fmap_xfm" , "inputnode.boldref2fmap_xfm" ),
527
+ ("outputnode.boldref2anat_xfm" , "inputnode.boldref2anat_xfm" ),
528
+ ]),
529
+ (bold_native_wf , bold_MNI6_wf , [
530
+ ("outputnode.bold_minimal" , "inputnode.bold_file" ),
531
+ ("outputnode.motion_xfm" , "inputnode.motion_xfm" ),
532
+ ]),
533
+ # Resample T1w-space BOLD to fsLR surfaces
534
+ (inputnode , bold_fsLR_resampling_wf , [
535
+ ("white" , "inputnode.white" ),
536
+ ("pial" , "inputnode.pial" ),
537
+ ("midthickness" , "inputnode.midthickness" ),
538
+ ("thickness" , "inputnode.thickness" ),
539
+ ("sphere_reg_fsLR" , "inputnode.sphere_reg_fsLR" ),
540
+ ("anat_ribbon" , "inputnode.anat_ribbon" ),
541
+ ]),
542
+ (bold_anat_wf , bold_fsLR_resampling_wf , [
543
+ ("outputnode.bold_file" , "inputnode.bold_file" ),
544
+ ]),
545
+ (bold_MNI6_wf , bold_grayords_wf , [
546
+ ("outputnode.bold_file" , "inputnode.bold_std" ),
547
+ ]),
548
+ (bold_fsLR_resampling_wf , bold_grayords_wf , [
549
+ ("outputnode.bold_fsLR" , "inputnode.bold_fsLR" ),
550
+ ]),
551
+ (bold_grayords_wf , ds_bold_cifti , [
552
+ ('outputnode.cifti_bold' , 'in_file' ),
553
+ (('outputnode.cifti_metadata' , _read_json ), 'meta_dict' ),
554
+ ]),
555
+ ]) # fmt:skip
556
+
465
557
bold_confounds_wf = init_bold_confs_wf (
466
558
mem_gb = mem_gb ["largemem" ],
467
559
metadata = all_metadata [0 ],
@@ -657,7 +749,6 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False):
657
749
spaces = config .workflow .spaces
658
750
fmriprep_dir = str (config .execution .fmriprep_dir )
659
751
freesurfer_spaces = spaces .get_fs_spaces ()
660
- project_goodvoxels = config .workflow .project_goodvoxels and config .workflow .cifti_output
661
752
662
753
ref_file = bold_file
663
754
wf_name = _get_wf_name (ref_file , "func_preproc" )
@@ -745,52 +836,6 @@ def init_func_preproc_wf(bold_file, has_fieldmap=False):
745
836
# SURFACES ##################################################################################
746
837
747
838
# CIFTI output
748
- if config .workflow .cifti_output :
749
- from .resampling import init_bold_fsLR_resampling_wf , init_bold_grayords_wf
750
-
751
- bold_fsLR_resampling_wf = init_bold_fsLR_resampling_wf (
752
- estimate_goodvoxels = project_goodvoxels ,
753
- grayord_density = config .workflow .cifti_output ,
754
- omp_nthreads = omp_nthreads ,
755
- mem_gb = mem_gb ["resampled" ],
756
- )
757
-
758
- bold_grayords_wf = init_bold_grayords_wf (
759
- grayord_density = config .workflow .cifti_output ,
760
- mem_gb = mem_gb ["resampled" ],
761
- repetition_time = metadata ["RepetitionTime" ],
762
- )
763
-
764
- # fmt:off
765
- workflow .connect ([
766
- (inputnode , bold_fsLR_resampling_wf , [
767
- ("surfaces" , "inputnode.surfaces" ),
768
- ("morphometrics" , "inputnode.morphometrics" ),
769
- ("sphere_reg_fsLR" , "inputnode.sphere_reg_fsLR" ),
770
- ("anat_ribbon" , "inputnode.anat_ribbon" ),
771
- ]),
772
- (bold_t1_trans_wf , bold_fsLR_resampling_wf , [
773
- ("outputnode.bold_t1" , "inputnode.bold_file" ),
774
- ]),
775
- (bold_std_trans_wf , bold_grayords_wf , [
776
- ("outputnode.bold_std" , "inputnode.bold_std" ),
777
- ("outputnode.spatial_reference" , "inputnode.spatial_reference" ),
778
- ]),
779
- (bold_fsLR_resampling_wf , bold_grayords_wf , [
780
- ("outputnode.bold_fsLR" , "inputnode.bold_fsLR" ),
781
- ]),
782
- (bold_fsLR_resampling_wf , func_derivatives_wf , [
783
- ("outputnode.goodvoxels_mask" , "inputnode.goodvoxels_mask" ),
784
- ]),
785
- (bold_fsLR_resampling_wf , outputnode , [
786
- ("outputnode.weights_text" , "weights_text" ),
787
- ]),
788
- (bold_grayords_wf , outputnode , [
789
- ("outputnode.cifti_bold" , "bold_cifti" ),
790
- ("outputnode.cifti_metadata" , "cifti_metadata" ),
791
- ]),
792
- ])
793
- # fmt:on
794
839
795
840
if spaces .get_spaces (nonstandard = False , dim = (3 ,)):
796
841
carpetplot_wf = init_carpetplot_wf (
@@ -950,3 +995,10 @@ def get_img_orientation(imgf):
950
995
"""Return the image orientation as a string"""
951
996
img = nb .load (imgf )
952
997
return "" .join (nb .aff2axcodes (img .affine ))
998
+
999
+
1000
+ def _read_json (in_file ):
1001
+ from json import loads
1002
+ from pathlib import Path
1003
+
1004
+ return loads (Path (in_file ).read_text ())
0 commit comments