@@ -1284,14 +1284,12 @@ def acpc_align_head_with_mask(wf, cfg, strat_pool, pipe_num, opt=None):
12841284 "option_key": "None",
12851285 "option_val": "None",
12861286 "inputs": [("desc-head_T1w", "desc-preproc_T1w",
1287- ["space-T1w_desc-brain_mask",
1288- "space-T1w_desc-brain_mask"]),
1287+ "space-T1w_desc-brain_mask"),
12891288 "T1w-ACPC-template",
12901289 "T1w-brain-ACPC-template"],
12911290 "outputs": ["desc-head_T1w",
12921291 "desc-preproc_T1w",
1293- ["space-T1w_desc-brain_mask",
1294- "space-T1w_desc-brain_mask"],
1292+ "space-T1w_desc-brain_mask",
12951293 "from-T1w_to-ACPC_mode-image_desc-aff2rig_xfm"]}
12961294 '''
12971295
@@ -2532,10 +2530,182 @@ def brain_extraction_temp_T2(wf, cfg, strat_pool, pipe_num, opt=None):
25322530
25332531 return (wf , outputs )
25342532
2533+ def freesurfer_abcd_preproc (wf , cfg , strat_pool , pipe_num , opt = None ):
2534+ '''
2535+ {"name": "freesurfer_abcd_preproc",
2536+ "config": ["anatomical_preproc", "brain_extraction"],
2537+ "switch": "None",
2538+ "option_key": "using",
2539+ "option_val": "FreeSurfer-ABCD",
2540+ "inputs": ["desc-preproc_T1w",
2541+ "T1w-template",
2542+ "T1w-brain-template-mask",
2543+ "template-ref-mask-res-2",
2544+ "T1w-template-res-2",
2545+ "freesurfer-subject-dir"],
2546+ "outputs": ["desc-restore_T1w",
2547+ "desc-restore-brain_T1w",
2548+ "pipeline-fs_desc-fast_biasfield",
2549+ "pipeline-fs_hemi-L_desc-surface_curv",
2550+ "pipeline-fs_hemi-R_desc-surface_curv",
2551+ "pipeline-fs_hemi-L_desc-surfaceMesh_pial",
2552+ "pipeline-fs_hemi-R_desc-surfaceMesh_pial",
2553+ "pipeline-fs_hemi-L_desc-surfaceMesh_smoothwm",
2554+ "pipeline-fs_hemi-R_desc-surfaceMesh_smoothwm",
2555+ "pipeline-fs_hemi-L_desc-surfaceMesh_sphere",
2556+ "pipeline-fs_hemi-R_desc-surfaceMesh_sphere",
2557+ "pipeline-fs_hemi-L_desc-surfaceMap_sulc",
2558+ "pipeline-fs_hemi-R_desc-surfaceMap_sulc",
2559+ "pipeline-fs_hemi-L_desc-surfaceMap_thickness",
2560+ "pipeline-fs_hemi-R_desc-surfaceMap_thickness",
2561+ "pipeline-fs_hemi-L_desc-surfaceMap_volume",
2562+ "pipeline-fs_hemi-R_desc-surfaceMap_volume",
2563+ "pipeline-fs_hemi-L_desc-surfaceMesh_white",
2564+ "pipeline-fs_hemi-R_desc-surfaceMesh_white",
2565+ "pipeline-fs_wmparc",
2566+ "freesurfer-subject-dir"]}
2567+ '''
2568+
2569+ # fnirt-based brain extraction
2570+ brain_extraction = fnirt_based_brain_extraction (config = cfg ,
2571+ wf_name = f'fnirt_based_brain_extraction_{ pipe_num } ' )
2572+
2573+ node , out = strat_pool .get_data ('desc-preproc_T1w' )
2574+ wf .connect (node , out , brain_extraction , 'inputspec.anat_data' )
2575+
2576+ node , out = strat_pool .get_data ('template-ref-mask-res-2' )
2577+ wf .connect (node , out , brain_extraction , 'inputspec.template-ref-mask-res-2' )
2578+
2579+ node , out = strat_pool .get_data ('T1w-template' )
2580+ wf .connect (node , out , brain_extraction , 'inputspec.template_skull_for_anat' )
2581+
2582+ node , out = strat_pool .get_data ('T1w-template-res-2' )
2583+ wf .connect (node , out , brain_extraction , 'inputspec.template_skull_for_anat_2mm' )
2584+
2585+ node , out = strat_pool .get_data ('T1w-brain-template-mask' )
2586+ wf .connect (node , out , brain_extraction , 'inputspec.template_brain_mask_for_anat' )
2587+
2588+ # fast bias field correction
2589+ fast_correction = fast_bias_field_correction (config = cfg ,
2590+ wf_name = f'fast_bias_field_correction_{ pipe_num } ' )
2591+
2592+ node , out = strat_pool .get_data ('desc-preproc_T1w' )
2593+ wf .connect (node , out , fast_correction , 'inputspec.anat_data' )
2594+
2595+ wf .connect (brain_extraction , 'outputspec.anat_brain' , fast_correction , 'inputspec.anat_brain' )
2596+
2597+ wf .connect (brain_extraction , 'outputspec.anat_brain_mask' , fast_correction , 'inputspec.anat_brain_mask' )
2598+
2599+ ### ABCD Harmonization ###
2600+ # Ref: https://github.com/DCAN-Labs/DCAN-HCP/blob/master/FreeSurfer/FreeSurferPipeline.sh#L140-L144
2601+
2602+ # flirt -interp spline -in "$T1wImage" -ref "$T1wImage" -applyisoxfm 1 -out "$T1wImageFile"_1mm.nii.gz
2603+ resample_head_1mm = pe .Node (interface = fsl .FLIRT (),
2604+ name = f'resample_anat_head_1mm_{ pipe_num } ' )
2605+ resample_head_1mm .inputs .interp = 'spline'
2606+ resample_head_1mm .inputs .apply_isoxfm = 1
2607+
2608+ node , out = strat_pool .get_data ('desc-preproc_T1w' )
2609+ wf .connect (node , out , resample_head_1mm , 'in_file' )
2610+
2611+ wf .connect (node , out , resample_head_1mm , 'reference' )
2612+
2613+ # applywarp --rel --interp=spline -i "$T1wImage" -r "$T1wImageFile"_1mm.nii.gz --premat=$FSLDIR/etc/flirtsch/ident.mat -o "$T1wImageFile"_1mm.nii.gz
2614+ applywarp_head_to_head_1mm = pe .Node (interface = fsl .ApplyWarp (),
2615+ name = f'applywarp_head_to_head_1mm_{ pipe_num } ' )
2616+ applywarp_head_to_head_1mm .inputs .relwarp = True
2617+ applywarp_head_to_head_1mm .inputs .interp = 'spline'
2618+ applywarp_head_to_head_1mm .inputs .premat = cfg .registration_workflows ['anatomical_registration' ]['registration' ]['FSL-FNIRT' ]['identity_matrix' ]
2619+
2620+ wf .connect (node , out , applywarp_head_to_head_1mm , 'in_file' )
2621+
2622+ wf .connect (resample_head_1mm , 'out_file' ,
2623+ applywarp_head_to_head_1mm , 'ref_file' )
2624+
2625+ # applywarp --rel --interp=nn -i "$T1wImageBrain" -r "$T1wImageFile"_1mm.nii.gz --premat=$FSLDIR/etc/flirtsch/ident.mat -o "$T1wImageBrainFile"_1mm.nii.gz
2626+ applywarp_brain_to_head_1mm = pe .Node (interface = fsl .ApplyWarp (),
2627+ name = f'applywarp_brain_to_head_1mm_{ pipe_num } ' )
2628+ applywarp_brain_to_head_1mm .inputs .relwarp = True
2629+ applywarp_brain_to_head_1mm .inputs .interp = 'nn'
2630+ applywarp_brain_to_head_1mm .inputs .premat = cfg .registration_workflows ['anatomical_registration' ]['registration' ]['FSL-FNIRT' ]['identity_matrix' ]
2631+
2632+ wf .connect (fast_correction , 'outputspec.anat_brain_restore' ,
2633+ applywarp_brain_to_head_1mm , 'in_file' )
2634+
2635+ wf .connect (resample_head_1mm , 'out_file' ,
2636+ applywarp_brain_to_head_1mm , 'ref_file' )
2637+
2638+ # fslstats $T1wImageBrain -M
2639+ average_brain = pe .Node (interface = fsl .ImageStats (),
2640+ name = f'average_brain_{ pipe_num } ' )
2641+ average_brain .inputs .op_string = '-M'
2642+ average_brain .inputs .output_type = 'NIFTI_GZ'
2643+
2644+ wf .connect (fast_correction , 'outputspec.anat_brain_restore' ,
2645+ average_brain , 'in_file' )
2646+
2647+ # fslmaths "$T1wImageFile"_1mm.nii.gz -div $Mean -mul 150 -abs "$T1wImageFile"_1mm.nii.gz
2648+ normalize_head = pe .Node (util .Function (input_names = ['in_file' , 'number' , 'out_file_suffix' ],
2649+ output_names = ['out_file' ],
2650+ function = fslmaths_command ),
2651+ name = f'normalize_head_{ pipe_num } ' )
2652+ normalize_head .inputs .out_file_suffix = '_norm'
2653+
2654+ wf .connect (applywarp_head_to_head_1mm , 'out_file' ,
2655+ normalize_head , 'in_file' )
2656+
2657+ wf .connect (average_brain , 'out_stat' ,
2658+ normalize_head , 'number' )
2659+
2660+ if strat_pool .check_rpool ('freesurfer-subject-dir' ):
2661+ outputs = {
2662+ 'desc-restore_T1w' : (fast_correction , 'outputspec.anat_restore' ),
2663+ 'desc-restore-brain_T1w' : (fast_correction ,
2664+ 'outputspec.anat_brain_restore' ),
2665+ 'pipeline-fs_desc-fast_biasfield' : (fast_correction , 'outputspec.bias_field' )}
2666+ return (wf , outputs )
2667+
2668+ else :
2669+ ### recon-all -all step ###
2670+ reconall = pe .Node (interface = freesurfer .ReconAll (),
2671+ name = f'anat_freesurfer_{ pipe_num } ' ,
2672+ mem_gb = 2.7 )
2673+
2674+ sub_dir = cfg .pipeline_setup ['working_directory' ]['path' ]
2675+ freesurfer_subject_dir = os .path .join (sub_dir ,
2676+ 'cpac_' + cfg ['subject_id' ],
2677+ f'anat_preproc_freesurfer_{ pipe_num } ' ,
2678+ 'anat_freesurfer' )
2679+
2680+ # create the directory for FreeSurfer node
2681+ if not os .path .exists (freesurfer_subject_dir ):
2682+ os .makedirs (freesurfer_subject_dir )
2683+
2684+ reconall .inputs .directive = 'all'
2685+ reconall .inputs .subjects_dir = freesurfer_subject_dir
2686+ reconall .inputs .openmp = cfg .pipeline_setup ['system_config' ]['num_OMP_threads' ]
2687+
2688+ wf .connect (normalize_head , 'out_file' ,
2689+ reconall , 'T1_files' )
2690+
2691+ wf , hemisphere_outputs = freesurfer_hemispheres (wf , reconall , pipe_num )
2692+
2693+ outputs = {
2694+ 'desc-restore_T1w' : (fast_correction , 'outputspec.anat_restore' ),
2695+ 'desc-restore-brain_T1w' : (fast_correction ,
2696+ 'outputspec.anat_brain_restore' ),
2697+ 'pipeline-fs_desc-fast_biasfield' : (fast_correction , 'outputspec.bias_field' ),
2698+ 'pipeline-fs_wmparc' : (reconall , 'wmparc' ),
2699+ 'freesurfer-subject-dir' : (reconall , 'subjects_dir' ),
2700+ ** hemisphere_outputs
2701+ }
2702+
2703+ return (wf , outputs )
2704+
25352705
25362706# we're grabbing the postproc outputs and appending them to
25372707# the reconall outputs
2538- @docstring_parameter (postproc_outputs = str (flatten_list (brain_mask_freesurfer , 'outputs' )
2708+ @docstring_parameter (postproc_outputs = str (flatten_list (freesurfer_abcd_preproc , 'outputs' )
25392709 ).lstrip ('[' ).replace ("'" , '"' ))
25402710
25412711def freesurfer_reconall (wf , cfg , strat_pool , pipe_num , opt = None ):
@@ -2810,178 +2980,6 @@ def fast_bias_field_correction(config=None, wf_name='fast_bias_field_correction'
28102980 return preproc
28112981
28122982
2813- def freesurfer_abcd_preproc (wf , cfg , strat_pool , pipe_num , opt = None ):
2814- '''
2815- {"name": "freesurfer_abcd_preproc",
2816- "config": ["anatomical_preproc", "brain_extraction"],
2817- "switch": "None",
2818- "option_key": "using",
2819- "option_val": "FreeSurfer-ABCD",
2820- "inputs": ["desc-preproc_T1w",
2821- "T1w-template",
2822- "T1w-brain-template-mask",
2823- "template-ref-mask-res-2",
2824- "T1w-template-res-2",
2825- "freesurfer-subject-dir"],
2826- "outputs": ["desc-restore_T1w",
2827- "desc-restore-brain_T1w",
2828- "pipeline-fs_desc-fast_biasfield",
2829- "pipeline-fs_hemi-L_desc-surface_curv",
2830- "pipeline-fs_hemi-R_desc-surface_curv",
2831- "pipeline-fs_hemi-L_desc-surfaceMesh_pial",
2832- "pipeline-fs_hemi-R_desc-surfaceMesh_pial",
2833- "pipeline-fs_hemi-L_desc-surfaceMesh_smoothwm",
2834- "pipeline-fs_hemi-R_desc-surfaceMesh_smoothwm",
2835- "pipeline-fs_hemi-L_desc-surfaceMesh_sphere",
2836- "pipeline-fs_hemi-R_desc-surfaceMesh_sphere",
2837- "pipeline-fs_hemi-L_desc-surfaceMap_sulc",
2838- "pipeline-fs_hemi-R_desc-surfaceMap_sulc",
2839- "pipeline-fs_hemi-L_desc-surfaceMap_thickness",
2840- "pipeline-fs_hemi-R_desc-surfaceMap_thickness",
2841- "pipeline-fs_hemi-L_desc-surfaceMap_volume",
2842- "pipeline-fs_hemi-R_desc-surfaceMap_volume",
2843- "pipeline-fs_hemi-L_desc-surfaceMesh_white",
2844- "pipeline-fs_hemi-R_desc-surfaceMesh_white",
2845- "pipeline-fs_wmparc",
2846- "freesurfer-subject-dir"]}
2847- '''
2848-
2849- # fnirt-based brain extraction
2850- brain_extraction = fnirt_based_brain_extraction (config = cfg ,
2851- wf_name = f'fnirt_based_brain_extraction_{ pipe_num } ' )
2852-
2853- node , out = strat_pool .get_data ('desc-preproc_T1w' )
2854- wf .connect (node , out , brain_extraction , 'inputspec.anat_data' )
2855-
2856- node , out = strat_pool .get_data ('template-ref-mask-res-2' )
2857- wf .connect (node , out , brain_extraction , 'inputspec.template-ref-mask-res-2' )
2858-
2859- node , out = strat_pool .get_data ('T1w-template' )
2860- wf .connect (node , out , brain_extraction , 'inputspec.template_skull_for_anat' )
2861-
2862- node , out = strat_pool .get_data ('T1w-template-res-2' )
2863- wf .connect (node , out , brain_extraction , 'inputspec.template_skull_for_anat_2mm' )
2864-
2865- node , out = strat_pool .get_data ('T1w-brain-template-mask' )
2866- wf .connect (node , out , brain_extraction , 'inputspec.template_brain_mask_for_anat' )
2867-
2868- # fast bias field correction
2869- fast_correction = fast_bias_field_correction (config = cfg ,
2870- wf_name = f'fast_bias_field_correction_{ pipe_num } ' )
2871-
2872- node , out = strat_pool .get_data ('desc-preproc_T1w' )
2873- wf .connect (node , out , fast_correction , 'inputspec.anat_data' )
2874-
2875- wf .connect (brain_extraction , 'outputspec.anat_brain' , fast_correction , 'inputspec.anat_brain' )
2876-
2877- wf .connect (brain_extraction , 'outputspec.anat_brain_mask' , fast_correction , 'inputspec.anat_brain_mask' )
2878-
2879- ### ABCD Harmonization ###
2880- # Ref: https://github.com/DCAN-Labs/DCAN-HCP/blob/master/FreeSurfer/FreeSurferPipeline.sh#L140-L144
2881-
2882- # flirt -interp spline -in "$T1wImage" -ref "$T1wImage" -applyisoxfm 1 -out "$T1wImageFile"_1mm.nii.gz
2883- resample_head_1mm = pe .Node (interface = fsl .FLIRT (),
2884- name = f'resample_anat_head_1mm_{ pipe_num } ' )
2885- resample_head_1mm .inputs .interp = 'spline'
2886- resample_head_1mm .inputs .apply_isoxfm = 1
2887-
2888- node , out = strat_pool .get_data ('desc-preproc_T1w' )
2889- wf .connect (node , out , resample_head_1mm , 'in_file' )
2890-
2891- wf .connect (node , out , resample_head_1mm , 'reference' )
2892-
2893- # applywarp --rel --interp=spline -i "$T1wImage" -r "$T1wImageFile"_1mm.nii.gz --premat=$FSLDIR/etc/flirtsch/ident.mat -o "$T1wImageFile"_1mm.nii.gz
2894- applywarp_head_to_head_1mm = pe .Node (interface = fsl .ApplyWarp (),
2895- name = f'applywarp_head_to_head_1mm_{ pipe_num } ' )
2896- applywarp_head_to_head_1mm .inputs .relwarp = True
2897- applywarp_head_to_head_1mm .inputs .interp = 'spline'
2898- applywarp_head_to_head_1mm .inputs .premat = cfg .registration_workflows ['anatomical_registration' ]['registration' ]['FSL-FNIRT' ]['identity_matrix' ]
2899-
2900- wf .connect (node , out , applywarp_head_to_head_1mm , 'in_file' )
2901-
2902- wf .connect (resample_head_1mm , 'out_file' ,
2903- applywarp_head_to_head_1mm , 'ref_file' )
2904-
2905- # applywarp --rel --interp=nn -i "$T1wImageBrain" -r "$T1wImageFile"_1mm.nii.gz --premat=$FSLDIR/etc/flirtsch/ident.mat -o "$T1wImageBrainFile"_1mm.nii.gz
2906- applywarp_brain_to_head_1mm = pe .Node (interface = fsl .ApplyWarp (),
2907- name = f'applywarp_brain_to_head_1mm_{ pipe_num } ' )
2908- applywarp_brain_to_head_1mm .inputs .relwarp = True
2909- applywarp_brain_to_head_1mm .inputs .interp = 'nn'
2910- applywarp_brain_to_head_1mm .inputs .premat = cfg .registration_workflows ['anatomical_registration' ]['registration' ]['FSL-FNIRT' ]['identity_matrix' ]
2911-
2912- wf .connect (fast_correction , 'outputspec.anat_brain_restore' ,
2913- applywarp_brain_to_head_1mm , 'in_file' )
2914-
2915- wf .connect (resample_head_1mm , 'out_file' ,
2916- applywarp_brain_to_head_1mm , 'ref_file' )
2917-
2918- # fslstats $T1wImageBrain -M
2919- average_brain = pe .Node (interface = fsl .ImageStats (),
2920- name = f'average_brain_{ pipe_num } ' )
2921- average_brain .inputs .op_string = '-M'
2922- average_brain .inputs .output_type = 'NIFTI_GZ'
2923-
2924- wf .connect (fast_correction , 'outputspec.anat_brain_restore' ,
2925- average_brain , 'in_file' )
2926-
2927- # fslmaths "$T1wImageFile"_1mm.nii.gz -div $Mean -mul 150 -abs "$T1wImageFile"_1mm.nii.gz
2928- normalize_head = pe .Node (util .Function (input_names = ['in_file' , 'number' , 'out_file_suffix' ],
2929- output_names = ['out_file' ],
2930- function = fslmaths_command ),
2931- name = f'normalize_head_{ pipe_num } ' )
2932- normalize_head .inputs .out_file_suffix = '_norm'
2933-
2934- wf .connect (applywarp_head_to_head_1mm , 'out_file' ,
2935- normalize_head , 'in_file' )
2936-
2937- wf .connect (average_brain , 'out_stat' ,
2938- normalize_head , 'number' )
2939-
2940- if strat_pool .check_rpool ('freesurfer-subject-dir' ):
2941- outputs = {
2942- 'desc-restore_T1w' : (fast_correction , 'outputspec.anat_restore' ),
2943- 'desc-restore-brain_T1w' : (fast_correction ,
2944- 'outputspec.anat_brain_restore' ),
2945- 'pipeline-fs_desc-fast_biasfield' : (fast_correction , 'outputspec.bias_field' )}
2946- return (wf , outputs )
2947-
2948- else :
2949- ### recon-all -all step ###
2950- reconall = pe .Node (interface = freesurfer .ReconAll (),
2951- name = f'anat_freesurfer_{ pipe_num } ' ,
2952- mem_gb = 2.7 )
2953-
2954- sub_dir = cfg .pipeline_setup ['working_directory' ]['path' ]
2955- freesurfer_subject_dir = os .path .join (sub_dir ,
2956- 'cpac_' + cfg ['subject_id' ],
2957- f'anat_preproc_freesurfer_{ pipe_num } ' ,
2958- 'anat_freesurfer' )
2959-
2960- # create the directory for FreeSurfer node
2961- if not os .path .exists (freesurfer_subject_dir ):
2962- os .makedirs (freesurfer_subject_dir )
2963-
2964- reconall .inputs .directive = 'all'
2965- reconall .inputs .subjects_dir = freesurfer_subject_dir
2966- reconall .inputs .openmp = cfg .pipeline_setup ['system_config' ]['num_OMP_threads' ]
2967-
2968- wf .connect (normalize_head , 'out_file' ,
2969- reconall , 'T1_files' )
2970-
2971- wf , hemisphere_outputs = freesurfer_hemispheres (wf , reconall , pipe_num )
2972-
2973- outputs = {
2974- 'desc-restore_T1w' : (fast_correction , 'outputspec.anat_restore' ),
2975- 'desc-restore-brain_T1w' : (fast_correction ,
2976- 'outputspec.anat_brain_restore' ),
2977- 'pipeline-fs_desc-fast_biasfield' : (fast_correction , 'outputspec.bias_field' ),
2978- 'pipeline-fs_wmparc' : (reconall , 'wmparc' ),
2979- 'freesurfer-subject-dir' : (reconall , 'subjects_dir' ),
2980- ** hemisphere_outputs
2981- }
2982-
2983- return (wf , outputs )
2984-
29852983def correct_restore_brain_intensity_abcd (wf , cfg , strat_pool , pipe_num , opt = None ):
29862984 '''
29872985 {"name": "correct_restore_brain_intensity_abcd",
0 commit comments